@kite-copilot/chat-panel 0.2.25 → 0.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auto.cjs CHANGED
@@ -885,7 +885,6 @@ function DataRenderer({ type, data }) {
885
885
  }
886
886
 
887
887
  // src/ChatPanel.tsx
888
- var import_supabase_js = require("@supabase/supabase-js");
889
888
  var import_jsx_runtime9 = require("react/jsx-runtime");
890
889
  var DEFAULT_AGENT_URL = "http://localhost:5002";
891
890
  var PANEL_WIDTH = 340;
@@ -1314,16 +1313,13 @@ function ChatPanel({
1314
1313
  currentPage,
1315
1314
  agentUrl = DEFAULT_AGENT_URL,
1316
1315
  startingQuestions: startingQuestionsProp,
1317
- startingQuestionsEndpoint,
1318
- supabaseUrl,
1319
- supabaseAnonKey
1316
+ startingQuestionsEndpoint
1320
1317
  } = {}) {
1321
1318
  const [messages, setMessages] = React4.useState(initialMessages);
1322
1319
  const [input, setInput] = React4.useState("");
1323
1320
  const [sessionId, setSessionId] = React4.useState(() => crypto.randomUUID());
1324
1321
  const [isEscalated, setIsEscalated] = React4.useState(false);
1325
- const [supabaseClient, setSupabaseClient] = React4.useState(null);
1326
- const realtimeChannelRef = React4.useRef(null);
1322
+ const escalationWsRef = React4.useRef(null);
1327
1323
  const resetSession = React4.useCallback(() => {
1328
1324
  setSessionId(crypto.randomUUID());
1329
1325
  }, []);
@@ -1548,63 +1544,66 @@ function ChatPanel({
1548
1544
  guideComplete,
1549
1545
  onNavigate
1550
1546
  ]);
1551
- React4.useEffect(() => {
1552
- if (supabaseUrl && supabaseAnonKey && !supabaseClient) {
1553
- const client = (0, import_supabase_js.createClient)(supabaseUrl, supabaseAnonKey);
1554
- setSupabaseClient(client);
1547
+ const connectToEscalationWs = React4.useCallback((currentSessionId) => {
1548
+ if (!agentUrl) return;
1549
+ if (escalationWsRef.current) {
1550
+ escalationWsRef.current.close();
1555
1551
  }
1556
- }, [supabaseUrl, supabaseAnonKey, supabaseClient]);
1557
- const subscribeToAgentMessages = React4.useCallback((currentSessionId) => {
1558
- if (!supabaseClient) return;
1559
- if (realtimeChannelRef.current) {
1560
- supabaseClient.removeChannel(realtimeChannelRef.current);
1561
- }
1562
- const channel = supabaseClient.channel(`user-chat-${currentSessionId}`).on(
1563
- "postgres_changes",
1564
- {
1565
- event: "INSERT",
1566
- schema: "public",
1567
- table: "chat_history",
1568
- filter: `session_id=eq.${currentSessionId}`
1569
- },
1570
- (payload) => {
1571
- const newMsg = payload.new;
1572
- if (newMsg.role === "agent") {
1573
- setMessages((prev) => [
1574
- ...prev,
1575
- {
1576
- id: Date.now(),
1577
- role: "agent",
1578
- kind: "text",
1579
- content: newMsg.content
1580
- }
1581
- ]);
1552
+ const wsUrl = agentUrl.replace(/^http/, "ws") + `/ws/escalation/${currentSessionId}`;
1553
+ const ws = new WebSocket(wsUrl);
1554
+ ws.onmessage = (event) => {
1555
+ try {
1556
+ const data = JSON.parse(event.data);
1557
+ if (data.type === "agent_message") {
1558
+ setMessages((prev) => [...prev, {
1559
+ id: Date.now(),
1560
+ role: "agent",
1561
+ kind: "text",
1562
+ content: data.content
1563
+ }]);
1564
+ } else if (data.type === "error") {
1565
+ console.error("[KiteChat] Escalation error:", data.message);
1582
1566
  }
1567
+ } catch (err) {
1568
+ console.error("[KiteChat] Failed to parse escalation message:", err);
1583
1569
  }
1584
- ).subscribe();
1585
- realtimeChannelRef.current = channel;
1586
- }, [supabaseClient]);
1587
- React4.useEffect(() => {
1588
- return () => {
1589
- if (realtimeChannelRef.current && supabaseClient) {
1590
- supabaseClient.removeChannel(realtimeChannelRef.current);
1591
- }
1592
1570
  };
1593
- }, [supabaseClient]);
1571
+ ws.onerror = (err) => {
1572
+ console.error("[KiteChat] Escalation WebSocket error:", err);
1573
+ };
1574
+ ws.onclose = () => {
1575
+ console.log("[KiteChat] Escalation WebSocket closed");
1576
+ };
1577
+ escalationWsRef.current = ws;
1578
+ }, [agentUrl]);
1594
1579
  const sendEscalatedMessage = React4.useCallback(async (content) => {
1595
- if (!supabaseClient || !isEscalated) return false;
1580
+ if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
1581
+ console.error("[KiteChat] Escalation WebSocket not connected");
1582
+ return false;
1583
+ }
1596
1584
  try {
1597
- await supabaseClient.from("chat_history").insert({
1598
- session_id: sessionId,
1599
- role: "user",
1585
+ escalationWsRef.current.send(JSON.stringify({
1586
+ type: "user_message",
1600
1587
  content
1601
- });
1588
+ }));
1602
1589
  return true;
1603
1590
  } catch (err) {
1604
1591
  console.error("[KiteChat] Failed to send escalated message:", err);
1605
1592
  return false;
1606
1593
  }
1607
- }, [supabaseClient, isEscalated, sessionId]);
1594
+ }, []);
1595
+ React4.useEffect(() => {
1596
+ return () => {
1597
+ if (escalationWsRef.current) {
1598
+ escalationWsRef.current.close();
1599
+ }
1600
+ };
1601
+ }, []);
1602
+ React4.useEffect(() => {
1603
+ if (isEscalated && sessionId) {
1604
+ connectToEscalationWs(sessionId);
1605
+ }
1606
+ }, [isEscalated, sessionId, connectToEscalationWs]);
1608
1607
  function streamAssistantMessage(messageId, fullText, followups) {
1609
1608
  let textToStream = fullText;
1610
1609
  let extractedFollowups = followups;
@@ -1715,7 +1714,7 @@ function ChatPanel({
1715
1714
  return;
1716
1715
  }
1717
1716
  if (!trimmed) return;
1718
- if (isEscalated && supabaseClient) {
1717
+ if (isEscalated) {
1719
1718
  const userMessage = {
1720
1719
  id: Date.now(),
1721
1720
  role: "user",
@@ -2065,7 +2064,6 @@ function ChatPanel({
2065
2064
  content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
2066
2065
  };
2067
2066
  setMessages((prev) => [...prev, escalationMessage]);
2068
- subscribeToAgentMessages(sessionId);
2069
2067
  }
2070
2068
  } catch (parseError) {
2071
2069
  console.error("Failed to parse SSE event:", parseError);
@@ -4130,9 +4128,7 @@ function ChatPanelWithToggle({
4130
4128
  startingQuestionsEndpoint,
4131
4129
  defaultOpen = false,
4132
4130
  isOpen: controlledIsOpen,
4133
- onOpenChange,
4134
- supabaseUrl,
4135
- supabaseAnonKey
4131
+ onOpenChange
4136
4132
  }) {
4137
4133
  const [internalIsOpen, setInternalIsOpen] = React4.useState(defaultOpen);
4138
4134
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
@@ -4163,9 +4159,7 @@ function ChatPanelWithToggle({
4163
4159
  currentPage,
4164
4160
  agentUrl,
4165
4161
  startingQuestions,
4166
- startingQuestionsEndpoint,
4167
- supabaseUrl,
4168
- supabaseAnonKey
4162
+ startingQuestionsEndpoint
4169
4163
  }
4170
4164
  );
4171
4165
  }
package/dist/auto.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CGiuk776.cjs';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.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-CGiuk776.js';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.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-WCRTS3TD.js";
3
+ } from "./chunk-4KYS4INW.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {
@@ -884,7 +884,6 @@ function DataRenderer({ type, data }) {
884
884
  // src/ChatPanel.tsx
885
885
  import * as React4 from "react";
886
886
  import { ArrowLeft, ArrowUp, Command, CornerDownLeft, CheckCircle2 as CheckCircle23, SquarePen, Paperclip, X, FileSpreadsheet, Loader2 as Loader22, ChevronLeft, ChevronRight, Sparkles } from "lucide-react";
887
- import { createClient } from "@supabase/supabase-js";
888
887
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
889
888
  var DEFAULT_AGENT_URL = "http://localhost:5002";
890
889
  var PANEL_WIDTH = 340;
@@ -1313,16 +1312,13 @@ function ChatPanel({
1313
1312
  currentPage,
1314
1313
  agentUrl = DEFAULT_AGENT_URL,
1315
1314
  startingQuestions: startingQuestionsProp,
1316
- startingQuestionsEndpoint,
1317
- supabaseUrl,
1318
- supabaseAnonKey
1315
+ startingQuestionsEndpoint
1319
1316
  } = {}) {
1320
1317
  const [messages, setMessages] = React4.useState(initialMessages);
1321
1318
  const [input, setInput] = React4.useState("");
1322
1319
  const [sessionId, setSessionId] = React4.useState(() => crypto.randomUUID());
1323
1320
  const [isEscalated, setIsEscalated] = React4.useState(false);
1324
- const [supabaseClient, setSupabaseClient] = React4.useState(null);
1325
- const realtimeChannelRef = React4.useRef(null);
1321
+ const escalationWsRef = React4.useRef(null);
1326
1322
  const resetSession = React4.useCallback(() => {
1327
1323
  setSessionId(crypto.randomUUID());
1328
1324
  }, []);
@@ -1547,63 +1543,66 @@ function ChatPanel({
1547
1543
  guideComplete,
1548
1544
  onNavigate
1549
1545
  ]);
1550
- React4.useEffect(() => {
1551
- if (supabaseUrl && supabaseAnonKey && !supabaseClient) {
1552
- const client = createClient(supabaseUrl, supabaseAnonKey);
1553
- setSupabaseClient(client);
1546
+ const connectToEscalationWs = React4.useCallback((currentSessionId) => {
1547
+ if (!agentUrl) return;
1548
+ if (escalationWsRef.current) {
1549
+ escalationWsRef.current.close();
1554
1550
  }
1555
- }, [supabaseUrl, supabaseAnonKey, supabaseClient]);
1556
- const subscribeToAgentMessages = React4.useCallback((currentSessionId) => {
1557
- if (!supabaseClient) return;
1558
- if (realtimeChannelRef.current) {
1559
- supabaseClient.removeChannel(realtimeChannelRef.current);
1560
- }
1561
- const channel = supabaseClient.channel(`user-chat-${currentSessionId}`).on(
1562
- "postgres_changes",
1563
- {
1564
- event: "INSERT",
1565
- schema: "public",
1566
- table: "chat_history",
1567
- filter: `session_id=eq.${currentSessionId}`
1568
- },
1569
- (payload) => {
1570
- const newMsg = payload.new;
1571
- if (newMsg.role === "agent") {
1572
- setMessages((prev) => [
1573
- ...prev,
1574
- {
1575
- id: Date.now(),
1576
- role: "agent",
1577
- kind: "text",
1578
- content: newMsg.content
1579
- }
1580
- ]);
1551
+ const wsUrl = agentUrl.replace(/^http/, "ws") + `/ws/escalation/${currentSessionId}`;
1552
+ const ws = new WebSocket(wsUrl);
1553
+ ws.onmessage = (event) => {
1554
+ try {
1555
+ const data = JSON.parse(event.data);
1556
+ if (data.type === "agent_message") {
1557
+ setMessages((prev) => [...prev, {
1558
+ id: Date.now(),
1559
+ role: "agent",
1560
+ kind: "text",
1561
+ content: data.content
1562
+ }]);
1563
+ } else if (data.type === "error") {
1564
+ console.error("[KiteChat] Escalation error:", data.message);
1581
1565
  }
1566
+ } catch (err) {
1567
+ console.error("[KiteChat] Failed to parse escalation message:", err);
1582
1568
  }
1583
- ).subscribe();
1584
- realtimeChannelRef.current = channel;
1585
- }, [supabaseClient]);
1586
- React4.useEffect(() => {
1587
- return () => {
1588
- if (realtimeChannelRef.current && supabaseClient) {
1589
- supabaseClient.removeChannel(realtimeChannelRef.current);
1590
- }
1591
1569
  };
1592
- }, [supabaseClient]);
1570
+ ws.onerror = (err) => {
1571
+ console.error("[KiteChat] Escalation WebSocket error:", err);
1572
+ };
1573
+ ws.onclose = () => {
1574
+ console.log("[KiteChat] Escalation WebSocket closed");
1575
+ };
1576
+ escalationWsRef.current = ws;
1577
+ }, [agentUrl]);
1593
1578
  const sendEscalatedMessage = React4.useCallback(async (content) => {
1594
- if (!supabaseClient || !isEscalated) return false;
1579
+ if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
1580
+ console.error("[KiteChat] Escalation WebSocket not connected");
1581
+ return false;
1582
+ }
1595
1583
  try {
1596
- await supabaseClient.from("chat_history").insert({
1597
- session_id: sessionId,
1598
- role: "user",
1584
+ escalationWsRef.current.send(JSON.stringify({
1585
+ type: "user_message",
1599
1586
  content
1600
- });
1587
+ }));
1601
1588
  return true;
1602
1589
  } catch (err) {
1603
1590
  console.error("[KiteChat] Failed to send escalated message:", err);
1604
1591
  return false;
1605
1592
  }
1606
- }, [supabaseClient, isEscalated, sessionId]);
1593
+ }, []);
1594
+ React4.useEffect(() => {
1595
+ return () => {
1596
+ if (escalationWsRef.current) {
1597
+ escalationWsRef.current.close();
1598
+ }
1599
+ };
1600
+ }, []);
1601
+ React4.useEffect(() => {
1602
+ if (isEscalated && sessionId) {
1603
+ connectToEscalationWs(sessionId);
1604
+ }
1605
+ }, [isEscalated, sessionId, connectToEscalationWs]);
1607
1606
  function streamAssistantMessage(messageId, fullText, followups) {
1608
1607
  let textToStream = fullText;
1609
1608
  let extractedFollowups = followups;
@@ -1714,7 +1713,7 @@ function ChatPanel({
1714
1713
  return;
1715
1714
  }
1716
1715
  if (!trimmed) return;
1717
- if (isEscalated && supabaseClient) {
1716
+ if (isEscalated) {
1718
1717
  const userMessage = {
1719
1718
  id: Date.now(),
1720
1719
  role: "user",
@@ -2064,7 +2063,6 @@ function ChatPanel({
2064
2063
  content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
2065
2064
  };
2066
2065
  setMessages((prev) => [...prev, escalationMessage]);
2067
- subscribeToAgentMessages(sessionId);
2068
2066
  }
2069
2067
  } catch (parseError) {
2070
2068
  console.error("Failed to parse SSE event:", parseError);
@@ -4149,9 +4147,7 @@ function ChatPanelWithToggle({
4149
4147
  startingQuestionsEndpoint,
4150
4148
  defaultOpen = false,
4151
4149
  isOpen: controlledIsOpen,
4152
- onOpenChange,
4153
- supabaseUrl,
4154
- supabaseAnonKey
4150
+ onOpenChange
4155
4151
  }) {
4156
4152
  const [internalIsOpen, setInternalIsOpen] = React4.useState(defaultOpen);
4157
4153
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
@@ -4182,9 +4178,7 @@ function ChatPanelWithToggle({
4182
4178
  currentPage,
4183
4179
  agentUrl,
4184
4180
  startingQuestions,
4185
- startingQuestionsEndpoint,
4186
- supabaseUrl,
4187
- supabaseAnonKey
4181
+ startingQuestionsEndpoint
4188
4182
  }
4189
4183
  );
4190
4184
  }
@@ -98,12 +98,8 @@ interface ChatPanelProps {
98
98
  startingQuestions?: StartingQuestion[];
99
99
  /** API endpoint to fetch starting questions */
100
100
  startingQuestionsEndpoint?: string;
101
- /** Supabase URL for Realtime escalation support */
102
- supabaseUrl?: string;
103
- /** Supabase anon key for Realtime escalation support */
104
- supabaseAnonKey?: string;
105
101
  }
106
- declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, supabaseUrl, supabaseAnonKey, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
107
103
  /**
108
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
109
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)
@@ -148,12 +144,8 @@ interface ChatPanelWithToggleProps {
148
144
  isOpen?: boolean;
149
145
  /** Callback when panel open state changes */
150
146
  onOpenChange?: (isOpen: boolean) => void;
151
- /** Supabase URL for Realtime escalation support */
152
- supabaseUrl?: string;
153
- /** Supabase anon key for Realtime escalation support */
154
- supabaseAnonKey?: string;
155
147
  }
156
- declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, supabaseUrl, supabaseAnonKey, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
148
+ declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
157
149
  /**
158
150
  * @deprecated Use ChatPanelWithToggle instead for the new side panel UX
159
151
  */
@@ -98,12 +98,8 @@ interface ChatPanelProps {
98
98
  startingQuestions?: StartingQuestion[];
99
99
  /** API endpoint to fetch starting questions */
100
100
  startingQuestionsEndpoint?: string;
101
- /** Supabase URL for Realtime escalation support */
102
- supabaseUrl?: string;
103
- /** Supabase anon key for Realtime escalation support */
104
- supabaseAnonKey?: string;
105
101
  }
106
- declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, supabaseUrl, supabaseAnonKey, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
107
103
  /**
108
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
109
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)
@@ -148,12 +144,8 @@ interface ChatPanelWithToggleProps {
148
144
  isOpen?: boolean;
149
145
  /** Callback when panel open state changes */
150
146
  onOpenChange?: (isOpen: boolean) => void;
151
- /** Supabase URL for Realtime escalation support */
152
- supabaseUrl?: string;
153
- /** Supabase anon key for Realtime escalation support */
154
- supabaseAnonKey?: string;
155
147
  }
156
- declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, supabaseUrl, supabaseAnonKey, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
148
+ declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
157
149
  /**
158
150
  * @deprecated Use ChatPanelWithToggle instead for the new side panel UX
159
151
  */