@hef2024/llmasaservice-ui 0.22.1 → 0.22.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.js CHANGED
@@ -3894,6 +3894,7 @@ var AIChatPanel = ({
3894
3894
  const lastScrollTopRef = (0, import_react12.useRef)(0);
3895
3895
  const scrollRAFRef = (0, import_react12.useRef)(null);
3896
3896
  const lastScrollTimeRef = (0, import_react12.useRef)(0);
3897
+ const prevResponseLengthRef = (0, import_react12.useRef)(0);
3897
3898
  const prevIdleRef = (0, import_react12.useRef)(true);
3898
3899
  const hasNotifiedCompletionRef = (0, import_react12.useRef)(true);
3899
3900
  const latestHistoryRef = (0, import_react12.useRef)(initialHistory);
@@ -4368,6 +4369,7 @@ var AIChatPanel = ({
4368
4369
  setCurrentThinkingIndex(0);
4369
4370
  setError(null);
4370
4371
  setUserHasScrolled(false);
4372
+ prevResponseLengthRef.current = 0;
4371
4373
  setResponse("");
4372
4374
  if (!idle) {
4373
4375
  stop(lastController);
@@ -4568,11 +4570,24 @@ var AIChatPanel = ({
4568
4570
  }
4569
4571
  if (!isNowIdle && hasNotifiedCompletionRef.current) {
4570
4572
  hasNotifiedCompletionRef.current = false;
4573
+ prevResponseLengthRef.current = 0;
4571
4574
  }
4572
4575
  }, [idle]);
4573
4576
  (0, import_react12.useEffect)(() => {
4577
+ const currentResponseLength = response.length;
4578
+ const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
4579
+ console.log("AIChatPanel - Auto-scroll effect:", {
4580
+ idle,
4581
+ currentResponseLength,
4582
+ prevLength: prevResponseLengthRef.current,
4583
+ responseGotLonger,
4584
+ userHasScrolled,
4585
+ scrollToEnd
4586
+ });
4587
+ prevResponseLengthRef.current = currentResponseLength;
4574
4588
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4575
- if (!idle && shouldAutoScroll && response) {
4589
+ if (!idle && shouldAutoScroll && response && responseGotLonger) {
4590
+ console.log("AIChatPanel - Calling scrollToBottom");
4576
4591
  scrollToBottom(false);
4577
4592
  }
4578
4593
  }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
@@ -6267,12 +6282,16 @@ var AIAgentPanel = import_react14.default.forwardRef(({
6267
6282
  }, [context, sharedContextSections, pageContextSections, contextDataSources]);
6268
6283
  (0, import_react14.useEffect)(() => {
6269
6284
  const contextString = JSON.stringify(mergedContext.sections.map((s) => ({ id: s.id, data: s.data })));
6285
+ console.log("AIAgentPanel - Context effect running, sections:", mergedContext.sections.length);
6270
6286
  if (prevContextRef.current === null) {
6287
+ console.log("AIAgentPanel - First render, initializing context ref");
6271
6288
  prevContextRef.current = contextString;
6272
6289
  return;
6273
6290
  }
6274
6291
  if (prevContextRef.current !== contextString) {
6275
6292
  console.log("AIAgentPanel - Context changed, showing notification");
6293
+ console.log("AIAgentPanel - Old context:", prevContextRef.current.substring(0, 100));
6294
+ console.log("AIAgentPanel - New context:", contextString.substring(0, 100));
6276
6295
  prevContextRef.current = contextString;
6277
6296
  if (contextNotificationTimeoutRef.current) {
6278
6297
  clearTimeout(contextNotificationTimeoutRef.current);
@@ -6283,8 +6302,10 @@ var AIAgentPanel = import_react14.default.forwardRef(({
6283
6302
  setShowContextNotification(false);
6284
6303
  contextNotificationTimeoutRef.current = null;
6285
6304
  }, 3e3);
6305
+ } else {
6306
+ console.log("AIAgentPanel - Context unchanged");
6286
6307
  }
6287
- }, [mergedContext.sections]);
6308
+ }, [mergedContext]);
6288
6309
  (0, import_react14.useEffect)(() => {
6289
6310
  return () => {
6290
6311
  if (contextNotificationTimeoutRef.current) {
package/dist/index.mjs CHANGED
@@ -3861,6 +3861,7 @@ var AIChatPanel = ({
3861
3861
  const lastScrollTopRef = useRef5(0);
3862
3862
  const scrollRAFRef = useRef5(null);
3863
3863
  const lastScrollTimeRef = useRef5(0);
3864
+ const prevResponseLengthRef = useRef5(0);
3864
3865
  const prevIdleRef = useRef5(true);
3865
3866
  const hasNotifiedCompletionRef = useRef5(true);
3866
3867
  const latestHistoryRef = useRef5(initialHistory);
@@ -4335,6 +4336,7 @@ var AIChatPanel = ({
4335
4336
  setCurrentThinkingIndex(0);
4336
4337
  setError(null);
4337
4338
  setUserHasScrolled(false);
4339
+ prevResponseLengthRef.current = 0;
4338
4340
  setResponse("");
4339
4341
  if (!idle) {
4340
4342
  stop(lastController);
@@ -4535,11 +4537,24 @@ var AIChatPanel = ({
4535
4537
  }
4536
4538
  if (!isNowIdle && hasNotifiedCompletionRef.current) {
4537
4539
  hasNotifiedCompletionRef.current = false;
4540
+ prevResponseLengthRef.current = 0;
4538
4541
  }
4539
4542
  }, [idle]);
4540
4543
  useEffect7(() => {
4544
+ const currentResponseLength = response.length;
4545
+ const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
4546
+ console.log("AIChatPanel - Auto-scroll effect:", {
4547
+ idle,
4548
+ currentResponseLength,
4549
+ prevLength: prevResponseLengthRef.current,
4550
+ responseGotLonger,
4551
+ userHasScrolled,
4552
+ scrollToEnd
4553
+ });
4554
+ prevResponseLengthRef.current = currentResponseLength;
4541
4555
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
4542
- if (!idle && shouldAutoScroll && response) {
4556
+ if (!idle && shouldAutoScroll && response && responseGotLonger) {
4557
+ console.log("AIChatPanel - Calling scrollToBottom");
4543
4558
  scrollToBottom(false);
4544
4559
  }
4545
4560
  }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
@@ -6234,12 +6249,16 @@ var AIAgentPanel = React13.forwardRef(({
6234
6249
  }, [context, sharedContextSections, pageContextSections, contextDataSources]);
6235
6250
  useEffect9(() => {
6236
6251
  const contextString = JSON.stringify(mergedContext.sections.map((s) => ({ id: s.id, data: s.data })));
6252
+ console.log("AIAgentPanel - Context effect running, sections:", mergedContext.sections.length);
6237
6253
  if (prevContextRef.current === null) {
6254
+ console.log("AIAgentPanel - First render, initializing context ref");
6238
6255
  prevContextRef.current = contextString;
6239
6256
  return;
6240
6257
  }
6241
6258
  if (prevContextRef.current !== contextString) {
6242
6259
  console.log("AIAgentPanel - Context changed, showing notification");
6260
+ console.log("AIAgentPanel - Old context:", prevContextRef.current.substring(0, 100));
6261
+ console.log("AIAgentPanel - New context:", contextString.substring(0, 100));
6243
6262
  prevContextRef.current = contextString;
6244
6263
  if (contextNotificationTimeoutRef.current) {
6245
6264
  clearTimeout(contextNotificationTimeoutRef.current);
@@ -6250,8 +6269,10 @@ var AIAgentPanel = React13.forwardRef(({
6250
6269
  setShowContextNotification(false);
6251
6270
  contextNotificationTimeoutRef.current = null;
6252
6271
  }, 3e3);
6272
+ } else {
6273
+ console.log("AIAgentPanel - Context unchanged");
6253
6274
  }
6254
- }, [mergedContext.sections]);
6275
+ }, [mergedContext]);
6255
6276
  useEffect9(() => {
6256
6277
  return () => {
6257
6278
  if (contextNotificationTimeoutRef.current) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hef2024/llmasaservice-ui",
3
- "version": "0.22.1",
3
+ "version": "0.22.3",
4
4
  "description": "Prebuilt UI components for LLMAsAService.io",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1534,8 +1534,11 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
1534
1534
  // Create a stable string representation of the context for comparison
1535
1535
  const contextString = JSON.stringify(mergedContext.sections.map(s => ({ id: s.id, data: s.data })));
1536
1536
 
1537
+ console.log('AIAgentPanel - Context effect running, sections:', mergedContext.sections.length);
1538
+
1537
1539
  // Skip on first render
1538
1540
  if (prevContextRef.current === null) {
1541
+ console.log('AIAgentPanel - First render, initializing context ref');
1539
1542
  prevContextRef.current = contextString;
1540
1543
  return;
1541
1544
  }
@@ -1543,6 +1546,8 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
1543
1546
  // Check if context actually changed
1544
1547
  if (prevContextRef.current !== contextString) {
1545
1548
  console.log('AIAgentPanel - Context changed, showing notification');
1549
+ console.log('AIAgentPanel - Old context:', prevContextRef.current.substring(0, 100));
1550
+ console.log('AIAgentPanel - New context:', contextString.substring(0, 100));
1546
1551
  prevContextRef.current = contextString;
1547
1552
 
1548
1553
  // Clear any existing timeout before setting a new one
@@ -1559,11 +1564,13 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
1559
1564
  setShowContextNotification(false);
1560
1565
  contextNotificationTimeoutRef.current = null;
1561
1566
  }, 3000);
1567
+ } else {
1568
+ console.log('AIAgentPanel - Context unchanged');
1562
1569
  }
1563
1570
 
1564
1571
  // Note: No cleanup on every re-render - only clear timeout when context changes
1565
1572
  // This prevents race conditions when switching rapidly
1566
- }, [mergedContext.sections]);
1573
+ }, [mergedContext]);
1567
1574
 
1568
1575
  // Separate cleanup effect for unmount only
1569
1576
  useEffect(() => {
@@ -846,6 +846,7 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
846
846
  const lastScrollTopRef = useRef<number>(0);
847
847
  const scrollRAFRef = useRef<number | null>(null);
848
848
  const lastScrollTimeRef = useRef<number>(0);
849
+ const prevResponseLengthRef = useRef<number>(0);
849
850
 
850
851
  // === NEW: Clean history management refs ===
851
852
  // Track previous idle state to detect transitions (false→true = completion)
@@ -1521,6 +1522,7 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1521
1522
 
1522
1523
  // Reset scroll tracking for new message - enable auto-scroll
1523
1524
  setUserHasScrolled(false);
1525
+ prevResponseLengthRef.current = 0;
1524
1526
 
1525
1527
  // IMPORTANT: Clear the response BEFORE setting new lastKey
1526
1528
  // This prevents the old response from being written to the new history entry
@@ -1814,21 +1816,41 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
1814
1816
  // Reset notification flag when starting a new stream
1815
1817
  if (!isNowIdle && hasNotifiedCompletionRef.current) {
1816
1818
  hasNotifiedCompletionRef.current = false;
1819
+ // Reset response length tracking for new stream
1820
+ prevResponseLengthRef.current = 0;
1817
1821
  }
1818
1822
  }, [idle]); // ONLY depends on idle - no history, no callbacks in deps
1819
-
1823
+
1820
1824
  // Auto-scroll to bottom - only while streaming and user hasn't manually scrolled
1821
1825
  useEffect(() => {
1822
1826
  // Only auto-scroll if:
1823
1827
  // 1. We're actively streaming (!idle)
1824
1828
  // 2. User hasn't manually scrolled up during this response (or scrollToEnd prop is true)
1825
1829
  // 3. We have content to show (response exists)
1830
+ // 4. The response actually got longer (not just a re-render from layout change)
1831
+ const currentResponseLength = response.length;
1832
+ const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
1833
+
1834
+ console.log('AIChatPanel - Auto-scroll effect:', {
1835
+ idle,
1836
+ currentResponseLength,
1837
+ prevLength: prevResponseLengthRef.current,
1838
+ responseGotLonger,
1839
+ userHasScrolled,
1840
+ scrollToEnd,
1841
+ });
1842
+
1843
+ prevResponseLengthRef.current = currentResponseLength;
1844
+
1845
+ // CRITICAL: Only auto-scroll during active streaming when response grows
1846
+ // This prevents scroll on layout changes (toast, context updates, etc.)
1826
1847
  const shouldAutoScroll = scrollToEnd || !userHasScrolled;
1827
- if (!idle && shouldAutoScroll && response) {
1848
+ if (!idle && shouldAutoScroll && response && responseGotLonger) {
1849
+ console.log('AIChatPanel - Calling scrollToBottom');
1828
1850
  // Use non-forced scroll - will only scroll if near bottom
1829
1851
  scrollToBottom(false);
1830
1852
  }
1831
- }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]); // Removed history dependency
1853
+ }, [response, scrollToBottom, idle, userHasScrolled, scrollToEnd]);
1832
1854
 
1833
1855
  // Ref to track idle state for scroll handler (avoids stale closure)
1834
1856
  const idleRef = useRef(idle);