@kite-copilot/chat-panel 0.2.26 → 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,68 +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
  }
1583
- }
1584
- ).subscribe();
1585
- realtimeChannelRef.current = channel;
1586
- }, [supabaseClient]);
1587
- React4.useEffect(() => {
1588
- return () => {
1589
- if (realtimeChannelRef.current && supabaseClient) {
1590
- supabaseClient.removeChannel(realtimeChannelRef.current);
1567
+ } catch (err) {
1568
+ console.error("[KiteChat] Failed to parse escalation message:", err);
1591
1569
  }
1592
1570
  };
1593
- }, [supabaseClient]);
1594
- React4.useEffect(() => {
1595
- if (isEscalated && supabaseClient && sessionId) {
1596
- subscribeToAgentMessages(sessionId);
1597
- }
1598
- }, [isEscalated, supabaseClient, sessionId, subscribeToAgentMessages]);
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]);
1599
1579
  const sendEscalatedMessage = React4.useCallback(async (content) => {
1600
- 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
+ }
1601
1584
  try {
1602
- await supabaseClient.from("chat_history").insert({
1603
- session_id: sessionId,
1604
- role: "user",
1585
+ escalationWsRef.current.send(JSON.stringify({
1586
+ type: "user_message",
1605
1587
  content
1606
- });
1588
+ }));
1607
1589
  return true;
1608
1590
  } catch (err) {
1609
1591
  console.error("[KiteChat] Failed to send escalated message:", err);
1610
1592
  return false;
1611
1593
  }
1612
- }, [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]);
1613
1607
  function streamAssistantMessage(messageId, fullText, followups) {
1614
1608
  let textToStream = fullText;
1615
1609
  let extractedFollowups = followups;
@@ -1720,7 +1714,7 @@ function ChatPanel({
1720
1714
  return;
1721
1715
  }
1722
1716
  if (!trimmed) return;
1723
- if (isEscalated && supabaseClient) {
1717
+ if (isEscalated) {
1724
1718
  const userMessage = {
1725
1719
  id: Date.now(),
1726
1720
  role: "user",
@@ -2070,7 +2064,6 @@ function ChatPanel({
2070
2064
  content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
2071
2065
  };
2072
2066
  setMessages((prev) => [...prev, escalationMessage]);
2073
- subscribeToAgentMessages(sessionId);
2074
2067
  }
2075
2068
  } catch (parseError) {
2076
2069
  console.error("Failed to parse SSE event:", parseError);
@@ -4135,9 +4128,7 @@ function ChatPanelWithToggle({
4135
4128
  startingQuestionsEndpoint,
4136
4129
  defaultOpen = false,
4137
4130
  isOpen: controlledIsOpen,
4138
- onOpenChange,
4139
- supabaseUrl,
4140
- supabaseAnonKey
4131
+ onOpenChange
4141
4132
  }) {
4142
4133
  const [internalIsOpen, setInternalIsOpen] = React4.useState(defaultOpen);
4143
4134
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
@@ -4168,9 +4159,7 @@ function ChatPanelWithToggle({
4168
4159
  currentPage,
4169
4160
  agentUrl,
4170
4161
  startingQuestions,
4171
- startingQuestionsEndpoint,
4172
- supabaseUrl,
4173
- supabaseAnonKey
4162
+ startingQuestionsEndpoint
4174
4163
  }
4175
4164
  );
4176
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-KPTM44LS.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,68 +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
  }
1582
- }
1583
- ).subscribe();
1584
- realtimeChannelRef.current = channel;
1585
- }, [supabaseClient]);
1586
- React4.useEffect(() => {
1587
- return () => {
1588
- if (realtimeChannelRef.current && supabaseClient) {
1589
- supabaseClient.removeChannel(realtimeChannelRef.current);
1566
+ } catch (err) {
1567
+ console.error("[KiteChat] Failed to parse escalation message:", err);
1590
1568
  }
1591
1569
  };
1592
- }, [supabaseClient]);
1593
- React4.useEffect(() => {
1594
- if (isEscalated && supabaseClient && sessionId) {
1595
- subscribeToAgentMessages(sessionId);
1596
- }
1597
- }, [isEscalated, supabaseClient, sessionId, subscribeToAgentMessages]);
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]);
1598
1578
  const sendEscalatedMessage = React4.useCallback(async (content) => {
1599
- 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
+ }
1600
1583
  try {
1601
- await supabaseClient.from("chat_history").insert({
1602
- session_id: sessionId,
1603
- role: "user",
1584
+ escalationWsRef.current.send(JSON.stringify({
1585
+ type: "user_message",
1604
1586
  content
1605
- });
1587
+ }));
1606
1588
  return true;
1607
1589
  } catch (err) {
1608
1590
  console.error("[KiteChat] Failed to send escalated message:", err);
1609
1591
  return false;
1610
1592
  }
1611
- }, [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]);
1612
1606
  function streamAssistantMessage(messageId, fullText, followups) {
1613
1607
  let textToStream = fullText;
1614
1608
  let extractedFollowups = followups;
@@ -1719,7 +1713,7 @@ function ChatPanel({
1719
1713
  return;
1720
1714
  }
1721
1715
  if (!trimmed) return;
1722
- if (isEscalated && supabaseClient) {
1716
+ if (isEscalated) {
1723
1717
  const userMessage = {
1724
1718
  id: Date.now(),
1725
1719
  role: "user",
@@ -2069,7 +2063,6 @@ function ChatPanel({
2069
2063
  content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
2070
2064
  };
2071
2065
  setMessages((prev) => [...prev, escalationMessage]);
2072
- subscribeToAgentMessages(sessionId);
2073
2066
  }
2074
2067
  } catch (parseError) {
2075
2068
  console.error("Failed to parse SSE event:", parseError);
@@ -4154,9 +4147,7 @@ function ChatPanelWithToggle({
4154
4147
  startingQuestionsEndpoint,
4155
4148
  defaultOpen = false,
4156
4149
  isOpen: controlledIsOpen,
4157
- onOpenChange,
4158
- supabaseUrl,
4159
- supabaseAnonKey
4150
+ onOpenChange
4160
4151
  }) {
4161
4152
  const [internalIsOpen, setInternalIsOpen] = React4.useState(defaultOpen);
4162
4153
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
@@ -4187,9 +4178,7 @@ function ChatPanelWithToggle({
4187
4178
  currentPage,
4188
4179
  agentUrl,
4189
4180
  startingQuestions,
4190
- startingQuestionsEndpoint,
4191
- supabaseUrl,
4192
- supabaseAnonKey
4181
+ startingQuestionsEndpoint
4193
4182
  }
4194
4183
  );
4195
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
  */