@kite-copilot/chat-panel 0.2.46 → 0.2.47
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 +5 -18
- package/dist/auto.cjs +44 -29
- package/dist/auto.d.cts +1 -4
- package/dist/auto.d.ts +1 -4
- package/dist/auto.js +1 -1
- package/dist/{chunk-4HIWUL6E.js → chunk-XMIO4GMW.js} +44 -29
- package/dist/{createKiteChat-o5u-5Sor.d.cts → createKiteChat-e6BnJS6T.d.cts} +18 -16
- package/dist/{createKiteChat-o5u-5Sor.d.ts → createKiteChat-e6BnJS6T.d.ts} +18 -16
- package/dist/embed.global.js +59 -24
- package/dist/index.cjs +44 -29
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,12 +47,11 @@ import '@kite-copilot/chat-panel/style.css';
|
|
|
47
47
|
// Create the chat instance
|
|
48
48
|
const chat = createKiteChat({
|
|
49
49
|
userId: 'user-123',
|
|
50
|
-
orgId: 'org-456',
|
|
50
|
+
orgId: 'org-456', // Organization ID for multi-tenant data isolation
|
|
51
51
|
agentUrl: 'https://your-api.example.com',
|
|
52
52
|
// Optional: Pass user info for session tracking in control center
|
|
53
53
|
userName: 'John Doe',
|
|
54
54
|
userEmail: 'john@example.com',
|
|
55
|
-
userOrganization: 'Acme Inc',
|
|
56
55
|
onNavigate: (page, subtab) => {
|
|
57
56
|
router.push(`/${page}${subtab ? `?tab=${subtab}` : ''}`);
|
|
58
57
|
},
|
|
@@ -139,7 +138,6 @@ const router = useRouter();
|
|
|
139
138
|
|
|
140
139
|
const { open, close, toggle, setCurrentPage } = useKiteChat({
|
|
141
140
|
userId: 'user-123',
|
|
142
|
-
orgId: 'org-456',
|
|
143
141
|
agentUrl: 'https://your-api.example.com',
|
|
144
142
|
onNavigate: (page, subtab) => {
|
|
145
143
|
router.push(`/${page}${subtab ? `?tab=${subtab}` : ''}`);
|
|
@@ -178,7 +176,6 @@ app.mount('#app');
|
|
|
178
176
|
// Initialize chat after Vue app is mounted
|
|
179
177
|
const chat = createKiteChat({
|
|
180
178
|
userId: 'user-123',
|
|
181
|
-
orgId: 'org-456',
|
|
182
179
|
agentUrl: 'https://your-api.example.com',
|
|
183
180
|
onNavigate: (page) => router.push(`/${page}`),
|
|
184
181
|
});
|
|
@@ -204,10 +201,8 @@ function App() {
|
|
|
204
201
|
<ChatPanelWithToggle
|
|
205
202
|
agentUrl="https://your-api.example.com"
|
|
206
203
|
userId="user-123"
|
|
207
|
-
orgId="org-456"
|
|
208
204
|
userName="John Doe"
|
|
209
205
|
userEmail="john@example.com"
|
|
210
|
-
userOrganization="Acme Inc"
|
|
211
206
|
onNavigate={(page) => router.push(`/${page}`)}
|
|
212
207
|
/>
|
|
213
208
|
</>
|
|
@@ -264,7 +259,6 @@ The panel shows suggested questions when empty. These can be customized per-user
|
|
|
264
259
|
// Option 1: Pass questions directly
|
|
265
260
|
const chat = createKiteChat({
|
|
266
261
|
userId: 'user-123',
|
|
267
|
-
orgId: 'org-456',
|
|
268
262
|
startingQuestions: [
|
|
269
263
|
{ id: '1', label: 'Changing layouts', prompt: 'How do I customize the layout?' },
|
|
270
264
|
{ id: '2', label: 'Bulk uploads', prompt: 'How do I upload data in bulk?' },
|
|
@@ -275,7 +269,6 @@ const chat = createKiteChat({
|
|
|
275
269
|
// Option 2: Fetch from backend (per-user)
|
|
276
270
|
const chat = createKiteChat({
|
|
277
271
|
userId: 'user-123',
|
|
278
|
-
orgId: 'org-456',
|
|
279
272
|
startingQuestionsEndpoint: '/api/user/starting-questions',
|
|
280
273
|
});
|
|
281
274
|
```
|
|
@@ -295,11 +288,9 @@ Pass user information to enable session tracking in the control center. This all
|
|
|
295
288
|
```ts
|
|
296
289
|
const chat = createKiteChat({
|
|
297
290
|
userId: 'user-123',
|
|
298
|
-
orgId: 'org-456',
|
|
299
291
|
// Optional user info for control center display
|
|
300
292
|
userName: 'John Doe',
|
|
301
293
|
userEmail: 'john@example.com',
|
|
302
|
-
userOrganization: 'Acme Inc',
|
|
303
294
|
});
|
|
304
295
|
```
|
|
305
296
|
|
|
@@ -307,9 +298,8 @@ const chat = createKiteChat({
|
|
|
307
298
|
|-------|-------------|
|
|
308
299
|
| `userName` | Displayed in conversations list and live chat |
|
|
309
300
|
| `userEmail` | Shown in user details panel |
|
|
310
|
-
| `userOrganization` | Helps support agents identify the customer's company |
|
|
311
301
|
|
|
312
|
-
**Note:** If user info is not provided, placeholder values ("Anonymous User", "Not provided"
|
|
302
|
+
**Note:** If user info is not provided, placeholder values ("Anonymous User", "Not provided") will be displayed in the control center.
|
|
313
303
|
|
|
314
304
|
## API Reference
|
|
315
305
|
|
|
@@ -322,12 +312,11 @@ Creates a new chat instance with explicit lifecycle control.
|
|
|
322
312
|
| Property | Type | Required | Description |
|
|
323
313
|
|----------|------|----------|-------------|
|
|
324
314
|
| `userId` | `string` | Yes | Unique identifier for the current user |
|
|
325
|
-
| `orgId` | `string` |
|
|
315
|
+
| `orgId` | `string` | No | Organization ID for multi-tenant data isolation |
|
|
326
316
|
| `agentUrl` | `string` | No | Backend agent API URL |
|
|
327
317
|
| `currentPage` | `string` | No | Current page context |
|
|
328
318
|
| `userName` | `string` | No | User's display name (for control center) |
|
|
329
319
|
| `userEmail` | `string` | No | User's email address (for control center) |
|
|
330
|
-
| `userOrganization` | `string` | No | User's organization name (for control center) |
|
|
331
320
|
| `theme` | `'light' \| 'dark' \| 'system'` | No | Theme preference |
|
|
332
321
|
| `startingQuestions` | `StartingQuestion[]` | No | Custom starting questions |
|
|
333
322
|
| `startingQuestionsEndpoint` | `string` | No | URL to fetch per-user questions |
|
|
@@ -363,10 +352,9 @@ import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
|
363
352
|
| `agentUrl` | `string` | `localhost:5002` | Backend agent URL |
|
|
364
353
|
| `currentPage` | `string` | - | Current page for context |
|
|
365
354
|
| `userId` | `string` | - | Unique user identifier |
|
|
366
|
-
| `orgId` | `string` | - | Organization
|
|
355
|
+
| `orgId` | `string` | - | Organization ID for multi-tenant data isolation |
|
|
367
356
|
| `userName` | `string` | - | User's display name (for control center) |
|
|
368
357
|
| `userEmail` | `string` | - | User's email address (for control center) |
|
|
369
|
-
| `userOrganization` | `string` | - | User's organization name (for control center) |
|
|
370
358
|
| `defaultOpen` | `boolean` | `false` | Initial open state (uncontrolled) |
|
|
371
359
|
| `isOpen` | `boolean` | - | Controlled open state |
|
|
372
360
|
| `onOpenChange` | `(isOpen: boolean) => void` | - | Called when open state changes |
|
|
@@ -463,8 +451,7 @@ Main chat endpoint for streaming responses.
|
|
|
463
451
|
"message": "user message",
|
|
464
452
|
"current_page": "dashboard",
|
|
465
453
|
"user_name": "John Doe",
|
|
466
|
-
"user_email": "john@example.com"
|
|
467
|
-
"user_organization": "Acme Inc"
|
|
454
|
+
"user_email": "john@example.com"
|
|
468
455
|
}
|
|
469
456
|
```
|
|
470
457
|
|
package/dist/auto.cjs
CHANGED
|
@@ -175,6 +175,7 @@ function ScrollBar({
|
|
|
175
175
|
|
|
176
176
|
// src/ChatPanel.tsx
|
|
177
177
|
var import_lucide_react4 = require("lucide-react");
|
|
178
|
+
var import_framer_motion2 = require("framer-motion");
|
|
178
179
|
|
|
179
180
|
// src/components/AssistantActivity.tsx
|
|
180
181
|
var import_lucide_react = require("lucide-react");
|
|
@@ -1023,9 +1024,10 @@ function TypingIndicator({ className = "" }) {
|
|
|
1023
1024
|
|
|
1024
1025
|
// src/ChatPanel.tsx
|
|
1025
1026
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1026
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
1027
|
+
var CHAT_PANEL_VERSION = true ? "0.2.47" : "dev";
|
|
1027
1028
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1028
|
-
var PANEL_WIDTH =
|
|
1029
|
+
var PANEL_WIDTH = 400;
|
|
1030
|
+
var PANEL_HEIGHT = 600;
|
|
1029
1031
|
function unescapeJsonString(str) {
|
|
1030
1032
|
return str.replace(/\\\\n/g, "\n").replace(/\\\\t/g, " ").replace(/\\\\"/g, '"').replace(/\\\\\\\\/g, "\\").replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
1031
1033
|
}
|
|
@@ -1482,13 +1484,28 @@ function ChatPanel({
|
|
|
1482
1484
|
orgId,
|
|
1483
1485
|
userName,
|
|
1484
1486
|
userEmail,
|
|
1485
|
-
userOrganization,
|
|
1486
1487
|
supabaseUrl,
|
|
1487
1488
|
supabaseAnonKey,
|
|
1489
|
+
initialCorner = "bottom-left",
|
|
1490
|
+
onCornerChange,
|
|
1488
1491
|
productBackendUrl
|
|
1489
1492
|
} = {}) {
|
|
1490
1493
|
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1491
1494
|
const [input, setInput] = React6.useState("");
|
|
1495
|
+
const [corner, setCorner] = React6.useState(initialCorner);
|
|
1496
|
+
const [isDragging, setIsDragging] = React6.useState(false);
|
|
1497
|
+
const dragControls = (0, import_framer_motion2.useAnimationControls)();
|
|
1498
|
+
const handleDragEnd = React6.useCallback((_event, info) => {
|
|
1499
|
+
dragControls.set({ x: 0, y: 0 });
|
|
1500
|
+
setIsDragging(false);
|
|
1501
|
+
const viewportWidth = window.innerWidth;
|
|
1502
|
+
const pointerX = info.point.x;
|
|
1503
|
+
const newCorner = pointerX < viewportWidth / 2 ? "bottom-left" : "bottom-right";
|
|
1504
|
+
if (newCorner !== corner) {
|
|
1505
|
+
setCorner(newCorner);
|
|
1506
|
+
onCornerChange?.(newCorner);
|
|
1507
|
+
}
|
|
1508
|
+
}, [corner, onCornerChange, dragControls]);
|
|
1492
1509
|
const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
|
|
1493
1510
|
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1494
1511
|
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
@@ -2276,7 +2293,6 @@ function ChatPanel({
|
|
|
2276
2293
|
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2277
2294
|
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2278
2295
|
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2279
|
-
console.log("[ChatPanel] user_organization:", userOrganization);
|
|
2280
2296
|
console.log("[ChatPanel] org_id:", orgId);
|
|
2281
2297
|
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2282
2298
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
@@ -2288,11 +2304,10 @@ function ChatPanel({
|
|
|
2288
2304
|
session_id: sessionId,
|
|
2289
2305
|
message: userText,
|
|
2290
2306
|
current_page: currentPage || "dashboard",
|
|
2291
|
-
user_id:
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
org_id: orgId
|
|
2307
|
+
user_id: userId,
|
|
2308
|
+
org_id: orgId,
|
|
2309
|
+
user_name: userName,
|
|
2310
|
+
user_email: userEmail
|
|
2296
2311
|
}),
|
|
2297
2312
|
signal: controller.signal
|
|
2298
2313
|
});
|
|
@@ -3323,12 +3338,21 @@ ${userText}`
|
|
|
3323
3338
|
}
|
|
3324
3339
|
}
|
|
3325
3340
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3326
|
-
|
|
3341
|
+
import_framer_motion2.motion.section,
|
|
3327
3342
|
{
|
|
3328
|
-
|
|
3329
|
-
|
|
3343
|
+
drag: true,
|
|
3344
|
+
dragMomentum: false,
|
|
3345
|
+
dragElastic: 0,
|
|
3346
|
+
animate: dragControls,
|
|
3347
|
+
onDragStart: () => setIsDragging(true),
|
|
3348
|
+
onDragEnd: handleDragEnd,
|
|
3349
|
+
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"}`,
|
|
3350
|
+
style: {
|
|
3351
|
+
width: `${PANEL_WIDTH}px`,
|
|
3352
|
+
height: `${PANEL_HEIGHT}px`
|
|
3353
|
+
},
|
|
3330
3354
|
children: [
|
|
3331
|
-
/* @__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", children: [
|
|
3355
|
+
/* @__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: [
|
|
3332
3356
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
3333
3357
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
|
|
3334
3358
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
|
|
@@ -3461,12 +3485,12 @@ ${userText}`
|
|
|
3461
3485
|
return null;
|
|
3462
3486
|
}
|
|
3463
3487
|
if (isUser) {
|
|
3464
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3 py-2 text-
|
|
3488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3 py-2 text-sm text-white shadow-sm", children: message.content }) }, message.id);
|
|
3465
3489
|
}
|
|
3466
3490
|
if (message.role === "agent") {
|
|
3467
3491
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-col items-start ${isRoleChange ? "mt-3" : ""}`, children: [
|
|
3468
3492
|
isRoleChange && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] text-gray-500 mb-1 ml-1", children: "Agent" }),
|
|
3469
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-[
|
|
3493
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-[300px] rounded-2xl rounded-bl-md bg-gray-100 px-4 py-3 text-sm text-gray-700", children: message.content })
|
|
3470
3494
|
] }, message.id);
|
|
3471
3495
|
}
|
|
3472
3496
|
if (message.kind === "searchSummary") {
|
|
@@ -4524,7 +4548,7 @@ ${userText}`
|
|
|
4524
4548
|
] }) }) }) })
|
|
4525
4549
|
}
|
|
4526
4550
|
),
|
|
4527
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "px-4 py-3
|
|
4551
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "px-4 py-3 bg-white shrink-0", children: [
|
|
4528
4552
|
pendingFile && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-2 flex items-center gap-2 rounded-xl bg-blue-50 border border-blue-200 px-3 py-2", children: [
|
|
4529
4553
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.FileSpreadsheet, { className: "h-4 w-4 text-blue-600" }),
|
|
4530
4554
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs text-blue-700 flex-1 truncate", children: pendingFile.name }),
|
|
@@ -4671,9 +4695,10 @@ function ChatPanelWithToggle({
|
|
|
4671
4695
|
orgId,
|
|
4672
4696
|
userName,
|
|
4673
4697
|
userEmail,
|
|
4674
|
-
userOrganization,
|
|
4675
4698
|
supabaseUrl,
|
|
4676
4699
|
supabaseAnonKey,
|
|
4700
|
+
initialCorner,
|
|
4701
|
+
onCornerChange,
|
|
4677
4702
|
productBackendUrl
|
|
4678
4703
|
}) {
|
|
4679
4704
|
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
@@ -4684,16 +4709,6 @@ function ChatPanelWithToggle({
|
|
|
4684
4709
|
}
|
|
4685
4710
|
onOpenChange?.(open);
|
|
4686
4711
|
};
|
|
4687
|
-
React6.useEffect(() => {
|
|
4688
|
-
const originalPadding = document.body.style.paddingRight;
|
|
4689
|
-
const originalTransition = document.body.style.transition;
|
|
4690
|
-
document.body.style.transition = "padding-right 0.3s ease";
|
|
4691
|
-
document.body.style.paddingRight = isOpen ? `${PANEL_WIDTH}px` : "0px";
|
|
4692
|
-
return () => {
|
|
4693
|
-
document.body.style.paddingRight = originalPadding;
|
|
4694
|
-
document.body.style.transition = originalTransition;
|
|
4695
|
-
};
|
|
4696
|
-
}, [isOpen]);
|
|
4697
4712
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4698
4713
|
ChatPanel,
|
|
4699
4714
|
{
|
|
@@ -4710,9 +4725,10 @@ function ChatPanelWithToggle({
|
|
|
4710
4725
|
orgId,
|
|
4711
4726
|
userName,
|
|
4712
4727
|
userEmail,
|
|
4713
|
-
userOrganization,
|
|
4714
4728
|
supabaseUrl,
|
|
4715
4729
|
supabaseAnonKey,
|
|
4730
|
+
initialCorner,
|
|
4731
|
+
onCornerChange,
|
|
4716
4732
|
productBackendUrl
|
|
4717
4733
|
}
|
|
4718
4734
|
);
|
|
@@ -4771,7 +4787,6 @@ function KiteChatWrapper({
|
|
|
4771
4787
|
orgId: config.orgId,
|
|
4772
4788
|
userName: config.userName,
|
|
4773
4789
|
userEmail: config.userEmail,
|
|
4774
|
-
userOrganization: config.userOrganization,
|
|
4775
4790
|
supabaseUrl: config.supabaseUrl,
|
|
4776
4791
|
supabaseAnonKey: config.supabaseAnonKey,
|
|
4777
4792
|
productBackendUrl: config.productBackendUrl
|
package/dist/auto.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-
|
|
1
|
+
import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-e6BnJS6T.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -15,7 +15,6 @@ import 'react/jsx-runtime';
|
|
|
15
15
|
* const chat = mountKiteChat({
|
|
16
16
|
* container: '#chat-container',
|
|
17
17
|
* userId: 'user-123',
|
|
18
|
-
* orgId: 'org-456',
|
|
19
18
|
* });
|
|
20
19
|
*
|
|
21
20
|
* // Later, if needed:
|
|
@@ -45,13 +44,11 @@ interface MountKiteChatConfig extends KiteChatConfig {
|
|
|
45
44
|
* const chat = mountKiteChat({
|
|
46
45
|
* container: '#my-chat',
|
|
47
46
|
* userId: 'user-123',
|
|
48
|
-
* orgId: 'org-456',
|
|
49
47
|
* });
|
|
50
48
|
*
|
|
51
49
|
* // Or let it create a container automatically
|
|
52
50
|
* const chat = mountKiteChat({
|
|
53
51
|
* userId: 'user-123',
|
|
54
|
-
* orgId: 'org-456',
|
|
55
52
|
* });
|
|
56
53
|
* ```
|
|
57
54
|
*/
|
package/dist/auto.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-
|
|
1
|
+
import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-e6BnJS6T.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -15,7 +15,6 @@ import 'react/jsx-runtime';
|
|
|
15
15
|
* const chat = mountKiteChat({
|
|
16
16
|
* container: '#chat-container',
|
|
17
17
|
* userId: 'user-123',
|
|
18
|
-
* orgId: 'org-456',
|
|
19
18
|
* });
|
|
20
19
|
*
|
|
21
20
|
* // Later, if needed:
|
|
@@ -45,13 +44,11 @@ interface MountKiteChatConfig extends KiteChatConfig {
|
|
|
45
44
|
* const chat = mountKiteChat({
|
|
46
45
|
* container: '#my-chat',
|
|
47
46
|
* userId: 'user-123',
|
|
48
|
-
* orgId: 'org-456',
|
|
49
47
|
* });
|
|
50
48
|
*
|
|
51
49
|
* // Or let it create a container automatically
|
|
52
50
|
* const chat = mountKiteChat({
|
|
53
51
|
* userId: 'user-123',
|
|
54
|
-
* orgId: 'org-456',
|
|
55
52
|
* });
|
|
56
53
|
* ```
|
|
57
54
|
*/
|
package/dist/auto.js
CHANGED
|
@@ -885,6 +885,7 @@ function DataRenderer({ type, data }) {
|
|
|
885
885
|
import * as React6 from "react";
|
|
886
886
|
import { createClient } from "@supabase/supabase-js";
|
|
887
887
|
import { ArrowLeft, ArrowUp, Command, CornerDownLeft, CheckCircle2 as CheckCircle23, SquarePen, Paperclip, X, FileSpreadsheet, Loader2 as Loader22, ChevronLeft, ChevronRight, Sparkles, Minus } from "lucide-react";
|
|
888
|
+
import { motion as motion2, useAnimationControls } from "framer-motion";
|
|
888
889
|
|
|
889
890
|
// src/hooks/useUserAuth.ts
|
|
890
891
|
import * as React4 from "react";
|
|
@@ -1024,9 +1025,10 @@ function TypingIndicator({ className = "" }) {
|
|
|
1024
1025
|
|
|
1025
1026
|
// src/ChatPanel.tsx
|
|
1026
1027
|
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1027
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
1028
|
+
var CHAT_PANEL_VERSION = true ? "0.2.47" : "dev";
|
|
1028
1029
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1029
|
-
var PANEL_WIDTH =
|
|
1030
|
+
var PANEL_WIDTH = 400;
|
|
1031
|
+
var PANEL_HEIGHT = 600;
|
|
1030
1032
|
function unescapeJsonString(str) {
|
|
1031
1033
|
return str.replace(/\\\\n/g, "\n").replace(/\\\\t/g, " ").replace(/\\\\"/g, '"').replace(/\\\\\\\\/g, "\\").replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
1032
1034
|
}
|
|
@@ -1483,13 +1485,28 @@ function ChatPanel({
|
|
|
1483
1485
|
orgId,
|
|
1484
1486
|
userName,
|
|
1485
1487
|
userEmail,
|
|
1486
|
-
userOrganization,
|
|
1487
1488
|
supabaseUrl,
|
|
1488
1489
|
supabaseAnonKey,
|
|
1490
|
+
initialCorner = "bottom-left",
|
|
1491
|
+
onCornerChange,
|
|
1489
1492
|
productBackendUrl
|
|
1490
1493
|
} = {}) {
|
|
1491
1494
|
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1492
1495
|
const [input, setInput] = React6.useState("");
|
|
1496
|
+
const [corner, setCorner] = React6.useState(initialCorner);
|
|
1497
|
+
const [isDragging, setIsDragging] = React6.useState(false);
|
|
1498
|
+
const dragControls = useAnimationControls();
|
|
1499
|
+
const handleDragEnd = React6.useCallback((_event, info) => {
|
|
1500
|
+
dragControls.set({ x: 0, y: 0 });
|
|
1501
|
+
setIsDragging(false);
|
|
1502
|
+
const viewportWidth = window.innerWidth;
|
|
1503
|
+
const pointerX = info.point.x;
|
|
1504
|
+
const newCorner = pointerX < viewportWidth / 2 ? "bottom-left" : "bottom-right";
|
|
1505
|
+
if (newCorner !== corner) {
|
|
1506
|
+
setCorner(newCorner);
|
|
1507
|
+
onCornerChange?.(newCorner);
|
|
1508
|
+
}
|
|
1509
|
+
}, [corner, onCornerChange, dragControls]);
|
|
1493
1510
|
const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
|
|
1494
1511
|
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1495
1512
|
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
@@ -2277,7 +2294,6 @@ function ChatPanel({
|
|
|
2277
2294
|
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2278
2295
|
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2279
2296
|
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2280
|
-
console.log("[ChatPanel] user_organization:", userOrganization);
|
|
2281
2297
|
console.log("[ChatPanel] org_id:", orgId);
|
|
2282
2298
|
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2283
2299
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
@@ -2289,11 +2305,10 @@ function ChatPanel({
|
|
|
2289
2305
|
session_id: sessionId,
|
|
2290
2306
|
message: userText,
|
|
2291
2307
|
current_page: currentPage || "dashboard",
|
|
2292
|
-
user_id:
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
org_id: orgId
|
|
2308
|
+
user_id: userId,
|
|
2309
|
+
org_id: orgId,
|
|
2310
|
+
user_name: userName,
|
|
2311
|
+
user_email: userEmail
|
|
2297
2312
|
}),
|
|
2298
2313
|
signal: controller.signal
|
|
2299
2314
|
});
|
|
@@ -3324,12 +3339,21 @@ ${userText}`
|
|
|
3324
3339
|
}
|
|
3325
3340
|
}
|
|
3326
3341
|
return /* @__PURE__ */ jsxs6(
|
|
3327
|
-
|
|
3342
|
+
motion2.section,
|
|
3328
3343
|
{
|
|
3329
|
-
|
|
3330
|
-
|
|
3344
|
+
drag: true,
|
|
3345
|
+
dragMomentum: false,
|
|
3346
|
+
dragElastic: 0,
|
|
3347
|
+
animate: dragControls,
|
|
3348
|
+
onDragStart: () => setIsDragging(true),
|
|
3349
|
+
onDragEnd: handleDragEnd,
|
|
3350
|
+
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"}`,
|
|
3351
|
+
style: {
|
|
3352
|
+
width: `${PANEL_WIDTH}px`,
|
|
3353
|
+
height: `${PANEL_HEIGHT}px`
|
|
3354
|
+
},
|
|
3331
3355
|
children: [
|
|
3332
|
-
/* @__PURE__ */ jsxs6("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", children: [
|
|
3356
|
+
/* @__PURE__ */ jsxs6("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: [
|
|
3333
3357
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2.5", children: [
|
|
3334
3358
|
/* @__PURE__ */ jsx10(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
|
|
3335
3359
|
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
|
|
@@ -3462,12 +3486,12 @@ ${userText}`
|
|
|
3462
3486
|
return null;
|
|
3463
3487
|
}
|
|
3464
3488
|
if (isUser) {
|
|
3465
|
-
return /* @__PURE__ */ jsx10("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ jsx10("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3 py-2 text-
|
|
3489
|
+
return /* @__PURE__ */ jsx10("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ jsx10("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3 py-2 text-sm text-white shadow-sm", children: message.content }) }, message.id);
|
|
3466
3490
|
}
|
|
3467
3491
|
if (message.role === "agent") {
|
|
3468
3492
|
return /* @__PURE__ */ jsxs6("div", { className: `flex flex-col items-start ${isRoleChange ? "mt-3" : ""}`, children: [
|
|
3469
3493
|
isRoleChange && /* @__PURE__ */ jsx10("span", { className: "text-[10px] text-gray-500 mb-1 ml-1", children: "Agent" }),
|
|
3470
|
-
/* @__PURE__ */ jsx10("div", { className: "max-w-[
|
|
3494
|
+
/* @__PURE__ */ jsx10("div", { className: "max-w-[300px] rounded-2xl rounded-bl-md bg-gray-100 px-4 py-3 text-sm text-gray-700", children: message.content })
|
|
3471
3495
|
] }, message.id);
|
|
3472
3496
|
}
|
|
3473
3497
|
if (message.kind === "searchSummary") {
|
|
@@ -4525,7 +4549,7 @@ ${userText}`
|
|
|
4525
4549
|
] }) }) }) })
|
|
4526
4550
|
}
|
|
4527
4551
|
),
|
|
4528
|
-
/* @__PURE__ */ jsxs6("div", { className: "px-4 py-3
|
|
4552
|
+
/* @__PURE__ */ jsxs6("div", { className: "px-4 py-3 bg-white shrink-0", children: [
|
|
4529
4553
|
pendingFile && /* @__PURE__ */ jsxs6("div", { className: "mb-2 flex items-center gap-2 rounded-xl bg-blue-50 border border-blue-200 px-3 py-2", children: [
|
|
4530
4554
|
/* @__PURE__ */ jsx10(FileSpreadsheet, { className: "h-4 w-4 text-blue-600" }),
|
|
4531
4555
|
/* @__PURE__ */ jsx10("span", { className: "text-xs text-blue-700 flex-1 truncate", children: pendingFile.name }),
|
|
@@ -4692,9 +4716,10 @@ function ChatPanelWithToggle({
|
|
|
4692
4716
|
orgId,
|
|
4693
4717
|
userName,
|
|
4694
4718
|
userEmail,
|
|
4695
|
-
userOrganization,
|
|
4696
4719
|
supabaseUrl,
|
|
4697
4720
|
supabaseAnonKey,
|
|
4721
|
+
initialCorner,
|
|
4722
|
+
onCornerChange,
|
|
4698
4723
|
productBackendUrl
|
|
4699
4724
|
}) {
|
|
4700
4725
|
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
@@ -4705,16 +4730,6 @@ function ChatPanelWithToggle({
|
|
|
4705
4730
|
}
|
|
4706
4731
|
onOpenChange?.(open);
|
|
4707
4732
|
};
|
|
4708
|
-
React6.useEffect(() => {
|
|
4709
|
-
const originalPadding = document.body.style.paddingRight;
|
|
4710
|
-
const originalTransition = document.body.style.transition;
|
|
4711
|
-
document.body.style.transition = "padding-right 0.3s ease";
|
|
4712
|
-
document.body.style.paddingRight = isOpen ? `${PANEL_WIDTH}px` : "0px";
|
|
4713
|
-
return () => {
|
|
4714
|
-
document.body.style.paddingRight = originalPadding;
|
|
4715
|
-
document.body.style.transition = originalTransition;
|
|
4716
|
-
};
|
|
4717
|
-
}, [isOpen]);
|
|
4718
4733
|
return /* @__PURE__ */ jsx10(
|
|
4719
4734
|
ChatPanel,
|
|
4720
4735
|
{
|
|
@@ -4731,9 +4746,10 @@ function ChatPanelWithToggle({
|
|
|
4731
4746
|
orgId,
|
|
4732
4747
|
userName,
|
|
4733
4748
|
userEmail,
|
|
4734
|
-
userOrganization,
|
|
4735
4749
|
supabaseUrl,
|
|
4736
4750
|
supabaseAnonKey,
|
|
4751
|
+
initialCorner,
|
|
4752
|
+
onCornerChange,
|
|
4737
4753
|
productBackendUrl
|
|
4738
4754
|
}
|
|
4739
4755
|
);
|
|
@@ -4806,7 +4822,6 @@ function KiteChatWrapper({
|
|
|
4806
4822
|
orgId: config.orgId,
|
|
4807
4823
|
userName: config.userName,
|
|
4808
4824
|
userEmail: config.userEmail,
|
|
4809
|
-
userOrganization: config.userOrganization,
|
|
4810
4825
|
supabaseUrl: config.supabaseUrl,
|
|
4811
4826
|
supabaseAnonKey: config.supabaseAnonKey,
|
|
4812
4827
|
productBackendUrl: config.productBackendUrl
|
|
@@ -82,6 +82,8 @@ type StartingQuestion = {
|
|
|
82
82
|
icon?: "layout" | "upload" | "setup" | "default";
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
/** Corner position for the floating panel */
|
|
86
|
+
type PanelCorner = "bottom-left" | "bottom-right";
|
|
85
87
|
interface ChatPanelProps {
|
|
86
88
|
/** Whether the panel is open (controlled mode) */
|
|
87
89
|
isOpen?: boolean;
|
|
@@ -100,22 +102,24 @@ interface ChatPanelProps {
|
|
|
100
102
|
startingQuestionsEndpoint?: string;
|
|
101
103
|
/** Unique identifier for the current user */
|
|
102
104
|
userId?: string;
|
|
103
|
-
/** Organization
|
|
105
|
+
/** Organization ID for multi-tenant data isolation */
|
|
104
106
|
orgId?: string;
|
|
105
107
|
/** User's display name (for personalization and support) */
|
|
106
108
|
userName?: string;
|
|
107
109
|
/** User's email address (for support agent context) */
|
|
108
110
|
userEmail?: string;
|
|
109
|
-
/** User's organization/company name (for support agent context) */
|
|
110
|
-
userOrganization?: string;
|
|
111
111
|
/** Supabase URL for realtime features (typing indicators in live chat) */
|
|
112
112
|
supabaseUrl?: string;
|
|
113
113
|
/** Supabase anonymous key for realtime features */
|
|
114
114
|
supabaseAnonKey?: string;
|
|
115
|
+
/** Initial corner position for the panel (default: "bottom-left") */
|
|
116
|
+
initialCorner?: PanelCorner;
|
|
117
|
+
/** Callback when panel corner changes after drag */
|
|
118
|
+
onCornerChange?: (corner: PanelCorner) => void;
|
|
115
119
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
116
120
|
productBackendUrl?: string;
|
|
117
121
|
}
|
|
118
|
-
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail,
|
|
122
|
+
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
119
123
|
/**
|
|
120
124
|
* PanelToggle - An arrow button on the right edge that toggles the side panel
|
|
121
125
|
* Shows left arrow when closed (click to open), right arrow when open (click to close)
|
|
@@ -162,22 +166,24 @@ interface ChatPanelWithToggleProps {
|
|
|
162
166
|
onOpenChange?: (isOpen: boolean) => void;
|
|
163
167
|
/** Unique identifier for the current user */
|
|
164
168
|
userId?: string;
|
|
165
|
-
/** Organization
|
|
169
|
+
/** Organization ID for multi-tenant data isolation */
|
|
166
170
|
orgId?: string;
|
|
167
171
|
/** User's display name (for personalization and support) */
|
|
168
172
|
userName?: string;
|
|
169
173
|
/** User's email address (for support agent context) */
|
|
170
174
|
userEmail?: string;
|
|
171
|
-
/** User's organization/company name (for support agent context) */
|
|
172
|
-
userOrganization?: string;
|
|
173
175
|
/** Supabase URL for realtime features (typing indicators in live chat) */
|
|
174
176
|
supabaseUrl?: string;
|
|
175
177
|
/** Supabase anonymous key for realtime features */
|
|
176
178
|
supabaseAnonKey?: string;
|
|
179
|
+
/** Initial corner position for the panel (default: "bottom-left") */
|
|
180
|
+
initialCorner?: PanelCorner;
|
|
181
|
+
/** Callback when panel corner changes after drag */
|
|
182
|
+
onCornerChange?: (corner: PanelCorner) => void;
|
|
177
183
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
178
184
|
productBackendUrl?: string;
|
|
179
185
|
}
|
|
180
|
-
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail,
|
|
186
|
+
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
181
187
|
/**
|
|
182
188
|
* @deprecated Use ChatPanelWithToggle instead for the new side panel UX
|
|
183
189
|
*/
|
|
@@ -203,7 +209,6 @@ declare function HelpButton({ onClick, className }: HelpButtonProps): react_jsx_
|
|
|
203
209
|
*
|
|
204
210
|
* const chat = createKiteChat({
|
|
205
211
|
* userId: 'user-123',
|
|
206
|
-
* orgId: 'org-456',
|
|
207
212
|
* agentUrl: 'https://api.example.com',
|
|
208
213
|
* onNavigate: (page) => router.push(`/${page}`),
|
|
209
214
|
* });
|
|
@@ -222,8 +227,8 @@ declare function HelpButton({ onClick, className }: HelpButtonProps): react_jsx_
|
|
|
222
227
|
interface KiteChatConfig {
|
|
223
228
|
/** Unique identifier for the current user */
|
|
224
229
|
userId: string;
|
|
225
|
-
/** Organization
|
|
226
|
-
orgId
|
|
230
|
+
/** Organization ID for multi-tenant data isolation */
|
|
231
|
+
orgId?: string;
|
|
227
232
|
/** Backend agent API URL (defaults to http://localhost:5002) */
|
|
228
233
|
agentUrl?: string;
|
|
229
234
|
/** Current page context for the chat (e.g., 'dashboard', 'settings') */
|
|
@@ -242,8 +247,6 @@ interface KiteChatConfig {
|
|
|
242
247
|
userName?: string;
|
|
243
248
|
/** User's email address (optional - for support agent context) */
|
|
244
249
|
userEmail?: string;
|
|
245
|
-
/** User's organization/company name (optional - for support agent context) */
|
|
246
|
-
userOrganization?: string;
|
|
247
250
|
/** Supabase URL for realtime features (typing indicators in live chat) */
|
|
248
251
|
supabaseUrl?: string;
|
|
249
252
|
/** Supabase anonymous key for realtime features */
|
|
@@ -269,7 +272,7 @@ interface KiteChatInstance {
|
|
|
269
272
|
isOpen: () => boolean;
|
|
270
273
|
/** Update the current page context */
|
|
271
274
|
setCurrentPage: (page: string) => void;
|
|
272
|
-
/** Update configuration (userId,
|
|
275
|
+
/** Update configuration (userId, callbacks, etc.) */
|
|
273
276
|
updateConfig: (config: Partial<KiteChatConfig>) => void;
|
|
274
277
|
/** Check if the widget is currently mounted */
|
|
275
278
|
isMounted: () => boolean;
|
|
@@ -287,7 +290,6 @@ interface KiteChatInstance {
|
|
|
287
290
|
* ```ts
|
|
288
291
|
* const chat = createKiteChat({
|
|
289
292
|
* userId: 'user-123',
|
|
290
|
-
* orgId: 'org-456',
|
|
291
293
|
* onNavigate: (page) => router.push(`/${page}`)
|
|
292
294
|
* });
|
|
293
295
|
*
|
|
@@ -297,4 +299,4 @@ interface KiteChatInstance {
|
|
|
297
299
|
*/
|
|
298
300
|
declare function createKiteChat(config: KiteChatConfig): KiteChatInstance;
|
|
299
301
|
|
|
300
|
-
export { type ActionType as A, ChatPanel as C, HelpButton as H, type KiteChatConfig as K, type NavigationTarget as N, PanelToggle as P, type SettingsTab as S, type KiteChatInstance as a, ChatPanelWithToggle as b, createKiteChat as c, type ChatPanelProps as d, type ChatPanelWithToggleProps as e, type PanelToggleProps as f, type HelpButtonProps as g, type Page as h, type ActionData as i, type StartingQuestion as j };
|
|
302
|
+
export { type ActionType as A, ChatPanel as C, HelpButton as H, type KiteChatConfig as K, type NavigationTarget as N, PanelToggle as P, type SettingsTab as S, type KiteChatInstance as a, ChatPanelWithToggle as b, createKiteChat as c, type ChatPanelProps as d, type ChatPanelWithToggleProps as e, type PanelToggleProps as f, type HelpButtonProps as g, type Page as h, type ActionData as i, type StartingQuestion as j, type PanelCorner as k };
|