@hef2024/llmasaservice-ui 0.20.1 → 0.20.3

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.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,63 @@ var AIAgentPanel = React13.forwardRef(({
5587
5665
  const [currentAgentId, setCurrentAgentId] = useState8(
5588
5666
  defaultAgent || agentIds[0] || ""
5589
5667
  );
5668
+ const [pendingFollowOnPrompt, setPendingFollowOnPrompt] = useState8(null);
5669
+ const [agentSwitchSettled, setAgentSwitchSettled] = useState8(true);
5670
+ const lastProcessedFollowOnRef = useRef6("");
5671
+ useEffect9(() => {
5672
+ if (selectedAgent && selectedAgent !== currentAgentId) {
5673
+ const oldAgentId = currentAgentId;
5674
+ setAgentSwitchSettled(false);
5675
+ setCurrentAgentId(selectedAgent);
5676
+ if (onAgentSwitch) {
5677
+ onAgentSwitch(oldAgentId, selectedAgent);
5678
+ }
5679
+ if (currentConversationIdRef.current) {
5680
+ setActiveConversations((prev) => {
5681
+ const existing = prev.get(currentConversationIdRef.current);
5682
+ if (existing) {
5683
+ const next = new Map(prev);
5684
+ next.set(currentConversationIdRef.current, __spreadProps(__spreadValues({}, existing), {
5685
+ agentId: selectedAgent
5686
+ }));
5687
+ return next;
5688
+ }
5689
+ return prev;
5690
+ });
5691
+ }
5692
+ }
5693
+ }, [selectedAgent]);
5694
+ useEffect9(() => {
5695
+ if (!agentSwitchSettled && followOnPrompt && followOnPrompt !== "" && followOnPrompt !== lastProcessedFollowOnRef.current) {
5696
+ setPendingFollowOnPrompt(followOnPrompt);
5697
+ lastProcessedFollowOnRef.current = followOnPrompt;
5698
+ }
5699
+ }, [followOnPrompt, agentSwitchSettled]);
5700
+ useEffect9(() => {
5701
+ if (!agentSwitchSettled) {
5702
+ const timer = setTimeout(() => {
5703
+ setAgentSwitchSettled(true);
5704
+ }, 100);
5705
+ return () => clearTimeout(timer);
5706
+ }
5707
+ }, [agentSwitchSettled]);
5708
+ const effectiveFollowOnPrompt = useMemo4(() => {
5709
+ if (!agentSwitchSettled) {
5710
+ return "";
5711
+ }
5712
+ if (pendingFollowOnPrompt) {
5713
+ return pendingFollowOnPrompt;
5714
+ }
5715
+ return followOnPrompt;
5716
+ }, [followOnPrompt, pendingFollowOnPrompt, agentSwitchSettled]);
5717
+ useEffect9(() => {
5718
+ if (agentSwitchSettled && pendingFollowOnPrompt) {
5719
+ const timer = setTimeout(() => {
5720
+ setPendingFollowOnPrompt(null);
5721
+ }, 100);
5722
+ return () => clearTimeout(timer);
5723
+ }
5724
+ }, [agentSwitchSettled, pendingFollowOnPrompt]);
5590
5725
  const [apiConversations, setApiConversations] = useState8([]);
5591
5726
  const [conversationsLoading, setConversationsLoading] = useState8(false);
5592
5727
  const [conversationsError, setConversationsError] = useState8(null);
@@ -5603,6 +5738,7 @@ var AIAgentPanel = React13.forwardRef(({
5603
5738
  "This Month": false,
5604
5739
  "Older": false
5605
5740
  });
5741
+ const [disabledContextSections, setDisabledContextSections] = useState8(/* @__PURE__ */ new Map());
5606
5742
  const {
5607
5743
  agents: agentProfiles,
5608
5744
  isLoading: agentsLoading,
@@ -5746,13 +5882,8 @@ var AIAgentPanel = React13.forwardRef(({
5746
5882
  fetchInProgressRef.current = true;
5747
5883
  setConversationsLoading(true);
5748
5884
  setConversationsError(null);
5749
- console.log("projectId", projectId);
5750
- console.log("customerId", customerId);
5751
- console.log("apiKey", apiKey);
5752
5885
  try {
5753
- console.log("fetchConversations - customerId:", customerId);
5754
5886
  const url2 = `https://api.llmasaservice.io/conversations?customer_id=${customerId}`;
5755
- console.log("fetchConversations - URL:", url2);
5756
5887
  const response = yield fetch(url2, {
5757
5888
  signal,
5758
5889
  headers: {
@@ -6136,8 +6267,21 @@ var AIAgentPanel = React13.forwardRef(({
6136
6267
  });
6137
6268
  }
6138
6269
  }, [pageContextSections, currentAgentId, agentIds, getAgent, localOverrides]);
6270
+ const currentDisabledSections = useMemo4(() => {
6271
+ return currentConversationId ? disabledContextSections.get(currentConversationId) || /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
6272
+ }, [currentConversationId, disabledContextSections]);
6273
+ const filteredContext = useMemo4(() => {
6274
+ const enabledSections = mergedContext.sections.filter(
6275
+ (section) => !currentDisabledSections.has(section.id)
6276
+ );
6277
+ const totalTokens = enabledSections.reduce((sum, s) => sum + (s.tokens || 0), 0);
6278
+ return {
6279
+ sections: enabledSections,
6280
+ totalTokens
6281
+ };
6282
+ }, [mergedContext.sections, currentDisabledSections]);
6139
6283
  const chatPanelData = useMemo4(() => {
6140
- const contextData = mergedContext.sections.map((section) => ({
6284
+ const contextData = filteredContext.sections.map((section) => ({
6141
6285
  key: section.id,
6142
6286
  data: JSON.stringify(section.data)
6143
6287
  }));
@@ -6151,7 +6295,7 @@ var AIAgentPanel = React13.forwardRef(({
6151
6295
  }
6152
6296
  }
6153
6297
  return [...data, ...contextData];
6154
- }, [data, mergedContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
6298
+ }, [data, filteredContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
6155
6299
  const handleAgentSwitch = useCallback4(
6156
6300
  (newAgentId) => {
6157
6301
  const oldAgentId = currentAgentId;
@@ -6282,6 +6426,21 @@ var AIAgentPanel = React13.forwardRef(({
6282
6426
  setSuggestedAgent(null);
6283
6427
  setHandoffSource("agent");
6284
6428
  }, []);
6429
+ const handleContextSectionToggle = useCallback4((sectionId, enabled) => {
6430
+ if (!currentConversationId) return;
6431
+ setDisabledContextSections((prev) => {
6432
+ const next = new Map(prev);
6433
+ const conversationDisabled = next.get(currentConversationId) || /* @__PURE__ */ new Set();
6434
+ const nextDisabled = new Set(conversationDisabled);
6435
+ if (enabled) {
6436
+ nextDisabled.delete(sectionId);
6437
+ } else {
6438
+ nextDisabled.add(sectionId);
6439
+ }
6440
+ next.set(currentConversationId, nextDisabled);
6441
+ return next;
6442
+ });
6443
+ }, [currentConversationId]);
6285
6444
  const handleConversationCreated = useCallback4((tempId, realId) => {
6286
6445
  console.log("Conversation created:", tempId, "->", realId);
6287
6446
  setActiveConversations((prev) => {
@@ -6609,15 +6768,17 @@ var AIAgentPanel = React13.forwardRef(({
6609
6768
  initialMessage,
6610
6769
  hideInitialPrompt,
6611
6770
  followOnQuestions,
6612
- followOnPrompt,
6771
+ followOnPrompt: effectiveFollowOnPrompt,
6613
6772
  agentOptions,
6614
6773
  currentAgentId,
6615
6774
  handleAgentSwitch,
6616
6775
  agentsLoading,
6617
6776
  contextSections: mergedContext.sections,
6618
- totalContextTokens: mergedContext.totalTokens || 0,
6777
+ totalContextTokens: filteredContext.totalTokens,
6619
6778
  maxContextTokens,
6620
6779
  enableContextDetailView,
6780
+ disabledSectionIds: currentDisabledSections,
6781
+ onToggleSection: handleContextSectionToggle,
6621
6782
  onConversationCreated: handleConversationCreated,
6622
6783
  conversationInitialPrompt: activeConv.conversationInitialPrompt,
6623
6784
  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.3",
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,92 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
706
716
  defaultAgent || agentIds[0] || ''
707
717
  );
708
718
 
719
+ // Track pending follow-on prompt after agent switch (to handle timing issues)
720
+ const [pendingFollowOnPrompt, setPendingFollowOnPrompt] = useState<string | null>(null);
721
+ const [agentSwitchSettled, setAgentSwitchSettled] = useState(true);
722
+ const lastProcessedFollowOnRef = useRef<string>('');
723
+
724
+ // Sync with controlled selectedAgent prop when it changes
725
+ useEffect(() => {
726
+ // Only sync if selectedAgent is provided (controlled mode) and differs from current
727
+ if (selectedAgent && selectedAgent !== currentAgentId) {
728
+ const oldAgentId = currentAgentId;
729
+
730
+ // Mark that an agent switch is in progress (not yet settled)
731
+ setAgentSwitchSettled(false);
732
+
733
+ setCurrentAgentId(selectedAgent);
734
+
735
+ // Fire onAgentSwitch callback for programmatic changes too
736
+ if (onAgentSwitch) {
737
+ onAgentSwitch(oldAgentId, selectedAgent);
738
+ }
739
+
740
+ // Update the current conversation's agent ID to match
741
+ if (currentConversationIdRef.current) {
742
+ setActiveConversations(prev => {
743
+ const existing = prev.get(currentConversationIdRef.current!);
744
+ if (existing) {
745
+ const next = new Map(prev);
746
+ next.set(currentConversationIdRef.current!, {
747
+ ...existing,
748
+ agentId: selectedAgent,
749
+ });
750
+ return next;
751
+ }
752
+ return prev;
753
+ });
754
+ }
755
+ }
756
+ }, [selectedAgent]); // Note: intentionally excluding other deps to only trigger on prop change
757
+
758
+ // Queue followOnPrompt if it arrives during an agent switch
759
+ useEffect(() => {
760
+ if (!agentSwitchSettled && followOnPrompt && followOnPrompt !== '' && followOnPrompt !== lastProcessedFollowOnRef.current) {
761
+ // Agent switch in progress - queue the prompt
762
+ setPendingFollowOnPrompt(followOnPrompt);
763
+ lastProcessedFollowOnRef.current = followOnPrompt;
764
+ }
765
+ }, [followOnPrompt, agentSwitchSettled]);
766
+
767
+ // Mark agent switch as settled after a short delay (allows ChatPanelWrapper to re-render)
768
+ useEffect(() => {
769
+ if (!agentSwitchSettled) {
770
+ const timer = setTimeout(() => {
771
+ setAgentSwitchSettled(true);
772
+ }, 100); // Small delay to ensure ChatPanelWrapper has re-rendered with new agent
773
+
774
+ return () => clearTimeout(timer);
775
+ }
776
+ }, [agentSwitchSettled]);
777
+
778
+ // Compute effective follow-on prompt (handles timing with agent switch)
779
+ const effectiveFollowOnPrompt = useMemo(() => {
780
+ // If agent switch hasn't settled yet, don't send any prompt
781
+ if (!agentSwitchSettled) {
782
+ return '';
783
+ }
784
+
785
+ // If there's a pending prompt from agent switch, use it
786
+ if (pendingFollowOnPrompt) {
787
+ return pendingFollowOnPrompt;
788
+ }
789
+
790
+ // Otherwise use the prop directly
791
+ return followOnPrompt;
792
+ }, [followOnPrompt, pendingFollowOnPrompt, agentSwitchSettled]);
793
+
794
+ // Clear pending prompt after it's been passed down
795
+ useEffect(() => {
796
+ if (agentSwitchSettled && pendingFollowOnPrompt) {
797
+ // Clear after a tick to ensure it was processed
798
+ const timer = setTimeout(() => {
799
+ setPendingFollowOnPrompt(null);
800
+ }, 100);
801
+ return () => clearTimeout(timer);
802
+ }
803
+ }, [agentSwitchSettled, pendingFollowOnPrompt]);
804
+
709
805
  // API-based conversation state
710
806
  const [apiConversations, setApiConversations] = useState<APIConversationSummary[]>([]);
711
807
  const [conversationsLoading, setConversationsLoading] = useState(false);
@@ -732,6 +828,9 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
732
828
  'Older': false,
733
829
  });
734
830
 
831
+ // Context section toggle state (per-conversation disabled sections)
832
+ const [disabledContextSections, setDisabledContextSections] = useState<Map<string, Set<string>>>(new Map());
833
+
735
834
  // Agent registry hook
736
835
  const {
737
836
  agents: agentProfiles,
@@ -945,14 +1044,9 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
945
1044
 
946
1045
  setConversationsLoading(true);
947
1046
  setConversationsError(null);
948
- console.log("projectId", projectId);
949
- console.log("customerId", customerId);
950
- console.log("apiKey", apiKey);
951
1047
 
952
1048
  try {
953
- console.log('fetchConversations - customerId:', customerId);
954
1049
  const url = `https://api.llmasaservice.io/conversations?customer_id=${customerId}`;
955
- console.log('fetchConversations - URL:', url);
956
1050
 
957
1051
  const response = await fetch(url, {
958
1052
  signal,
@@ -1509,9 +1603,30 @@ console.log("apiKey", apiKey);
1509
1603
  }
1510
1604
  }, [pageContextSections, currentAgentId, agentIds, getAgent, localOverrides]);
1511
1605
 
1606
+ // Get disabled sections for current conversation
1607
+ const currentDisabledSections = useMemo((): Set<string> => {
1608
+ return currentConversationId
1609
+ ? disabledContextSections.get(currentConversationId) || new Set<string>()
1610
+ : new Set<string>();
1611
+ }, [currentConversationId, disabledContextSections]);
1612
+
1613
+ // Filtered context (only enabled sections)
1614
+ const filteredContext = useMemo(() => {
1615
+ const enabledSections = mergedContext.sections.filter(
1616
+ section => !currentDisabledSections.has(section.id)
1617
+ );
1618
+ const totalTokens = enabledSections.reduce((sum, s) => sum + (s.tokens || 0), 0);
1619
+
1620
+ return {
1621
+ sections: enabledSections,
1622
+ totalTokens,
1623
+ };
1624
+ }, [mergedContext.sections, currentDisabledSections]);
1625
+
1512
1626
  // Build data array for ChatPanel
1513
1627
  const chatPanelData = useMemo(() => {
1514
- const contextData = mergedContext.sections.map((section) => ({
1628
+ // Use filtered sections (disabled sections are excluded)
1629
+ const contextData = filteredContext.sections.map((section) => ({
1515
1630
  key: section.id,
1516
1631
  data: JSON.stringify(section.data),
1517
1632
  }));
@@ -1528,7 +1643,7 @@ console.log("apiKey", apiKey);
1528
1643
  }
1529
1644
 
1530
1645
  return [...data, ...contextData];
1531
- }, [data, mergedContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
1646
+ }, [data, filteredContext.sections, buildAgentAwarenessInstructions, currentAgentId, enableAgentSuggestions]);
1532
1647
 
1533
1648
  // Handle agent switch - updates the agent for the current conversation without starting a new one
1534
1649
  const handleAgentSwitch = useCallback(
@@ -1697,6 +1812,26 @@ console.log("apiKey", apiKey);
1697
1812
  setHandoffSource('agent');
1698
1813
  }, []);
1699
1814
 
1815
+ // Handle context section toggle for current conversation
1816
+ const handleContextSectionToggle = useCallback((sectionId: string, enabled: boolean) => {
1817
+ if (!currentConversationId) return;
1818
+
1819
+ setDisabledContextSections(prev => {
1820
+ const next = new Map(prev);
1821
+ const conversationDisabled = next.get(currentConversationId) || new Set();
1822
+ const nextDisabled = new Set(conversationDisabled);
1823
+
1824
+ if (enabled) {
1825
+ nextDisabled.delete(sectionId);
1826
+ } else {
1827
+ nextDisabled.add(sectionId);
1828
+ }
1829
+
1830
+ next.set(currentConversationId, nextDisabled);
1831
+ return next;
1832
+ });
1833
+ }, [currentConversationId]);
1834
+
1700
1835
  // Handle conversation created - update temp ID to real ID from API
1701
1836
  const handleConversationCreated = useCallback((tempId: string, realId: string) => {
1702
1837
  console.log('Conversation created:', tempId, '->', realId);
@@ -2188,15 +2323,17 @@ console.log("apiKey", apiKey);
2188
2323
  initialMessage={initialMessage}
2189
2324
  hideInitialPrompt={hideInitialPrompt}
2190
2325
  followOnQuestions={followOnQuestions}
2191
- followOnPrompt={followOnPrompt}
2326
+ followOnPrompt={effectiveFollowOnPrompt}
2192
2327
  agentOptions={agentOptions}
2193
2328
  currentAgentId={currentAgentId}
2194
2329
  handleAgentSwitch={handleAgentSwitch}
2195
2330
  agentsLoading={agentsLoading}
2196
2331
  contextSections={mergedContext.sections}
2197
- totalContextTokens={mergedContext.totalTokens || 0}
2332
+ totalContextTokens={filteredContext.totalTokens}
2198
2333
  maxContextTokens={maxContextTokens}
2199
2334
  enableContextDetailView={enableContextDetailView}
2335
+ disabledSectionIds={currentDisabledSections}
2336
+ onToggleSection={handleContextSectionToggle}
2200
2337
  onConversationCreated={handleConversationCreated}
2201
2338
  conversationInitialPrompt={activeConv.conversationInitialPrompt}
2202
2339
  cssUrl={cssUrl}