@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 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: () => setContextViewerOpen(false),
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: () => setContextViewMode("detail"),
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: () => setContextViewMode("summary"),
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: () => setContextViewerOpen(false),
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
- return /* @__PURE__ */ import_react12.default.createElement("details", { key: section.id, className: "ai-chat-context-popover__detail-section", open: true }, /* @__PURE__ */ import_react12.default.createElement("summary", { className: "ai-chat-context-popover__detail-section-header" }, /* @__PURE__ */ import_react12.default.createElement("span", { className: "ai-chat-context-popover__detail-section-title" }, section.title), /* @__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)))), /* @__PURE__ */ import_react12.default.createElement("pre", { className: "ai-chat-context-popover__detail-content" }, /* @__PURE__ */ import_react12.default.createElement("code", null, formatContent(section.data, format))));
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 = mergedContext.sections.map((section) => ({
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, mergedContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
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: mergedContext.totalTokens || 0,
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: () => setContextViewerOpen(false),
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: () => setContextViewMode("detail"),
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: () => setContextViewMode("summary"),
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: () => setContextViewerOpen(false),
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
- return /* @__PURE__ */ React12.createElement("details", { key: section.id, className: "ai-chat-context-popover__detail-section", open: true }, /* @__PURE__ */ React12.createElement("summary", { className: "ai-chat-context-popover__detail-section-header" }, /* @__PURE__ */ React12.createElement("span", { className: "ai-chat-context-popover__detail-section-title" }, section.title), /* @__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)))), /* @__PURE__ */ React12.createElement("pre", { className: "ai-chat-context-popover__detail-content" }, /* @__PURE__ */ React12.createElement("code", null, formatContent(section.data, format))));
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 = mergedContext.sections.map((section) => ({
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, mergedContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
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: mergedContext.totalTokens || 0,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hef2024/llmasaservice-ui",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "description": "Prebuilt UI components for LLMAsAService.io",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -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
- const contextData = mergedContext.sections.map((section) => ({
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, mergedContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
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={mergedContext.totalTokens || 0}
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}
@@ -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;
@@ -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={() => setContextViewerOpen(false)}
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={() => setContextViewMode('detail')}
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={() => setContextViewMode('summary')}
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={() => setContextViewerOpen(false)}
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 key={section.id} className="ai-chat-context-popover__detail-section" open>
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
- <span className="ai-chat-context-popover__detail-section-title">{section.title}</span>
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 */}
@@ -64,3 +64,6 @@ const ToolInfoModal: React.FC<ToolInfoModalProps> = ({
64
64
 
65
65
  export default ToolInfoModal;
66
66
 
67
+
68
+
69
+
@@ -106,7 +106,6 @@ export function useAgentRegistry(
106
106
 
107
107
  const data = await response.json();
108
108
  const agentData = Array.isArray(data) ? data[0] : data;
109
-
110
109
 
111
110
  if (!agentData) {
112
111
  throw new Error(`No data returned for agent ${agentId}`);