@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 +23 -2
- package/dist/index.mjs +23 -2
- package/package.json +1 -1
- package/src/AIAgentPanel.tsx +8 -1
- package/src/AIChatPanel.tsx +25 -3
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
|
|
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
|
|
6275
|
+
}, [mergedContext]);
|
|
6255
6276
|
useEffect9(() => {
|
|
6256
6277
|
return () => {
|
|
6257
6278
|
if (contextNotificationTimeoutRef.current) {
|
package/package.json
CHANGED
package/src/AIAgentPanel.tsx
CHANGED
|
@@ -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
|
|
1573
|
+
}, [mergedContext]);
|
|
1567
1574
|
|
|
1568
1575
|
// Separate cleanup effect for unmount only
|
|
1569
1576
|
useEffect(() => {
|
package/src/AIChatPanel.tsx
CHANGED
|
@@ -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]);
|
|
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);
|