@hef2024/llmasaservice-ui 0.20.1 → 0.20.2
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/index.css +66 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +141 -15
- package/dist/index.mjs +141 -15
- package/package.json +1 -1
- package/src/AIAgentPanel.tsx +89 -8
- package/src/AIChatPanel.css +82 -0
- package/src/AIChatPanel.tsx +82 -6
- package/src/components/ui/ToolInfoModal.tsx +3 -0
- package/src/hooks/useAgentRegistry.ts +0 -1
package/dist/index.css
CHANGED
|
@@ -3371,6 +3371,72 @@ button[data-pending=true]::after {
|
|
|
3371
3371
|
font-family: "SF Mono", monospace;
|
|
3372
3372
|
font-size: 10px;
|
|
3373
3373
|
}
|
|
3374
|
+
.ai-chat-context-popover__detail-section-title-row {
|
|
3375
|
+
display: flex;
|
|
3376
|
+
align-items: center;
|
|
3377
|
+
gap: 12px;
|
|
3378
|
+
flex: 1;
|
|
3379
|
+
min-width: 0;
|
|
3380
|
+
}
|
|
3381
|
+
.ai-chat-context-popover__detail-section--disabled {
|
|
3382
|
+
opacity: 0.6;
|
|
3383
|
+
}
|
|
3384
|
+
.ai-chat-context-popover__detail-section--disabled .ai-chat-context-popover__detail-section-title {
|
|
3385
|
+
text-decoration: line-through;
|
|
3386
|
+
opacity: 0.7;
|
|
3387
|
+
}
|
|
3388
|
+
.ai-chat-context-toggle {
|
|
3389
|
+
position: relative;
|
|
3390
|
+
display: inline-flex;
|
|
3391
|
+
width: 36px;
|
|
3392
|
+
height: 20px;
|
|
3393
|
+
cursor: pointer;
|
|
3394
|
+
user-select: none;
|
|
3395
|
+
flex-shrink: 0;
|
|
3396
|
+
}
|
|
3397
|
+
.ai-chat-context-toggle__input {
|
|
3398
|
+
opacity: 0;
|
|
3399
|
+
width: 0;
|
|
3400
|
+
height: 0;
|
|
3401
|
+
position: absolute;
|
|
3402
|
+
}
|
|
3403
|
+
.ai-chat-context-toggle__slider {
|
|
3404
|
+
position: absolute;
|
|
3405
|
+
top: 0;
|
|
3406
|
+
left: 0;
|
|
3407
|
+
right: 0;
|
|
3408
|
+
bottom: 0;
|
|
3409
|
+
background-color: #cbd5e1;
|
|
3410
|
+
transition: background-color 0.2s ease;
|
|
3411
|
+
border-radius: 20px;
|
|
3412
|
+
}
|
|
3413
|
+
.ai-chat-context-toggle__slider:before {
|
|
3414
|
+
position: absolute;
|
|
3415
|
+
content: "";
|
|
3416
|
+
height: 16px;
|
|
3417
|
+
width: 16px;
|
|
3418
|
+
left: 2px;
|
|
3419
|
+
bottom: 2px;
|
|
3420
|
+
background-color: white;
|
|
3421
|
+
transition: transform 0.2s ease;
|
|
3422
|
+
border-radius: 50%;
|
|
3423
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
3424
|
+
}
|
|
3425
|
+
.ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider {
|
|
3426
|
+
background-color: #3b82f6;
|
|
3427
|
+
}
|
|
3428
|
+
.ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider:before {
|
|
3429
|
+
transform: translateX(16px);
|
|
3430
|
+
}
|
|
3431
|
+
.ai-chat-context-toggle:hover .ai-chat-context-toggle__slider {
|
|
3432
|
+
opacity: 0.9;
|
|
3433
|
+
}
|
|
3434
|
+
.dark-theme .ai-chat-context-toggle__slider {
|
|
3435
|
+
background-color: #4b5563;
|
|
3436
|
+
}
|
|
3437
|
+
.dark-theme .ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider {
|
|
3438
|
+
background-color: #60a5fa;
|
|
3439
|
+
}
|
|
3374
3440
|
.ai-chat-context-popover__detail-content {
|
|
3375
3441
|
margin: 0;
|
|
3376
3442
|
padding: 12px 14px;
|
package/dist/index.d.mts
CHANGED
|
@@ -182,6 +182,7 @@ interface AIAgentPanelHandle {
|
|
|
182
182
|
interface AIAgentPanelProps {
|
|
183
183
|
agents: (string | AgentConfig)[];
|
|
184
184
|
defaultAgent?: string;
|
|
185
|
+
selectedAgent?: string;
|
|
185
186
|
customerId: string;
|
|
186
187
|
apiKey?: string;
|
|
187
188
|
context?: AgentContext | null;
|
|
@@ -325,6 +326,8 @@ interface AIChatPanelProps {
|
|
|
325
326
|
totalContextTokens?: number;
|
|
326
327
|
maxContextTokens?: number;
|
|
327
328
|
enableContextDetailView?: boolean;
|
|
329
|
+
disabledSectionIds?: Set<string>;
|
|
330
|
+
onToggleSection?: (sectionId: string, enabled: boolean) => void;
|
|
328
331
|
onConversationCreated?: (conversationId: string) => void;
|
|
329
332
|
cssUrl?: string;
|
|
330
333
|
markdownClass?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -182,6 +182,7 @@ interface AIAgentPanelHandle {
|
|
|
182
182
|
interface AIAgentPanelProps {
|
|
183
183
|
agents: (string | AgentConfig)[];
|
|
184
184
|
defaultAgent?: string;
|
|
185
|
+
selectedAgent?: string;
|
|
185
186
|
customerId: string;
|
|
186
187
|
apiKey?: string;
|
|
187
188
|
context?: AgentContext | null;
|
|
@@ -325,6 +326,8 @@ interface AIChatPanelProps {
|
|
|
325
326
|
totalContextTokens?: number;
|
|
326
327
|
maxContextTokens?: number;
|
|
327
328
|
enableContextDetailView?: boolean;
|
|
329
|
+
disabledSectionIds?: Set<string>;
|
|
330
|
+
onToggleSection?: (sectionId: string, enabled: boolean) => void;
|
|
328
331
|
onConversationCreated?: (conversationId: string) => void;
|
|
329
332
|
cssUrl?: string;
|
|
330
333
|
markdownClass?: string;
|
package/dist/index.js
CHANGED
|
@@ -3500,12 +3500,15 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3500
3500
|
contextSections = [],
|
|
3501
3501
|
totalContextTokens = 0,
|
|
3502
3502
|
maxContextTokens = 8e3,
|
|
3503
|
-
enableContextDetailView = false
|
|
3503
|
+
enableContextDetailView = false,
|
|
3504
|
+
disabledSectionIds = /* @__PURE__ */ new Set(),
|
|
3505
|
+
onToggleSection
|
|
3504
3506
|
}) => {
|
|
3505
3507
|
const [inputValue, setInputValue] = (0, import_react12.useState)("");
|
|
3506
3508
|
const [dropdownOpen, setDropdownOpen] = (0, import_react12.useState)(false);
|
|
3507
3509
|
const [contextViewerOpen, setContextViewerOpen] = (0, import_react12.useState)(false);
|
|
3508
3510
|
const [contextViewMode, setContextViewMode] = (0, import_react12.useState)("summary");
|
|
3511
|
+
const [expandedSectionId, setExpandedSectionId] = (0, import_react12.useState)(null);
|
|
3509
3512
|
const textareaRef = (0, import_react12.useRef)(null);
|
|
3510
3513
|
const containerRef = (0, import_react12.useRef)(null);
|
|
3511
3514
|
const contextPopoverRef = (0, import_react12.useRef)(null);
|
|
@@ -3542,6 +3545,7 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3542
3545
|
if (contextPopoverRef.current && !contextPopoverRef.current.contains(event.target)) {
|
|
3543
3546
|
setContextViewerOpen(false);
|
|
3544
3547
|
setContextViewMode("summary");
|
|
3548
|
+
setExpandedSectionId(null);
|
|
3545
3549
|
}
|
|
3546
3550
|
};
|
|
3547
3551
|
if (contextViewerOpen) {
|
|
@@ -3623,6 +3627,9 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3623
3627
|
setContextViewerOpen(!contextViewerOpen);
|
|
3624
3628
|
if (!contextViewerOpen) {
|
|
3625
3629
|
setContextViewMode("summary");
|
|
3630
|
+
setExpandedSectionId(null);
|
|
3631
|
+
} else {
|
|
3632
|
+
setExpandedSectionId(null);
|
|
3626
3633
|
}
|
|
3627
3634
|
},
|
|
3628
3635
|
type: "button",
|
|
@@ -3640,7 +3647,10 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3640
3647
|
"button",
|
|
3641
3648
|
{
|
|
3642
3649
|
className: "ai-chat-context-popover__close",
|
|
3643
|
-
onClick: () =>
|
|
3650
|
+
onClick: () => {
|
|
3651
|
+
setContextViewerOpen(false);
|
|
3652
|
+
setExpandedSectionId(null);
|
|
3653
|
+
},
|
|
3644
3654
|
type: "button"
|
|
3645
3655
|
},
|
|
3646
3656
|
"\xD7"
|
|
@@ -3657,6 +3667,7 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3657
3667
|
className: `ai-chat-context-popover__section-item ${enableContextDetailView ? "ai-chat-context-popover__section-item--clickable" : ""}`,
|
|
3658
3668
|
onClick: () => {
|
|
3659
3669
|
if (enableContextDetailView) {
|
|
3670
|
+
setExpandedSectionId(section.id);
|
|
3660
3671
|
setContextViewMode("detail");
|
|
3661
3672
|
}
|
|
3662
3673
|
}
|
|
@@ -3668,7 +3679,10 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3668
3679
|
"button",
|
|
3669
3680
|
{
|
|
3670
3681
|
className: "ai-chat-context-popover__expand-btn",
|
|
3671
|
-
onClick: () =>
|
|
3682
|
+
onClick: () => {
|
|
3683
|
+
setExpandedSectionId(null);
|
|
3684
|
+
setContextViewMode("detail");
|
|
3685
|
+
},
|
|
3672
3686
|
type: "button"
|
|
3673
3687
|
},
|
|
3674
3688
|
"View details \u2192"
|
|
@@ -3677,7 +3691,10 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3677
3691
|
"button",
|
|
3678
3692
|
{
|
|
3679
3693
|
className: "ai-chat-context-popover__back",
|
|
3680
|
-
onClick: () =>
|
|
3694
|
+
onClick: () => {
|
|
3695
|
+
setContextViewMode("summary");
|
|
3696
|
+
setExpandedSectionId(null);
|
|
3697
|
+
},
|
|
3681
3698
|
type: "button"
|
|
3682
3699
|
},
|
|
3683
3700
|
"\u2190 Back"
|
|
@@ -3685,7 +3702,10 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3685
3702
|
"button",
|
|
3686
3703
|
{
|
|
3687
3704
|
className: "ai-chat-context-popover__close",
|
|
3688
|
-
onClick: () =>
|
|
3705
|
+
onClick: () => {
|
|
3706
|
+
setContextViewerOpen(false);
|
|
3707
|
+
setExpandedSectionId(null);
|
|
3708
|
+
},
|
|
3689
3709
|
type: "button"
|
|
3690
3710
|
},
|
|
3691
3711
|
"\xD7"
|
|
@@ -3697,7 +3717,39 @@ var ChatInput = import_react12.default.memo(({
|
|
|
3697
3717
|
}
|
|
3698
3718
|
))), /* @__PURE__ */ import_react12.default.createElement("div", { className: "ai-chat-context-popover__detail-sections" }, contextSections.map((section) => {
|
|
3699
3719
|
const format = detectFormat(section.data);
|
|
3700
|
-
|
|
3720
|
+
const isEnabled = !disabledSectionIds.has(section.id);
|
|
3721
|
+
return /* @__PURE__ */ import_react12.default.createElement(
|
|
3722
|
+
"details",
|
|
3723
|
+
{
|
|
3724
|
+
key: section.id,
|
|
3725
|
+
className: `ai-chat-context-popover__detail-section ${!isEnabled ? "ai-chat-context-popover__detail-section--disabled" : ""}`,
|
|
3726
|
+
open: expandedSectionId === section.id
|
|
3727
|
+
},
|
|
3728
|
+
/* @__PURE__ */ import_react12.default.createElement("summary", { className: "ai-chat-context-popover__detail-section-header" }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "ai-chat-context-popover__detail-section-title-row" }, /* @__PURE__ */ import_react12.default.createElement("span", { className: "ai-chat-context-popover__detail-section-title" }, section.title), /* @__PURE__ */ import_react12.default.createElement(
|
|
3729
|
+
"label",
|
|
3730
|
+
{
|
|
3731
|
+
className: "ai-chat-context-toggle",
|
|
3732
|
+
onClick: (e) => e.stopPropagation(),
|
|
3733
|
+
title: isEnabled ? "Disable this context section" : "Enable this context section"
|
|
3734
|
+
},
|
|
3735
|
+
/* @__PURE__ */ import_react12.default.createElement(
|
|
3736
|
+
"input",
|
|
3737
|
+
{
|
|
3738
|
+
type: "checkbox",
|
|
3739
|
+
checked: isEnabled,
|
|
3740
|
+
onChange: (e) => {
|
|
3741
|
+
e.stopPropagation();
|
|
3742
|
+
if (onToggleSection) {
|
|
3743
|
+
onToggleSection(section.id, !isEnabled);
|
|
3744
|
+
}
|
|
3745
|
+
},
|
|
3746
|
+
className: "ai-chat-context-toggle__input"
|
|
3747
|
+
}
|
|
3748
|
+
),
|
|
3749
|
+
/* @__PURE__ */ import_react12.default.createElement("span", { className: "ai-chat-context-toggle__slider" })
|
|
3750
|
+
)), /* @__PURE__ */ import_react12.default.createElement("span", { className: "ai-chat-context-popover__detail-section-meta" }, /* @__PURE__ */ import_react12.default.createElement("code", null, `{{${section.id}}}`), /* @__PURE__ */ import_react12.default.createElement("span", null, "~", section.tokens || Math.ceil(JSON.stringify(section.data).length / 4)))),
|
|
3751
|
+
/* @__PURE__ */ import_react12.default.createElement("pre", { className: "ai-chat-context-popover__detail-content" }, /* @__PURE__ */ import_react12.default.createElement("code", null, formatContent(section.data, format)))
|
|
3752
|
+
);
|
|
3701
3753
|
})))
|
|
3702
3754
|
)), /* @__PURE__ */ import_react12.default.createElement(
|
|
3703
3755
|
"button",
|
|
@@ -3773,6 +3825,8 @@ var AIChatPanel = ({
|
|
|
3773
3825
|
totalContextTokens = 0,
|
|
3774
3826
|
maxContextTokens = 8e3,
|
|
3775
3827
|
enableContextDetailView = false,
|
|
3828
|
+
disabledSectionIds: propDisabledSectionIds,
|
|
3829
|
+
onToggleSection: propOnToggleSection,
|
|
3776
3830
|
onConversationCreated,
|
|
3777
3831
|
// UI Customization Props
|
|
3778
3832
|
cssUrl,
|
|
@@ -3824,6 +3878,8 @@ var AIChatPanel = ({
|
|
|
3824
3878
|
const [pendingToolRequests, setPendingToolRequests] = (0, import_react12.useState)([]);
|
|
3825
3879
|
const [sessionApprovedTools, setSessionApprovedTools] = (0, import_react12.useState)([]);
|
|
3826
3880
|
const [alwaysApprovedTools, setAlwaysApprovedTools] = (0, import_react12.useState)([]);
|
|
3881
|
+
const [internalDisabledSectionIds, setInternalDisabledSectionIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
3882
|
+
const disabledSectionIds = propDisabledSectionIds != null ? propDisabledSectionIds : internalDisabledSectionIds;
|
|
3827
3883
|
(0, import_react12.useEffect)(() => {
|
|
3828
3884
|
setShowEmailPanel(customerEmailCaptureMode !== "HIDE");
|
|
3829
3885
|
if (customerEmailCaptureMode === "REQUIRED") {
|
|
@@ -3901,6 +3957,21 @@ var AIChatPanel = ({
|
|
|
3901
3957
|
userLanguage: navigator.language
|
|
3902
3958
|
};
|
|
3903
3959
|
}, []);
|
|
3960
|
+
const handleToggleSection = (0, import_react12.useCallback)((sectionId, enabled) => {
|
|
3961
|
+
if (propOnToggleSection) {
|
|
3962
|
+
propOnToggleSection(sectionId, enabled);
|
|
3963
|
+
} else {
|
|
3964
|
+
setInternalDisabledSectionIds((prev) => {
|
|
3965
|
+
const next = new Set(prev);
|
|
3966
|
+
if (enabled) {
|
|
3967
|
+
next.delete(sectionId);
|
|
3968
|
+
} else {
|
|
3969
|
+
next.add(sectionId);
|
|
3970
|
+
}
|
|
3971
|
+
return next;
|
|
3972
|
+
});
|
|
3973
|
+
}
|
|
3974
|
+
}, [propOnToggleSection]);
|
|
3904
3975
|
const ensureConversation = (0, import_react12.useCallback)(() => {
|
|
3905
3976
|
var _a2, _b;
|
|
3906
3977
|
console.log("ensureConversation - called with:", {
|
|
@@ -5041,7 +5112,9 @@ var AIChatPanel = ({
|
|
|
5041
5112
|
contextSections,
|
|
5042
5113
|
totalContextTokens,
|
|
5043
5114
|
maxContextTokens,
|
|
5044
|
-
enableContextDetailView
|
|
5115
|
+
enableContextDetailView,
|
|
5116
|
+
disabledSectionIds,
|
|
5117
|
+
onToggleSection: handleToggleSection
|
|
5045
5118
|
}
|
|
5046
5119
|
),
|
|
5047
5120
|
showPoweredBy && /* @__PURE__ */ import_react12.default.createElement("div", { className: "ai-chat-panel__footer" }, mcpServers && mcpServers.length > 0 && /* @__PURE__ */ import_react12.default.createElement("div", { className: "ai-chat-tools-status" }, /* @__PURE__ */ import_react12.default.createElement(
|
|
@@ -5392,6 +5465,8 @@ var ChatPanelWrapper = ({
|
|
|
5392
5465
|
totalContextTokens,
|
|
5393
5466
|
maxContextTokens,
|
|
5394
5467
|
enableContextDetailView,
|
|
5468
|
+
disabledSectionIds,
|
|
5469
|
+
onToggleSection,
|
|
5395
5470
|
onConversationCreated,
|
|
5396
5471
|
conversationInitialPrompt,
|
|
5397
5472
|
// New props from ChatPanel port
|
|
@@ -5493,6 +5568,8 @@ var ChatPanelWrapper = ({
|
|
|
5493
5568
|
totalContextTokens,
|
|
5494
5569
|
maxContextTokens,
|
|
5495
5570
|
enableContextDetailView,
|
|
5571
|
+
disabledSectionIds,
|
|
5572
|
+
onToggleSection,
|
|
5496
5573
|
onConversationCreated: conversationCreatedCallback,
|
|
5497
5574
|
cssUrl,
|
|
5498
5575
|
markdownClass,
|
|
@@ -5517,6 +5594,7 @@ ChatPanelWrapper.displayName = "ChatPanelWrapper";
|
|
|
5517
5594
|
var AIAgentPanel = import_react14.default.forwardRef(({
|
|
5518
5595
|
agents,
|
|
5519
5596
|
defaultAgent,
|
|
5597
|
+
selectedAgent,
|
|
5520
5598
|
customerId,
|
|
5521
5599
|
apiKey,
|
|
5522
5600
|
context,
|
|
@@ -5620,6 +5698,28 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
5620
5698
|
const [currentAgentId, setCurrentAgentId] = (0, import_react14.useState)(
|
|
5621
5699
|
defaultAgent || agentIds[0] || ""
|
|
5622
5700
|
);
|
|
5701
|
+
(0, import_react14.useEffect)(() => {
|
|
5702
|
+
if (selectedAgent && selectedAgent !== currentAgentId) {
|
|
5703
|
+
const oldAgentId = currentAgentId;
|
|
5704
|
+
setCurrentAgentId(selectedAgent);
|
|
5705
|
+
if (onAgentSwitch) {
|
|
5706
|
+
onAgentSwitch(oldAgentId, selectedAgent);
|
|
5707
|
+
}
|
|
5708
|
+
if (currentConversationIdRef.current) {
|
|
5709
|
+
setActiveConversations((prev) => {
|
|
5710
|
+
const existing = prev.get(currentConversationIdRef.current);
|
|
5711
|
+
if (existing) {
|
|
5712
|
+
const next = new Map(prev);
|
|
5713
|
+
next.set(currentConversationIdRef.current, __spreadProps(__spreadValues({}, existing), {
|
|
5714
|
+
agentId: selectedAgent
|
|
5715
|
+
}));
|
|
5716
|
+
return next;
|
|
5717
|
+
}
|
|
5718
|
+
return prev;
|
|
5719
|
+
});
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
}, [selectedAgent]);
|
|
5623
5723
|
const [apiConversations, setApiConversations] = (0, import_react14.useState)([]);
|
|
5624
5724
|
const [conversationsLoading, setConversationsLoading] = (0, import_react14.useState)(false);
|
|
5625
5725
|
const [conversationsError, setConversationsError] = (0, import_react14.useState)(null);
|
|
@@ -5636,6 +5736,7 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
5636
5736
|
"This Month": false,
|
|
5637
5737
|
"Older": false
|
|
5638
5738
|
});
|
|
5739
|
+
const [disabledContextSections, setDisabledContextSections] = (0, import_react14.useState)(/* @__PURE__ */ new Map());
|
|
5639
5740
|
const {
|
|
5640
5741
|
agents: agentProfiles,
|
|
5641
5742
|
isLoading: agentsLoading,
|
|
@@ -5779,13 +5880,8 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
5779
5880
|
fetchInProgressRef.current = true;
|
|
5780
5881
|
setConversationsLoading(true);
|
|
5781
5882
|
setConversationsError(null);
|
|
5782
|
-
console.log("projectId", projectId);
|
|
5783
|
-
console.log("customerId", customerId);
|
|
5784
|
-
console.log("apiKey", apiKey);
|
|
5785
5883
|
try {
|
|
5786
|
-
console.log("fetchConversations - customerId:", customerId);
|
|
5787
5884
|
const url2 = `https://api.llmasaservice.io/conversations?customer_id=${customerId}`;
|
|
5788
|
-
console.log("fetchConversations - URL:", url2);
|
|
5789
5885
|
const response = yield fetch(url2, {
|
|
5790
5886
|
signal,
|
|
5791
5887
|
headers: {
|
|
@@ -6169,8 +6265,21 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6169
6265
|
});
|
|
6170
6266
|
}
|
|
6171
6267
|
}, [pageContextSections, currentAgentId, agentIds, getAgent, localOverrides]);
|
|
6268
|
+
const currentDisabledSections = (0, import_react14.useMemo)(() => {
|
|
6269
|
+
return currentConversationId ? disabledContextSections.get(currentConversationId) || /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
|
|
6270
|
+
}, [currentConversationId, disabledContextSections]);
|
|
6271
|
+
const filteredContext = (0, import_react14.useMemo)(() => {
|
|
6272
|
+
const enabledSections = mergedContext.sections.filter(
|
|
6273
|
+
(section) => !currentDisabledSections.has(section.id)
|
|
6274
|
+
);
|
|
6275
|
+
const totalTokens = enabledSections.reduce((sum, s) => sum + (s.tokens || 0), 0);
|
|
6276
|
+
return {
|
|
6277
|
+
sections: enabledSections,
|
|
6278
|
+
totalTokens
|
|
6279
|
+
};
|
|
6280
|
+
}, [mergedContext.sections, currentDisabledSections]);
|
|
6172
6281
|
const chatPanelData = (0, import_react14.useMemo)(() => {
|
|
6173
|
-
const contextData =
|
|
6282
|
+
const contextData = filteredContext.sections.map((section) => ({
|
|
6174
6283
|
key: section.id,
|
|
6175
6284
|
data: JSON.stringify(section.data)
|
|
6176
6285
|
}));
|
|
@@ -6184,7 +6293,7 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6184
6293
|
}
|
|
6185
6294
|
}
|
|
6186
6295
|
return [...data, ...contextData];
|
|
6187
|
-
}, [data,
|
|
6296
|
+
}, [data, filteredContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
|
|
6188
6297
|
const handleAgentSwitch = (0, import_react14.useCallback)(
|
|
6189
6298
|
(newAgentId) => {
|
|
6190
6299
|
const oldAgentId = currentAgentId;
|
|
@@ -6315,6 +6424,21 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6315
6424
|
setSuggestedAgent(null);
|
|
6316
6425
|
setHandoffSource("agent");
|
|
6317
6426
|
}, []);
|
|
6427
|
+
const handleContextSectionToggle = (0, import_react14.useCallback)((sectionId, enabled) => {
|
|
6428
|
+
if (!currentConversationId) return;
|
|
6429
|
+
setDisabledContextSections((prev) => {
|
|
6430
|
+
const next = new Map(prev);
|
|
6431
|
+
const conversationDisabled = next.get(currentConversationId) || /* @__PURE__ */ new Set();
|
|
6432
|
+
const nextDisabled = new Set(conversationDisabled);
|
|
6433
|
+
if (enabled) {
|
|
6434
|
+
nextDisabled.delete(sectionId);
|
|
6435
|
+
} else {
|
|
6436
|
+
nextDisabled.add(sectionId);
|
|
6437
|
+
}
|
|
6438
|
+
next.set(currentConversationId, nextDisabled);
|
|
6439
|
+
return next;
|
|
6440
|
+
});
|
|
6441
|
+
}, [currentConversationId]);
|
|
6318
6442
|
const handleConversationCreated = (0, import_react14.useCallback)((tempId, realId) => {
|
|
6319
6443
|
console.log("Conversation created:", tempId, "->", realId);
|
|
6320
6444
|
setActiveConversations((prev) => {
|
|
@@ -6648,9 +6772,11 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6648
6772
|
handleAgentSwitch,
|
|
6649
6773
|
agentsLoading,
|
|
6650
6774
|
contextSections: mergedContext.sections,
|
|
6651
|
-
totalContextTokens:
|
|
6775
|
+
totalContextTokens: filteredContext.totalTokens,
|
|
6652
6776
|
maxContextTokens,
|
|
6653
6777
|
enableContextDetailView,
|
|
6778
|
+
disabledSectionIds: currentDisabledSections,
|
|
6779
|
+
onToggleSection: handleContextSectionToggle,
|
|
6654
6780
|
onConversationCreated: handleConversationCreated,
|
|
6655
6781
|
conversationInitialPrompt: activeConv.conversationInitialPrompt,
|
|
6656
6782
|
cssUrl,
|
package/dist/index.mjs
CHANGED
|
@@ -3467,12 +3467,15 @@ var ChatInput = React12.memo(({
|
|
|
3467
3467
|
contextSections = [],
|
|
3468
3468
|
totalContextTokens = 0,
|
|
3469
3469
|
maxContextTokens = 8e3,
|
|
3470
|
-
enableContextDetailView = false
|
|
3470
|
+
enableContextDetailView = false,
|
|
3471
|
+
disabledSectionIds = /* @__PURE__ */ new Set(),
|
|
3472
|
+
onToggleSection
|
|
3471
3473
|
}) => {
|
|
3472
3474
|
const [inputValue, setInputValue] = useState6("");
|
|
3473
3475
|
const [dropdownOpen, setDropdownOpen] = useState6(false);
|
|
3474
3476
|
const [contextViewerOpen, setContextViewerOpen] = useState6(false);
|
|
3475
3477
|
const [contextViewMode, setContextViewMode] = useState6("summary");
|
|
3478
|
+
const [expandedSectionId, setExpandedSectionId] = useState6(null);
|
|
3476
3479
|
const textareaRef = useRef5(null);
|
|
3477
3480
|
const containerRef = useRef5(null);
|
|
3478
3481
|
const contextPopoverRef = useRef5(null);
|
|
@@ -3509,6 +3512,7 @@ var ChatInput = React12.memo(({
|
|
|
3509
3512
|
if (contextPopoverRef.current && !contextPopoverRef.current.contains(event.target)) {
|
|
3510
3513
|
setContextViewerOpen(false);
|
|
3511
3514
|
setContextViewMode("summary");
|
|
3515
|
+
setExpandedSectionId(null);
|
|
3512
3516
|
}
|
|
3513
3517
|
};
|
|
3514
3518
|
if (contextViewerOpen) {
|
|
@@ -3590,6 +3594,9 @@ var ChatInput = React12.memo(({
|
|
|
3590
3594
|
setContextViewerOpen(!contextViewerOpen);
|
|
3591
3595
|
if (!contextViewerOpen) {
|
|
3592
3596
|
setContextViewMode("summary");
|
|
3597
|
+
setExpandedSectionId(null);
|
|
3598
|
+
} else {
|
|
3599
|
+
setExpandedSectionId(null);
|
|
3593
3600
|
}
|
|
3594
3601
|
},
|
|
3595
3602
|
type: "button",
|
|
@@ -3607,7 +3614,10 @@ var ChatInput = React12.memo(({
|
|
|
3607
3614
|
"button",
|
|
3608
3615
|
{
|
|
3609
3616
|
className: "ai-chat-context-popover__close",
|
|
3610
|
-
onClick: () =>
|
|
3617
|
+
onClick: () => {
|
|
3618
|
+
setContextViewerOpen(false);
|
|
3619
|
+
setExpandedSectionId(null);
|
|
3620
|
+
},
|
|
3611
3621
|
type: "button"
|
|
3612
3622
|
},
|
|
3613
3623
|
"\xD7"
|
|
@@ -3624,6 +3634,7 @@ var ChatInput = React12.memo(({
|
|
|
3624
3634
|
className: `ai-chat-context-popover__section-item ${enableContextDetailView ? "ai-chat-context-popover__section-item--clickable" : ""}`,
|
|
3625
3635
|
onClick: () => {
|
|
3626
3636
|
if (enableContextDetailView) {
|
|
3637
|
+
setExpandedSectionId(section.id);
|
|
3627
3638
|
setContextViewMode("detail");
|
|
3628
3639
|
}
|
|
3629
3640
|
}
|
|
@@ -3635,7 +3646,10 @@ var ChatInput = React12.memo(({
|
|
|
3635
3646
|
"button",
|
|
3636
3647
|
{
|
|
3637
3648
|
className: "ai-chat-context-popover__expand-btn",
|
|
3638
|
-
onClick: () =>
|
|
3649
|
+
onClick: () => {
|
|
3650
|
+
setExpandedSectionId(null);
|
|
3651
|
+
setContextViewMode("detail");
|
|
3652
|
+
},
|
|
3639
3653
|
type: "button"
|
|
3640
3654
|
},
|
|
3641
3655
|
"View details \u2192"
|
|
@@ -3644,7 +3658,10 @@ var ChatInput = React12.memo(({
|
|
|
3644
3658
|
"button",
|
|
3645
3659
|
{
|
|
3646
3660
|
className: "ai-chat-context-popover__back",
|
|
3647
|
-
onClick: () =>
|
|
3661
|
+
onClick: () => {
|
|
3662
|
+
setContextViewMode("summary");
|
|
3663
|
+
setExpandedSectionId(null);
|
|
3664
|
+
},
|
|
3648
3665
|
type: "button"
|
|
3649
3666
|
},
|
|
3650
3667
|
"\u2190 Back"
|
|
@@ -3652,7 +3669,10 @@ var ChatInput = React12.memo(({
|
|
|
3652
3669
|
"button",
|
|
3653
3670
|
{
|
|
3654
3671
|
className: "ai-chat-context-popover__close",
|
|
3655
|
-
onClick: () =>
|
|
3672
|
+
onClick: () => {
|
|
3673
|
+
setContextViewerOpen(false);
|
|
3674
|
+
setExpandedSectionId(null);
|
|
3675
|
+
},
|
|
3656
3676
|
type: "button"
|
|
3657
3677
|
},
|
|
3658
3678
|
"\xD7"
|
|
@@ -3664,7 +3684,39 @@ var ChatInput = React12.memo(({
|
|
|
3664
3684
|
}
|
|
3665
3685
|
))), /* @__PURE__ */ React12.createElement("div", { className: "ai-chat-context-popover__detail-sections" }, contextSections.map((section) => {
|
|
3666
3686
|
const format = detectFormat(section.data);
|
|
3667
|
-
|
|
3687
|
+
const isEnabled = !disabledSectionIds.has(section.id);
|
|
3688
|
+
return /* @__PURE__ */ React12.createElement(
|
|
3689
|
+
"details",
|
|
3690
|
+
{
|
|
3691
|
+
key: section.id,
|
|
3692
|
+
className: `ai-chat-context-popover__detail-section ${!isEnabled ? "ai-chat-context-popover__detail-section--disabled" : ""}`,
|
|
3693
|
+
open: expandedSectionId === section.id
|
|
3694
|
+
},
|
|
3695
|
+
/* @__PURE__ */ React12.createElement("summary", { className: "ai-chat-context-popover__detail-section-header" }, /* @__PURE__ */ React12.createElement("div", { className: "ai-chat-context-popover__detail-section-title-row" }, /* @__PURE__ */ React12.createElement("span", { className: "ai-chat-context-popover__detail-section-title" }, section.title), /* @__PURE__ */ React12.createElement(
|
|
3696
|
+
"label",
|
|
3697
|
+
{
|
|
3698
|
+
className: "ai-chat-context-toggle",
|
|
3699
|
+
onClick: (e) => e.stopPropagation(),
|
|
3700
|
+
title: isEnabled ? "Disable this context section" : "Enable this context section"
|
|
3701
|
+
},
|
|
3702
|
+
/* @__PURE__ */ React12.createElement(
|
|
3703
|
+
"input",
|
|
3704
|
+
{
|
|
3705
|
+
type: "checkbox",
|
|
3706
|
+
checked: isEnabled,
|
|
3707
|
+
onChange: (e) => {
|
|
3708
|
+
e.stopPropagation();
|
|
3709
|
+
if (onToggleSection) {
|
|
3710
|
+
onToggleSection(section.id, !isEnabled);
|
|
3711
|
+
}
|
|
3712
|
+
},
|
|
3713
|
+
className: "ai-chat-context-toggle__input"
|
|
3714
|
+
}
|
|
3715
|
+
),
|
|
3716
|
+
/* @__PURE__ */ React12.createElement("span", { className: "ai-chat-context-toggle__slider" })
|
|
3717
|
+
)), /* @__PURE__ */ React12.createElement("span", { className: "ai-chat-context-popover__detail-section-meta" }, /* @__PURE__ */ React12.createElement("code", null, `{{${section.id}}}`), /* @__PURE__ */ React12.createElement("span", null, "~", section.tokens || Math.ceil(JSON.stringify(section.data).length / 4)))),
|
|
3718
|
+
/* @__PURE__ */ React12.createElement("pre", { className: "ai-chat-context-popover__detail-content" }, /* @__PURE__ */ React12.createElement("code", null, formatContent(section.data, format)))
|
|
3719
|
+
);
|
|
3668
3720
|
})))
|
|
3669
3721
|
)), /* @__PURE__ */ React12.createElement(
|
|
3670
3722
|
"button",
|
|
@@ -3740,6 +3792,8 @@ var AIChatPanel = ({
|
|
|
3740
3792
|
totalContextTokens = 0,
|
|
3741
3793
|
maxContextTokens = 8e3,
|
|
3742
3794
|
enableContextDetailView = false,
|
|
3795
|
+
disabledSectionIds: propDisabledSectionIds,
|
|
3796
|
+
onToggleSection: propOnToggleSection,
|
|
3743
3797
|
onConversationCreated,
|
|
3744
3798
|
// UI Customization Props
|
|
3745
3799
|
cssUrl,
|
|
@@ -3791,6 +3845,8 @@ var AIChatPanel = ({
|
|
|
3791
3845
|
const [pendingToolRequests, setPendingToolRequests] = useState6([]);
|
|
3792
3846
|
const [sessionApprovedTools, setSessionApprovedTools] = useState6([]);
|
|
3793
3847
|
const [alwaysApprovedTools, setAlwaysApprovedTools] = useState6([]);
|
|
3848
|
+
const [internalDisabledSectionIds, setInternalDisabledSectionIds] = useState6(/* @__PURE__ */ new Set());
|
|
3849
|
+
const disabledSectionIds = propDisabledSectionIds != null ? propDisabledSectionIds : internalDisabledSectionIds;
|
|
3794
3850
|
useEffect7(() => {
|
|
3795
3851
|
setShowEmailPanel(customerEmailCaptureMode !== "HIDE");
|
|
3796
3852
|
if (customerEmailCaptureMode === "REQUIRED") {
|
|
@@ -3868,6 +3924,21 @@ var AIChatPanel = ({
|
|
|
3868
3924
|
userLanguage: navigator.language
|
|
3869
3925
|
};
|
|
3870
3926
|
}, []);
|
|
3927
|
+
const handleToggleSection = useCallback2((sectionId, enabled) => {
|
|
3928
|
+
if (propOnToggleSection) {
|
|
3929
|
+
propOnToggleSection(sectionId, enabled);
|
|
3930
|
+
} else {
|
|
3931
|
+
setInternalDisabledSectionIds((prev) => {
|
|
3932
|
+
const next = new Set(prev);
|
|
3933
|
+
if (enabled) {
|
|
3934
|
+
next.delete(sectionId);
|
|
3935
|
+
} else {
|
|
3936
|
+
next.add(sectionId);
|
|
3937
|
+
}
|
|
3938
|
+
return next;
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}, [propOnToggleSection]);
|
|
3871
3942
|
const ensureConversation = useCallback2(() => {
|
|
3872
3943
|
var _a2, _b;
|
|
3873
3944
|
console.log("ensureConversation - called with:", {
|
|
@@ -5008,7 +5079,9 @@ var AIChatPanel = ({
|
|
|
5008
5079
|
contextSections,
|
|
5009
5080
|
totalContextTokens,
|
|
5010
5081
|
maxContextTokens,
|
|
5011
|
-
enableContextDetailView
|
|
5082
|
+
enableContextDetailView,
|
|
5083
|
+
disabledSectionIds,
|
|
5084
|
+
onToggleSection: handleToggleSection
|
|
5012
5085
|
}
|
|
5013
5086
|
),
|
|
5014
5087
|
showPoweredBy && /* @__PURE__ */ React12.createElement("div", { className: "ai-chat-panel__footer" }, mcpServers && mcpServers.length > 0 && /* @__PURE__ */ React12.createElement("div", { className: "ai-chat-tools-status" }, /* @__PURE__ */ React12.createElement(
|
|
@@ -5359,6 +5432,8 @@ var ChatPanelWrapper = ({
|
|
|
5359
5432
|
totalContextTokens,
|
|
5360
5433
|
maxContextTokens,
|
|
5361
5434
|
enableContextDetailView,
|
|
5435
|
+
disabledSectionIds,
|
|
5436
|
+
onToggleSection,
|
|
5362
5437
|
onConversationCreated,
|
|
5363
5438
|
conversationInitialPrompt,
|
|
5364
5439
|
// New props from ChatPanel port
|
|
@@ -5460,6 +5535,8 @@ var ChatPanelWrapper = ({
|
|
|
5460
5535
|
totalContextTokens,
|
|
5461
5536
|
maxContextTokens,
|
|
5462
5537
|
enableContextDetailView,
|
|
5538
|
+
disabledSectionIds,
|
|
5539
|
+
onToggleSection,
|
|
5463
5540
|
onConversationCreated: conversationCreatedCallback,
|
|
5464
5541
|
cssUrl,
|
|
5465
5542
|
markdownClass,
|
|
@@ -5484,6 +5561,7 @@ ChatPanelWrapper.displayName = "ChatPanelWrapper";
|
|
|
5484
5561
|
var AIAgentPanel = React13.forwardRef(({
|
|
5485
5562
|
agents,
|
|
5486
5563
|
defaultAgent,
|
|
5564
|
+
selectedAgent,
|
|
5487
5565
|
customerId,
|
|
5488
5566
|
apiKey,
|
|
5489
5567
|
context,
|
|
@@ -5587,6 +5665,28 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
5587
5665
|
const [currentAgentId, setCurrentAgentId] = useState8(
|
|
5588
5666
|
defaultAgent || agentIds[0] || ""
|
|
5589
5667
|
);
|
|
5668
|
+
useEffect9(() => {
|
|
5669
|
+
if (selectedAgent && selectedAgent !== currentAgentId) {
|
|
5670
|
+
const oldAgentId = currentAgentId;
|
|
5671
|
+
setCurrentAgentId(selectedAgent);
|
|
5672
|
+
if (onAgentSwitch) {
|
|
5673
|
+
onAgentSwitch(oldAgentId, selectedAgent);
|
|
5674
|
+
}
|
|
5675
|
+
if (currentConversationIdRef.current) {
|
|
5676
|
+
setActiveConversations((prev) => {
|
|
5677
|
+
const existing = prev.get(currentConversationIdRef.current);
|
|
5678
|
+
if (existing) {
|
|
5679
|
+
const next = new Map(prev);
|
|
5680
|
+
next.set(currentConversationIdRef.current, __spreadProps(__spreadValues({}, existing), {
|
|
5681
|
+
agentId: selectedAgent
|
|
5682
|
+
}));
|
|
5683
|
+
return next;
|
|
5684
|
+
}
|
|
5685
|
+
return prev;
|
|
5686
|
+
});
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
}, [selectedAgent]);
|
|
5590
5690
|
const [apiConversations, setApiConversations] = useState8([]);
|
|
5591
5691
|
const [conversationsLoading, setConversationsLoading] = useState8(false);
|
|
5592
5692
|
const [conversationsError, setConversationsError] = useState8(null);
|
|
@@ -5603,6 +5703,7 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
5603
5703
|
"This Month": false,
|
|
5604
5704
|
"Older": false
|
|
5605
5705
|
});
|
|
5706
|
+
const [disabledContextSections, setDisabledContextSections] = useState8(/* @__PURE__ */ new Map());
|
|
5606
5707
|
const {
|
|
5607
5708
|
agents: agentProfiles,
|
|
5608
5709
|
isLoading: agentsLoading,
|
|
@@ -5746,13 +5847,8 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
5746
5847
|
fetchInProgressRef.current = true;
|
|
5747
5848
|
setConversationsLoading(true);
|
|
5748
5849
|
setConversationsError(null);
|
|
5749
|
-
console.log("projectId", projectId);
|
|
5750
|
-
console.log("customerId", customerId);
|
|
5751
|
-
console.log("apiKey", apiKey);
|
|
5752
5850
|
try {
|
|
5753
|
-
console.log("fetchConversations - customerId:", customerId);
|
|
5754
5851
|
const url2 = `https://api.llmasaservice.io/conversations?customer_id=${customerId}`;
|
|
5755
|
-
console.log("fetchConversations - URL:", url2);
|
|
5756
5852
|
const response = yield fetch(url2, {
|
|
5757
5853
|
signal,
|
|
5758
5854
|
headers: {
|
|
@@ -6136,8 +6232,21 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6136
6232
|
});
|
|
6137
6233
|
}
|
|
6138
6234
|
}, [pageContextSections, currentAgentId, agentIds, getAgent, localOverrides]);
|
|
6235
|
+
const currentDisabledSections = useMemo4(() => {
|
|
6236
|
+
return currentConversationId ? disabledContextSections.get(currentConversationId) || /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
|
|
6237
|
+
}, [currentConversationId, disabledContextSections]);
|
|
6238
|
+
const filteredContext = useMemo4(() => {
|
|
6239
|
+
const enabledSections = mergedContext.sections.filter(
|
|
6240
|
+
(section) => !currentDisabledSections.has(section.id)
|
|
6241
|
+
);
|
|
6242
|
+
const totalTokens = enabledSections.reduce((sum, s) => sum + (s.tokens || 0), 0);
|
|
6243
|
+
return {
|
|
6244
|
+
sections: enabledSections,
|
|
6245
|
+
totalTokens
|
|
6246
|
+
};
|
|
6247
|
+
}, [mergedContext.sections, currentDisabledSections]);
|
|
6139
6248
|
const chatPanelData = useMemo4(() => {
|
|
6140
|
-
const contextData =
|
|
6249
|
+
const contextData = filteredContext.sections.map((section) => ({
|
|
6141
6250
|
key: section.id,
|
|
6142
6251
|
data: JSON.stringify(section.data)
|
|
6143
6252
|
}));
|
|
@@ -6151,7 +6260,7 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6151
6260
|
}
|
|
6152
6261
|
}
|
|
6153
6262
|
return [...data, ...contextData];
|
|
6154
|
-
}, [data,
|
|
6263
|
+
}, [data, filteredContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
|
|
6155
6264
|
const handleAgentSwitch = useCallback4(
|
|
6156
6265
|
(newAgentId) => {
|
|
6157
6266
|
const oldAgentId = currentAgentId;
|
|
@@ -6282,6 +6391,21 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6282
6391
|
setSuggestedAgent(null);
|
|
6283
6392
|
setHandoffSource("agent");
|
|
6284
6393
|
}, []);
|
|
6394
|
+
const handleContextSectionToggle = useCallback4((sectionId, enabled) => {
|
|
6395
|
+
if (!currentConversationId) return;
|
|
6396
|
+
setDisabledContextSections((prev) => {
|
|
6397
|
+
const next = new Map(prev);
|
|
6398
|
+
const conversationDisabled = next.get(currentConversationId) || /* @__PURE__ */ new Set();
|
|
6399
|
+
const nextDisabled = new Set(conversationDisabled);
|
|
6400
|
+
if (enabled) {
|
|
6401
|
+
nextDisabled.delete(sectionId);
|
|
6402
|
+
} else {
|
|
6403
|
+
nextDisabled.add(sectionId);
|
|
6404
|
+
}
|
|
6405
|
+
next.set(currentConversationId, nextDisabled);
|
|
6406
|
+
return next;
|
|
6407
|
+
});
|
|
6408
|
+
}, [currentConversationId]);
|
|
6285
6409
|
const handleConversationCreated = useCallback4((tempId, realId) => {
|
|
6286
6410
|
console.log("Conversation created:", tempId, "->", realId);
|
|
6287
6411
|
setActiveConversations((prev) => {
|
|
@@ -6615,9 +6739,11 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6615
6739
|
handleAgentSwitch,
|
|
6616
6740
|
agentsLoading,
|
|
6617
6741
|
contextSections: mergedContext.sections,
|
|
6618
|
-
totalContextTokens:
|
|
6742
|
+
totalContextTokens: filteredContext.totalTokens,
|
|
6619
6743
|
maxContextTokens,
|
|
6620
6744
|
enableContextDetailView,
|
|
6745
|
+
disabledSectionIds: currentDisabledSections,
|
|
6746
|
+
onToggleSection: handleContextSectionToggle,
|
|
6621
6747
|
onConversationCreated: handleConversationCreated,
|
|
6622
6748
|
conversationInitialPrompt: activeConv.conversationInitialPrompt,
|
|
6623
6749
|
cssUrl,
|
package/package.json
CHANGED
package/src/AIAgentPanel.tsx
CHANGED
|
@@ -73,6 +73,9 @@ export interface AIAgentPanelProps {
|
|
|
73
73
|
// Agent Configuration - can be string IDs or full config objects
|
|
74
74
|
agents: (string | AgentConfig)[];
|
|
75
75
|
defaultAgent?: string;
|
|
76
|
+
|
|
77
|
+
// Controlled selection - when provided, external state drives which agent is active
|
|
78
|
+
selectedAgent?: string;
|
|
76
79
|
|
|
77
80
|
// Customer ID - REQUIRED for conversation history
|
|
78
81
|
customerId: string;
|
|
@@ -394,6 +397,8 @@ interface ChatPanelWrapperProps {
|
|
|
394
397
|
totalContextTokens: number;
|
|
395
398
|
maxContextTokens: number;
|
|
396
399
|
enableContextDetailView: boolean;
|
|
400
|
+
disabledSectionIds: Set<string>;
|
|
401
|
+
onToggleSection: (sectionId: string, enabled: boolean) => void;
|
|
397
402
|
// Conversation creation callback
|
|
398
403
|
onConversationCreated: (tempId: string, realId: string) => void;
|
|
399
404
|
// Per-conversation initial prompt
|
|
@@ -445,6 +450,8 @@ const ChatPanelWrapper = (({
|
|
|
445
450
|
totalContextTokens,
|
|
446
451
|
maxContextTokens,
|
|
447
452
|
enableContextDetailView,
|
|
453
|
+
disabledSectionIds,
|
|
454
|
+
onToggleSection,
|
|
448
455
|
onConversationCreated,
|
|
449
456
|
conversationInitialPrompt,
|
|
450
457
|
// New props from ChatPanel port
|
|
@@ -570,6 +577,8 @@ const ChatPanelWrapper = (({
|
|
|
570
577
|
totalContextTokens={totalContextTokens}
|
|
571
578
|
maxContextTokens={maxContextTokens}
|
|
572
579
|
enableContextDetailView={enableContextDetailView}
|
|
580
|
+
disabledSectionIds={disabledSectionIds}
|
|
581
|
+
onToggleSection={onToggleSection}
|
|
573
582
|
onConversationCreated={conversationCreatedCallback}
|
|
574
583
|
cssUrl={cssUrl}
|
|
575
584
|
markdownClass={markdownClass}
|
|
@@ -596,6 +605,7 @@ ChatPanelWrapper.displayName = 'ChatPanelWrapper';
|
|
|
596
605
|
const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
597
606
|
agents,
|
|
598
607
|
defaultAgent,
|
|
608
|
+
selectedAgent,
|
|
599
609
|
customerId,
|
|
600
610
|
apiKey,
|
|
601
611
|
context,
|
|
@@ -706,6 +716,36 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
706
716
|
defaultAgent || agentIds[0] || ''
|
|
707
717
|
);
|
|
708
718
|
|
|
719
|
+
// Sync with controlled selectedAgent prop when it changes
|
|
720
|
+
useEffect(() => {
|
|
721
|
+
// Only sync if selectedAgent is provided (controlled mode) and differs from current
|
|
722
|
+
if (selectedAgent && selectedAgent !== currentAgentId) {
|
|
723
|
+
const oldAgentId = currentAgentId;
|
|
724
|
+
setCurrentAgentId(selectedAgent);
|
|
725
|
+
|
|
726
|
+
// Fire onAgentSwitch callback for programmatic changes too
|
|
727
|
+
if (onAgentSwitch) {
|
|
728
|
+
onAgentSwitch(oldAgentId, selectedAgent);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Update the current conversation's agent ID to match
|
|
732
|
+
if (currentConversationIdRef.current) {
|
|
733
|
+
setActiveConversations(prev => {
|
|
734
|
+
const existing = prev.get(currentConversationIdRef.current!);
|
|
735
|
+
if (existing) {
|
|
736
|
+
const next = new Map(prev);
|
|
737
|
+
next.set(currentConversationIdRef.current!, {
|
|
738
|
+
...existing,
|
|
739
|
+
agentId: selectedAgent,
|
|
740
|
+
});
|
|
741
|
+
return next;
|
|
742
|
+
}
|
|
743
|
+
return prev;
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}, [selectedAgent]); // Note: intentionally excluding currentAgentId and onAgentSwitch to only trigger on prop change
|
|
748
|
+
|
|
709
749
|
// API-based conversation state
|
|
710
750
|
const [apiConversations, setApiConversations] = useState<APIConversationSummary[]>([]);
|
|
711
751
|
const [conversationsLoading, setConversationsLoading] = useState(false);
|
|
@@ -732,6 +772,9 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
732
772
|
'Older': false,
|
|
733
773
|
});
|
|
734
774
|
|
|
775
|
+
// Context section toggle state (per-conversation disabled sections)
|
|
776
|
+
const [disabledContextSections, setDisabledContextSections] = useState<Map<string, Set<string>>>(new Map());
|
|
777
|
+
|
|
735
778
|
// Agent registry hook
|
|
736
779
|
const {
|
|
737
780
|
agents: agentProfiles,
|
|
@@ -945,14 +988,9 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
945
988
|
|
|
946
989
|
setConversationsLoading(true);
|
|
947
990
|
setConversationsError(null);
|
|
948
|
-
console.log("projectId", projectId);
|
|
949
|
-
console.log("customerId", customerId);
|
|
950
|
-
console.log("apiKey", apiKey);
|
|
951
991
|
|
|
952
992
|
try {
|
|
953
|
-
console.log('fetchConversations - customerId:', customerId);
|
|
954
993
|
const url = `https://api.llmasaservice.io/conversations?customer_id=${customerId}`;
|
|
955
|
-
console.log('fetchConversations - URL:', url);
|
|
956
994
|
|
|
957
995
|
const response = await fetch(url, {
|
|
958
996
|
signal,
|
|
@@ -1509,9 +1547,30 @@ console.log("apiKey", apiKey);
|
|
|
1509
1547
|
}
|
|
1510
1548
|
}, [pageContextSections, currentAgentId, agentIds, getAgent, localOverrides]);
|
|
1511
1549
|
|
|
1550
|
+
// Get disabled sections for current conversation
|
|
1551
|
+
const currentDisabledSections = useMemo((): Set<string> => {
|
|
1552
|
+
return currentConversationId
|
|
1553
|
+
? disabledContextSections.get(currentConversationId) || new Set<string>()
|
|
1554
|
+
: new Set<string>();
|
|
1555
|
+
}, [currentConversationId, disabledContextSections]);
|
|
1556
|
+
|
|
1557
|
+
// Filtered context (only enabled sections)
|
|
1558
|
+
const filteredContext = useMemo(() => {
|
|
1559
|
+
const enabledSections = mergedContext.sections.filter(
|
|
1560
|
+
section => !currentDisabledSections.has(section.id)
|
|
1561
|
+
);
|
|
1562
|
+
const totalTokens = enabledSections.reduce((sum, s) => sum + (s.tokens || 0), 0);
|
|
1563
|
+
|
|
1564
|
+
return {
|
|
1565
|
+
sections: enabledSections,
|
|
1566
|
+
totalTokens,
|
|
1567
|
+
};
|
|
1568
|
+
}, [mergedContext.sections, currentDisabledSections]);
|
|
1569
|
+
|
|
1512
1570
|
// Build data array for ChatPanel
|
|
1513
1571
|
const chatPanelData = useMemo(() => {
|
|
1514
|
-
|
|
1572
|
+
// Use filtered sections (disabled sections are excluded)
|
|
1573
|
+
const contextData = filteredContext.sections.map((section) => ({
|
|
1515
1574
|
key: section.id,
|
|
1516
1575
|
data: JSON.stringify(section.data),
|
|
1517
1576
|
}));
|
|
@@ -1528,7 +1587,7 @@ console.log("apiKey", apiKey);
|
|
|
1528
1587
|
}
|
|
1529
1588
|
|
|
1530
1589
|
return [...data, ...contextData];
|
|
1531
|
-
}, [data,
|
|
1590
|
+
}, [data, filteredContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
|
|
1532
1591
|
|
|
1533
1592
|
// Handle agent switch - updates the agent for the current conversation without starting a new one
|
|
1534
1593
|
const handleAgentSwitch = useCallback(
|
|
@@ -1697,6 +1756,26 @@ console.log("apiKey", apiKey);
|
|
|
1697
1756
|
setHandoffSource('agent');
|
|
1698
1757
|
}, []);
|
|
1699
1758
|
|
|
1759
|
+
// Handle context section toggle for current conversation
|
|
1760
|
+
const handleContextSectionToggle = useCallback((sectionId: string, enabled: boolean) => {
|
|
1761
|
+
if (!currentConversationId) return;
|
|
1762
|
+
|
|
1763
|
+
setDisabledContextSections(prev => {
|
|
1764
|
+
const next = new Map(prev);
|
|
1765
|
+
const conversationDisabled = next.get(currentConversationId) || new Set();
|
|
1766
|
+
const nextDisabled = new Set(conversationDisabled);
|
|
1767
|
+
|
|
1768
|
+
if (enabled) {
|
|
1769
|
+
nextDisabled.delete(sectionId);
|
|
1770
|
+
} else {
|
|
1771
|
+
nextDisabled.add(sectionId);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
next.set(currentConversationId, nextDisabled);
|
|
1775
|
+
return next;
|
|
1776
|
+
});
|
|
1777
|
+
}, [currentConversationId]);
|
|
1778
|
+
|
|
1700
1779
|
// Handle conversation created - update temp ID to real ID from API
|
|
1701
1780
|
const handleConversationCreated = useCallback((tempId: string, realId: string) => {
|
|
1702
1781
|
console.log('Conversation created:', tempId, '->', realId);
|
|
@@ -2194,9 +2273,11 @@ console.log("apiKey", apiKey);
|
|
|
2194
2273
|
handleAgentSwitch={handleAgentSwitch}
|
|
2195
2274
|
agentsLoading={agentsLoading}
|
|
2196
2275
|
contextSections={mergedContext.sections}
|
|
2197
|
-
totalContextTokens={
|
|
2276
|
+
totalContextTokens={filteredContext.totalTokens}
|
|
2198
2277
|
maxContextTokens={maxContextTokens}
|
|
2199
2278
|
enableContextDetailView={enableContextDetailView}
|
|
2279
|
+
disabledSectionIds={currentDisabledSections}
|
|
2280
|
+
onToggleSection={handleContextSectionToggle}
|
|
2200
2281
|
onConversationCreated={handleConversationCreated}
|
|
2201
2282
|
conversationInitialPrompt={activeConv.conversationInitialPrompt}
|
|
2202
2283
|
cssUrl={cssUrl}
|
package/src/AIChatPanel.css
CHANGED
|
@@ -1575,6 +1575,88 @@
|
|
|
1575
1575
|
font-size: 10px;
|
|
1576
1576
|
}
|
|
1577
1577
|
|
|
1578
|
+
/* Detail Section Title Row (with toggle) */
|
|
1579
|
+
.ai-chat-context-popover__detail-section-title-row {
|
|
1580
|
+
display: flex;
|
|
1581
|
+
align-items: center;
|
|
1582
|
+
gap: 12px;
|
|
1583
|
+
flex: 1;
|
|
1584
|
+
min-width: 0;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
/* Disabled Section Styling */
|
|
1588
|
+
.ai-chat-context-popover__detail-section--disabled {
|
|
1589
|
+
opacity: 0.6;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
.ai-chat-context-popover__detail-section--disabled .ai-chat-context-popover__detail-section-title {
|
|
1593
|
+
text-decoration: line-through;
|
|
1594
|
+
opacity: 0.7;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
/* Context Toggle Switch */
|
|
1598
|
+
.ai-chat-context-toggle {
|
|
1599
|
+
position: relative;
|
|
1600
|
+
display: inline-flex;
|
|
1601
|
+
width: 36px;
|
|
1602
|
+
height: 20px;
|
|
1603
|
+
cursor: pointer;
|
|
1604
|
+
user-select: none;
|
|
1605
|
+
flex-shrink: 0;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
.ai-chat-context-toggle__input {
|
|
1609
|
+
opacity: 0;
|
|
1610
|
+
width: 0;
|
|
1611
|
+
height: 0;
|
|
1612
|
+
position: absolute;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
.ai-chat-context-toggle__slider {
|
|
1616
|
+
position: absolute;
|
|
1617
|
+
top: 0;
|
|
1618
|
+
left: 0;
|
|
1619
|
+
right: 0;
|
|
1620
|
+
bottom: 0;
|
|
1621
|
+
background-color: #cbd5e1;
|
|
1622
|
+
transition: background-color 0.2s ease;
|
|
1623
|
+
border-radius: 20px;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
.ai-chat-context-toggle__slider:before {
|
|
1627
|
+
position: absolute;
|
|
1628
|
+
content: "";
|
|
1629
|
+
height: 16px;
|
|
1630
|
+
width: 16px;
|
|
1631
|
+
left: 2px;
|
|
1632
|
+
bottom: 2px;
|
|
1633
|
+
background-color: white;
|
|
1634
|
+
transition: transform 0.2s ease;
|
|
1635
|
+
border-radius: 50%;
|
|
1636
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
.ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider {
|
|
1640
|
+
background-color: #3b82f6;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
.ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider:before {
|
|
1644
|
+
transform: translateX(16px);
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
.ai-chat-context-toggle:hover .ai-chat-context-toggle__slider {
|
|
1648
|
+
opacity: 0.9;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/* Dark theme toggle */
|
|
1652
|
+
.dark-theme .ai-chat-context-toggle__slider {
|
|
1653
|
+
background-color: #4b5563;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
.dark-theme .ai-chat-context-toggle__input:checked + .ai-chat-context-toggle__slider {
|
|
1657
|
+
background-color: #60a5fa;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1578
1660
|
/* Detail Content */
|
|
1579
1661
|
.ai-chat-context-popover__detail-content {
|
|
1580
1662
|
margin: 0;
|
package/src/AIChatPanel.tsx
CHANGED
|
@@ -88,6 +88,8 @@ export interface AIChatPanelProps {
|
|
|
88
88
|
totalContextTokens?: number;
|
|
89
89
|
maxContextTokens?: number;
|
|
90
90
|
enableContextDetailView?: boolean;
|
|
91
|
+
disabledSectionIds?: Set<string>;
|
|
92
|
+
onToggleSection?: (sectionId: string, enabled: boolean) => void;
|
|
91
93
|
|
|
92
94
|
// Callback when a new conversation is created via API
|
|
93
95
|
onConversationCreated?: (conversationId: string) => void;
|
|
@@ -295,6 +297,8 @@ interface ChatInputProps {
|
|
|
295
297
|
totalContextTokens?: number;
|
|
296
298
|
maxContextTokens?: number;
|
|
297
299
|
enableContextDetailView?: boolean;
|
|
300
|
+
disabledSectionIds?: Set<string>;
|
|
301
|
+
onToggleSection?: (sectionId: string, enabled: boolean) => void;
|
|
298
302
|
onContextViewerToggle?: () => void;
|
|
299
303
|
}
|
|
300
304
|
|
|
@@ -313,11 +317,14 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
313
317
|
totalContextTokens = 0,
|
|
314
318
|
maxContextTokens = 8000,
|
|
315
319
|
enableContextDetailView = false,
|
|
320
|
+
disabledSectionIds = new Set(),
|
|
321
|
+
onToggleSection,
|
|
316
322
|
}) => {
|
|
317
323
|
const [inputValue, setInputValue] = useState('');
|
|
318
324
|
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
319
325
|
const [contextViewerOpen, setContextViewerOpen] = useState(false);
|
|
320
326
|
const [contextViewMode, setContextViewMode] = useState<'summary' | 'detail'>('summary');
|
|
327
|
+
const [expandedSectionId, setExpandedSectionId] = useState<string | null>(null);
|
|
321
328
|
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
322
329
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
323
330
|
const contextPopoverRef = useRef<HTMLDivElement | null>(null);
|
|
@@ -363,6 +370,7 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
363
370
|
if (contextPopoverRef.current && !contextPopoverRef.current.contains(event.target as Node)) {
|
|
364
371
|
setContextViewerOpen(false);
|
|
365
372
|
setContextViewMode('summary');
|
|
373
|
+
setExpandedSectionId(null);
|
|
366
374
|
}
|
|
367
375
|
};
|
|
368
376
|
if (contextViewerOpen) {
|
|
@@ -466,6 +474,9 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
466
474
|
setContextViewerOpen(!contextViewerOpen);
|
|
467
475
|
if (!contextViewerOpen) {
|
|
468
476
|
setContextViewMode('summary');
|
|
477
|
+
setExpandedSectionId(null);
|
|
478
|
+
} else {
|
|
479
|
+
setExpandedSectionId(null);
|
|
469
480
|
}
|
|
470
481
|
}}
|
|
471
482
|
type="button"
|
|
@@ -488,7 +499,10 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
488
499
|
<span className="ai-chat-context-popover__title">Context</span>
|
|
489
500
|
<button
|
|
490
501
|
className="ai-chat-context-popover__close"
|
|
491
|
-
onClick={() =>
|
|
502
|
+
onClick={() => {
|
|
503
|
+
setContextViewerOpen(false);
|
|
504
|
+
setExpandedSectionId(null);
|
|
505
|
+
}}
|
|
492
506
|
type="button"
|
|
493
507
|
>
|
|
494
508
|
×
|
|
@@ -517,6 +531,7 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
517
531
|
className={`ai-chat-context-popover__section-item ${enableContextDetailView ? 'ai-chat-context-popover__section-item--clickable' : ''}`}
|
|
518
532
|
onClick={() => {
|
|
519
533
|
if (enableContextDetailView) {
|
|
534
|
+
setExpandedSectionId(section.id);
|
|
520
535
|
setContextViewMode('detail');
|
|
521
536
|
}
|
|
522
537
|
}}
|
|
@@ -532,7 +547,10 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
532
547
|
{enableContextDetailView && (
|
|
533
548
|
<button
|
|
534
549
|
className="ai-chat-context-popover__expand-btn"
|
|
535
|
-
onClick={() =>
|
|
550
|
+
onClick={() => {
|
|
551
|
+
setExpandedSectionId(null);
|
|
552
|
+
setContextViewMode('detail');
|
|
553
|
+
}}
|
|
536
554
|
type="button"
|
|
537
555
|
>
|
|
538
556
|
View details →
|
|
@@ -547,7 +565,10 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
547
565
|
<div className="ai-chat-context-popover__header">
|
|
548
566
|
<button
|
|
549
567
|
className="ai-chat-context-popover__back"
|
|
550
|
-
onClick={() =>
|
|
568
|
+
onClick={() => {
|
|
569
|
+
setContextViewMode('summary');
|
|
570
|
+
setExpandedSectionId(null);
|
|
571
|
+
}}
|
|
551
572
|
type="button"
|
|
552
573
|
>
|
|
553
574
|
← Back
|
|
@@ -555,7 +576,10 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
555
576
|
<span className="ai-chat-context-popover__title">Context Details</span>
|
|
556
577
|
<button
|
|
557
578
|
className="ai-chat-context-popover__close"
|
|
558
|
-
onClick={() =>
|
|
579
|
+
onClick={() => {
|
|
580
|
+
setContextViewerOpen(false);
|
|
581
|
+
setExpandedSectionId(null);
|
|
582
|
+
}}
|
|
559
583
|
type="button"
|
|
560
584
|
>
|
|
561
585
|
×
|
|
@@ -580,10 +604,35 @@ const ChatInput = React.memo<ChatInputProps>(({
|
|
|
580
604
|
<div className="ai-chat-context-popover__detail-sections">
|
|
581
605
|
{contextSections.map((section) => {
|
|
582
606
|
const format = detectFormat(section.data);
|
|
607
|
+
const isEnabled = !disabledSectionIds.has(section.id);
|
|
583
608
|
return (
|
|
584
|
-
<details
|
|
609
|
+
<details
|
|
610
|
+
key={section.id}
|
|
611
|
+
className={`ai-chat-context-popover__detail-section ${!isEnabled ? 'ai-chat-context-popover__detail-section--disabled' : ''}`}
|
|
612
|
+
open={expandedSectionId === section.id}
|
|
613
|
+
>
|
|
585
614
|
<summary className="ai-chat-context-popover__detail-section-header">
|
|
586
|
-
<
|
|
615
|
+
<div className="ai-chat-context-popover__detail-section-title-row">
|
|
616
|
+
<span className="ai-chat-context-popover__detail-section-title">{section.title}</span>
|
|
617
|
+
<label
|
|
618
|
+
className="ai-chat-context-toggle"
|
|
619
|
+
onClick={(e) => e.stopPropagation()}
|
|
620
|
+
title={isEnabled ? "Disable this context section" : "Enable this context section"}
|
|
621
|
+
>
|
|
622
|
+
<input
|
|
623
|
+
type="checkbox"
|
|
624
|
+
checked={isEnabled}
|
|
625
|
+
onChange={(e) => {
|
|
626
|
+
e.stopPropagation();
|
|
627
|
+
if (onToggleSection) {
|
|
628
|
+
onToggleSection(section.id, !isEnabled);
|
|
629
|
+
}
|
|
630
|
+
}}
|
|
631
|
+
className="ai-chat-context-toggle__input"
|
|
632
|
+
/>
|
|
633
|
+
<span className="ai-chat-context-toggle__slider"></span>
|
|
634
|
+
</label>
|
|
635
|
+
</div>
|
|
587
636
|
<span className="ai-chat-context-popover__detail-section-meta">
|
|
588
637
|
<code>{`{{${section.id}}}`}</code>
|
|
589
638
|
<span>~{section.tokens || Math.ceil(JSON.stringify(section.data).length / 4)}</span>
|
|
@@ -701,6 +750,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
701
750
|
totalContextTokens = 0,
|
|
702
751
|
maxContextTokens = 8000,
|
|
703
752
|
enableContextDetailView = false,
|
|
753
|
+
disabledSectionIds: propDisabledSectionIds,
|
|
754
|
+
onToggleSection: propOnToggleSection,
|
|
704
755
|
onConversationCreated,
|
|
705
756
|
// UI Customization Props
|
|
706
757
|
cssUrl,
|
|
@@ -770,6 +821,11 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
770
821
|
const [sessionApprovedTools, setSessionApprovedTools] = useState<string[]>([]);
|
|
771
822
|
const [alwaysApprovedTools, setAlwaysApprovedTools] = useState<string[]>([]);
|
|
772
823
|
|
|
824
|
+
// Context section toggle state (disabled sections)
|
|
825
|
+
// Use internal state only if prop is not provided
|
|
826
|
+
const [internalDisabledSectionIds, setInternalDisabledSectionIds] = useState<Set<string>>(new Set());
|
|
827
|
+
const disabledSectionIds = propDisabledSectionIds ?? internalDisabledSectionIds;
|
|
828
|
+
|
|
773
829
|
// Email capture mode effect - like ChatPanel
|
|
774
830
|
useEffect(() => {
|
|
775
831
|
setShowEmailPanel(customerEmailCaptureMode !== 'HIDE');
|
|
@@ -891,6 +947,24 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
891
947
|
};
|
|
892
948
|
}, []);
|
|
893
949
|
|
|
950
|
+
// Handle toggling context sections on/off
|
|
951
|
+
const handleToggleSection = useCallback((sectionId: string, enabled: boolean) => {
|
|
952
|
+
// Use prop callback if provided, otherwise use internal state
|
|
953
|
+
if (propOnToggleSection) {
|
|
954
|
+
propOnToggleSection(sectionId, enabled);
|
|
955
|
+
} else {
|
|
956
|
+
setInternalDisabledSectionIds(prev => {
|
|
957
|
+
const next = new Set(prev);
|
|
958
|
+
if (enabled) {
|
|
959
|
+
next.delete(sectionId);
|
|
960
|
+
} else {
|
|
961
|
+
next.add(sectionId);
|
|
962
|
+
}
|
|
963
|
+
return next;
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
}, [propOnToggleSection]);
|
|
967
|
+
|
|
894
968
|
// Ensure a conversation exists before sending the first message
|
|
895
969
|
// This creates a conversation on the server and returns the conversation ID
|
|
896
970
|
const ensureConversation = useCallback(() => {
|
|
@@ -2633,6 +2707,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
2633
2707
|
totalContextTokens={totalContextTokens}
|
|
2634
2708
|
maxContextTokens={maxContextTokens}
|
|
2635
2709
|
enableContextDetailView={enableContextDetailView}
|
|
2710
|
+
disabledSectionIds={disabledSectionIds}
|
|
2711
|
+
onToggleSection={handleToggleSection}
|
|
2636
2712
|
/>
|
|
2637
2713
|
|
|
2638
2714
|
{/* Footer */}
|