@hef2024/llmasaservice-ui 0.22.8 → 0.22.10
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/CONTROLLED-COLLAPSE-IMPLEMENTATION.md +2 -0
- package/dist/index.css +51 -47
- package/dist/index.js +2 -73
- package/dist/index.mjs +2 -73
- package/docs/CONTROLLED-COLLAPSE-QUICK-START.md +2 -0
- package/docs/CONTROLLED-COLLAPSE-STATE.md +2 -0
- package/package.json +1 -1
- package/src/AIAgentPanel.css +52 -47
- package/src/AIAgentPanel.tsx +0 -48
- package/src/AIChatPanel.tsx +0 -37
|
@@ -272,3 +272,5 @@ For questions or issues:
|
|
|
272
272
|
|
|
273
273
|
The controlled collapse state feature is now fully implemented, documented, and tested. It follows React best practices, maintains backward compatibility, and provides a flexible solution for persisting panel state across page navigations.
|
|
274
274
|
|
|
275
|
+
|
|
276
|
+
|
package/dist/index.css
CHANGED
|
@@ -997,12 +997,12 @@ button[data-pending=true]::after {
|
|
|
997
997
|
--ai-panel-collapsed-width: 48px;
|
|
998
998
|
--ai-panel-border-radius: 0;
|
|
999
999
|
--ai-panel-transition: 0.2s ease;
|
|
1000
|
-
--ai-sidebar-bg: #
|
|
1000
|
+
--ai-sidebar-bg: #ffffff;
|
|
1001
1001
|
--ai-sidebar-border: #e5e7eb;
|
|
1002
|
-
--ai-sidebar-text: #
|
|
1002
|
+
--ai-sidebar-text: #111827;
|
|
1003
1003
|
--ai-sidebar-text-muted: #6b7280;
|
|
1004
|
-
--ai-sidebar-hover: #
|
|
1005
|
-
--ai-sidebar-active: #
|
|
1004
|
+
--ai-sidebar-hover: #f9fafb;
|
|
1005
|
+
--ai-sidebar-active: #f3f4f6;
|
|
1006
1006
|
--ai-header-bg: #ffffff;
|
|
1007
1007
|
--ai-header-border: #e5e7eb;
|
|
1008
1008
|
--ai-header-height: 52px;
|
|
@@ -1011,13 +1011,13 @@ button[data-pending=true]::after {
|
|
|
1011
1011
|
--ai-agent-selector-bg: #ffffff;
|
|
1012
1012
|
--ai-agent-selector-border: #e5e7eb;
|
|
1013
1013
|
--ai-conversation-bg: transparent;
|
|
1014
|
-
--ai-conversation-hover: rgba(0, 0, 0, 0.
|
|
1015
|
-
--ai-conversation-active: rgba(0, 0, 0, 0.
|
|
1014
|
+
--ai-conversation-hover: rgba(0, 0, 0, 0.03);
|
|
1015
|
+
--ai-conversation-active: rgba(0, 0, 0, 0.05);
|
|
1016
1016
|
--ai-conversation-title-color: #1f2937;
|
|
1017
1017
|
--ai-conversation-preview-color: #6b7280;
|
|
1018
1018
|
--ai-conversation-meta-color: #9ca3af;
|
|
1019
|
-
--ai-group-label-color: #
|
|
1020
|
-
--ai-group-label-size: 0.
|
|
1019
|
+
--ai-group-label-color: #6b7280;
|
|
1020
|
+
--ai-group-label-size: 0.6875rem;
|
|
1021
1021
|
--ai-button-primary-bg: #3b82f6;
|
|
1022
1022
|
--ai-button-primary-text: #ffffff;
|
|
1023
1023
|
--ai-button-primary-hover: #2563eb;
|
|
@@ -1025,18 +1025,18 @@ button[data-pending=true]::after {
|
|
|
1025
1025
|
--ai-button-secondary-text: #374151;
|
|
1026
1026
|
--ai-button-secondary-border: #d1d5db;
|
|
1027
1027
|
--ai-button-secondary-hover: #e5e7eb;
|
|
1028
|
-
--ai-button-ghost-hover:
|
|
1028
|
+
--ai-button-ghost-hover: #f3f4f6;
|
|
1029
1029
|
--ai-button-destructive-bg: #ef4444;
|
|
1030
1030
|
--ai-button-destructive-text: #ffffff;
|
|
1031
1031
|
--ai-button-destructive-hover: #dc2626;
|
|
1032
|
-
--ai-button-radius:
|
|
1032
|
+
--ai-button-radius: 4px;
|
|
1033
1033
|
--ai-input-bg: #ffffff;
|
|
1034
1034
|
--ai-input-border: #d1d5db;
|
|
1035
1035
|
--ai-input-text: #1f2937;
|
|
1036
1036
|
--ai-input-placeholder: #9ca3af;
|
|
1037
1037
|
--ai-input-focus-border: #3b82f6;
|
|
1038
1038
|
--ai-input-focus-ring: rgba(59, 130, 246, 0.2);
|
|
1039
|
-
--ai-input-radius:
|
|
1039
|
+
--ai-input-radius: 4px;
|
|
1040
1040
|
--ai-select-bg: #ffffff;
|
|
1041
1041
|
--ai-select-border: #d1d5db;
|
|
1042
1042
|
--ai-select-text: #1f2937;
|
|
@@ -1067,21 +1067,21 @@ button[data-pending=true]::after {
|
|
|
1067
1067
|
--ai-chat-bg: #ffffff;
|
|
1068
1068
|
}
|
|
1069
1069
|
.dark-theme {
|
|
1070
|
-
--ai-sidebar-bg: #
|
|
1071
|
-
--ai-sidebar-border: #
|
|
1070
|
+
--ai-sidebar-bg: #111827;
|
|
1071
|
+
--ai-sidebar-border: #1f2937;
|
|
1072
1072
|
--ai-sidebar-text: #f3f4f6;
|
|
1073
1073
|
--ai-sidebar-text-muted: #9ca3af;
|
|
1074
|
-
--ai-sidebar-hover: #
|
|
1075
|
-
--ai-sidebar-active: #
|
|
1076
|
-
--ai-header-bg: #
|
|
1077
|
-
--ai-header-border: #
|
|
1074
|
+
--ai-sidebar-hover: #1f2937;
|
|
1075
|
+
--ai-sidebar-active: #374151;
|
|
1076
|
+
--ai-header-bg: #0d1117;
|
|
1077
|
+
--ai-header-border: #1f2937;
|
|
1078
1078
|
--ai-agent-badge-bg: #1e3a5f;
|
|
1079
1079
|
--ai-agent-badge-text: #60a5fa;
|
|
1080
1080
|
--ai-agent-selector-bg: #1f2937;
|
|
1081
1081
|
--ai-agent-selector-border: #374151;
|
|
1082
|
-
--ai-conversation-hover: rgba(255, 255, 255, 0.
|
|
1082
|
+
--ai-conversation-hover: rgba(255, 255, 255, 0.05);
|
|
1083
1083
|
--ai-conversation-active: rgba(255, 255, 255, 0.08);
|
|
1084
|
-
--ai-conversation-title-color: #
|
|
1084
|
+
--ai-conversation-title-color: #e5e7eb;
|
|
1085
1085
|
--ai-conversation-preview-color: #9ca3af;
|
|
1086
1086
|
--ai-conversation-meta-color: #6b7280;
|
|
1087
1087
|
--ai-group-label-color: #6b7280;
|
|
@@ -1092,7 +1092,7 @@ button[data-pending=true]::after {
|
|
|
1092
1092
|
--ai-button-secondary-text: #f3f4f6;
|
|
1093
1093
|
--ai-button-secondary-border: #4b5563;
|
|
1094
1094
|
--ai-button-secondary-hover: #4b5563;
|
|
1095
|
-
--ai-button-ghost-hover:
|
|
1095
|
+
--ai-button-ghost-hover: #1f2937;
|
|
1096
1096
|
--ai-input-bg: #1f2937;
|
|
1097
1097
|
--ai-input-border: #374151;
|
|
1098
1098
|
--ai-input-text: #f3f4f6;
|
|
@@ -1286,7 +1286,7 @@ button[data-pending=true]::after {
|
|
|
1286
1286
|
.ai-agent-panel__conversations {
|
|
1287
1287
|
flex: 1;
|
|
1288
1288
|
overflow-y: auto;
|
|
1289
|
-
padding: 8px;
|
|
1289
|
+
padding: 8px 0;
|
|
1290
1290
|
}
|
|
1291
1291
|
.ai-agent-panel__empty {
|
|
1292
1292
|
display: flex;
|
|
@@ -1312,15 +1312,15 @@ button[data-pending=true]::after {
|
|
|
1312
1312
|
opacity: 0.7;
|
|
1313
1313
|
}
|
|
1314
1314
|
.ai-agent-panel__group {
|
|
1315
|
-
margin-bottom:
|
|
1315
|
+
margin-bottom: 24px;
|
|
1316
1316
|
}
|
|
1317
1317
|
.ai-agent-panel__group-label {
|
|
1318
1318
|
font-size: var(--ai-group-label-size);
|
|
1319
|
-
font-weight:
|
|
1319
|
+
font-weight: 400;
|
|
1320
1320
|
color: var(--ai-group-label-color);
|
|
1321
1321
|
text-transform: uppercase;
|
|
1322
|
-
letter-spacing: 0.
|
|
1323
|
-
padding: 8px
|
|
1322
|
+
letter-spacing: 0.1em;
|
|
1323
|
+
padding: 8px 12px 4px;
|
|
1324
1324
|
}
|
|
1325
1325
|
.ai-agent-panel__group-label--clickable {
|
|
1326
1326
|
display: flex;
|
|
@@ -1328,10 +1328,10 @@ button[data-pending=true]::after {
|
|
|
1328
1328
|
justify-content: space-between;
|
|
1329
1329
|
cursor: pointer;
|
|
1330
1330
|
user-select: none;
|
|
1331
|
-
transition:
|
|
1331
|
+
transition: opacity 0.15s;
|
|
1332
1332
|
}
|
|
1333
1333
|
.ai-agent-panel__group-label--clickable:hover {
|
|
1334
|
-
|
|
1334
|
+
opacity: 0.7;
|
|
1335
1335
|
}
|
|
1336
1336
|
.ai-agent-panel__group-chevron {
|
|
1337
1337
|
font-size: 8px;
|
|
@@ -1344,10 +1344,11 @@ button[data-pending=true]::after {
|
|
|
1344
1344
|
.ai-agent-panel__conversation {
|
|
1345
1345
|
display: flex;
|
|
1346
1346
|
align-items: flex-start;
|
|
1347
|
-
padding:
|
|
1348
|
-
|
|
1347
|
+
padding: 6px 12px;
|
|
1348
|
+
margin: 0;
|
|
1349
|
+
border-radius: 0;
|
|
1349
1350
|
cursor: pointer;
|
|
1350
|
-
transition: background-color 0.
|
|
1351
|
+
transition: background-color 0.1s ease;
|
|
1351
1352
|
gap: 8px;
|
|
1352
1353
|
}
|
|
1353
1354
|
.ai-agent-panel__conversation:hover {
|
|
@@ -1362,12 +1363,12 @@ button[data-pending=true]::after {
|
|
|
1362
1363
|
}
|
|
1363
1364
|
.ai-agent-panel__conversation-title {
|
|
1364
1365
|
font-weight: 400;
|
|
1365
|
-
font-size:
|
|
1366
|
-
color: var(--ai-conversation-
|
|
1366
|
+
font-size: 13px;
|
|
1367
|
+
color: var(--ai-conversation-title-color);
|
|
1367
1368
|
white-space: nowrap;
|
|
1368
1369
|
overflow: hidden;
|
|
1369
1370
|
text-overflow: ellipsis;
|
|
1370
|
-
|
|
1371
|
+
line-height: 1.5;
|
|
1371
1372
|
}
|
|
1372
1373
|
.ai-agent-panel__conversation-preview {
|
|
1373
1374
|
font-size: 11px;
|
|
@@ -1908,22 +1909,25 @@ button[data-pending=true]::after {
|
|
|
1908
1909
|
}
|
|
1909
1910
|
}
|
|
1910
1911
|
.ai-agent-panel__group--active {
|
|
1911
|
-
|
|
1912
|
-
border-radius: 6px;
|
|
1913
|
-
margin-bottom: 8px;
|
|
1914
|
-
padding: 4px;
|
|
1912
|
+
margin-bottom: 24px;
|
|
1915
1913
|
}
|
|
1916
1914
|
.ai-agent-panel__group--active .ai-agent-panel__group-label {
|
|
1917
|
-
color: var(--ai-
|
|
1918
|
-
font-weight:
|
|
1915
|
+
color: var(--ai-group-label-color);
|
|
1916
|
+
font-weight: 400;
|
|
1917
|
+
padding: 8px 12px 4px;
|
|
1919
1918
|
}
|
|
1920
1919
|
.ai-agent-panel__conversation--active-item {
|
|
1921
1920
|
display: flex;
|
|
1922
1921
|
align-items: center;
|
|
1923
1922
|
justify-content: space-between;
|
|
1924
|
-
background-color:
|
|
1925
|
-
|
|
1926
|
-
margin:
|
|
1923
|
+
background-color: transparent;
|
|
1924
|
+
padding: 6px 12px;
|
|
1925
|
+
margin: 0;
|
|
1926
|
+
transition: background-color 0.1s ease;
|
|
1927
|
+
cursor: pointer;
|
|
1928
|
+
}
|
|
1929
|
+
.ai-agent-panel__conversation--active-item:hover {
|
|
1930
|
+
background-color: var(--ai-conversation-hover);
|
|
1927
1931
|
}
|
|
1928
1932
|
.ai-agent-panel__conversation--active-item .ai-agent-panel__conversation-content {
|
|
1929
1933
|
flex: 1;
|
|
@@ -1935,8 +1939,7 @@ button[data-pending=true]::after {
|
|
|
1935
1939
|
gap: 6px;
|
|
1936
1940
|
}
|
|
1937
1941
|
.ai-agent-panel__conversation--current {
|
|
1938
|
-
background-color:
|
|
1939
|
-
border-left: 2px solid var(--ai-button-primary-bg);
|
|
1942
|
+
background-color: rgba(59, 130, 246, 0.08) !important;
|
|
1940
1943
|
}
|
|
1941
1944
|
.ai-agent-panel__conversation--in-active {
|
|
1942
1945
|
opacity: 0.7;
|
|
@@ -1972,8 +1975,9 @@ button[data-pending=true]::after {
|
|
|
1972
1975
|
}
|
|
1973
1976
|
.ai-agent-panel__active-badge {
|
|
1974
1977
|
color: var(--ai-button-primary-bg);
|
|
1975
|
-
font-size:
|
|
1976
|
-
margin-right:
|
|
1978
|
+
font-size: 7px;
|
|
1979
|
+
margin-right: 4px;
|
|
1980
|
+
opacity: 0.8;
|
|
1977
1981
|
}
|
|
1978
1982
|
.ai-agent-panel__loading-dot {
|
|
1979
1983
|
display: inline-block;
|
|
@@ -1996,7 +2000,7 @@ button[data-pending=true]::after {
|
|
|
1996
2000
|
.ai-agent-panel__group-divider {
|
|
1997
2001
|
height: 1px;
|
|
1998
2002
|
background-color: var(--ai-sidebar-border);
|
|
1999
|
-
margin:
|
|
2003
|
+
margin: 20px 0;
|
|
2000
2004
|
}
|
|
2001
2005
|
.ai-agent-panel__chat-wrapper {
|
|
2002
2006
|
position: absolute;
|
package/dist/index.js
CHANGED
|
@@ -4338,13 +4338,7 @@ var AIChatPanel = ({
|
|
|
4338
4338
|
}
|
|
4339
4339
|
}), [thumbsDownClick, interactionClicked]);
|
|
4340
4340
|
const scrollToBottom = (0, import_react12.useCallback)((force = false) => {
|
|
4341
|
-
var _a2
|
|
4342
|
-
console.log("\u{1F535} scrollToBottom called", {
|
|
4343
|
-
force,
|
|
4344
|
-
idle: idleRef.current,
|
|
4345
|
-
calledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4346
|
-
stackTrace: (_a2 = new Error().stack) == null ? void 0 : _a2.split("\n").slice(2, 4).join("\n")
|
|
4347
|
-
});
|
|
4341
|
+
var _a2;
|
|
4348
4342
|
if (scrollRAFRef.current) {
|
|
4349
4343
|
cancelAnimationFrame(scrollRAFRef.current);
|
|
4350
4344
|
}
|
|
@@ -4355,19 +4349,10 @@ var AIChatPanel = ({
|
|
|
4355
4349
|
const scrollHeight = scrollElement.scrollHeight;
|
|
4356
4350
|
const clientHeight = scrollElement.clientHeight;
|
|
4357
4351
|
const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
|
|
4358
|
-
console.log("\u{1F535} scrollToBottom: checking position", {
|
|
4359
|
-
scrollTop,
|
|
4360
|
-
scrollHeight,
|
|
4361
|
-
clientHeight,
|
|
4362
|
-
distanceFromBottom: scrollHeight - scrollTop - clientHeight,
|
|
4363
|
-
isNearBottom
|
|
4364
|
-
});
|
|
4365
4352
|
if (!isNearBottom) {
|
|
4366
|
-
console.log("\u{1F535} scrollToBottom: CANCELLED (not near bottom)");
|
|
4367
4353
|
return;
|
|
4368
4354
|
}
|
|
4369
4355
|
}
|
|
4370
|
-
console.log("\u{1F535} scrollToBottom: EXECUTING SCROLL", { force });
|
|
4371
4356
|
const now = Date.now();
|
|
4372
4357
|
if (now - lastScrollTimeRef.current < 100) {
|
|
4373
4358
|
scrollRAFRef.current = requestAnimationFrame(() => {
|
|
@@ -4377,11 +4362,10 @@ var AIChatPanel = ({
|
|
|
4377
4362
|
});
|
|
4378
4363
|
return;
|
|
4379
4364
|
}
|
|
4380
|
-
(
|
|
4365
|
+
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "auto" });
|
|
4381
4366
|
lastScrollTimeRef.current = now;
|
|
4382
4367
|
}, []);
|
|
4383
4368
|
const continueChat = (0, import_react12.useCallback)((promptText) => {
|
|
4384
|
-
console.log("AIChatPanel.continueChat called with:", promptText);
|
|
4385
4369
|
setThinkingBlocks([]);
|
|
4386
4370
|
setCurrentThinkingIndex(0);
|
|
4387
4371
|
setError(null);
|
|
@@ -4597,31 +4581,15 @@ var AIChatPanel = ({
|
|
|
4597
4581
|
userHasScrolledRef.current = userHasScrolled;
|
|
4598
4582
|
}, [userHasScrolled]);
|
|
4599
4583
|
(0, import_react12.useEffect)(() => {
|
|
4600
|
-
console.log("AIChatPanel - Auto-scroll effect triggered", {
|
|
4601
|
-
idle,
|
|
4602
|
-
responseLength: response.length,
|
|
4603
|
-
effectRanAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4604
|
-
});
|
|
4605
4584
|
if (idle) {
|
|
4606
|
-
console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle=true)");
|
|
4607
4585
|
return;
|
|
4608
4586
|
}
|
|
4609
4587
|
const currentResponseLength = response.length;
|
|
4610
4588
|
const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
|
|
4611
|
-
console.log("AIChatPanel - Auto-scroll checks:", {
|
|
4612
|
-
currentResponseLength,
|
|
4613
|
-
prevLength: prevResponseLengthRef.current,
|
|
4614
|
-
responseGotLonger,
|
|
4615
|
-
userHasScrolled: userHasScrolledRef.current,
|
|
4616
|
-
scrollToEnd: scrollToEndRef.current
|
|
4617
|
-
});
|
|
4618
4589
|
prevResponseLengthRef.current = currentResponseLength;
|
|
4619
4590
|
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
4620
4591
|
if (shouldAutoScroll && response && responseGotLonger) {
|
|
4621
|
-
console.log("AIChatPanel - \u2705 SCROLLING TO BOTTOM");
|
|
4622
4592
|
scrollToBottom(false);
|
|
4623
|
-
} else {
|
|
4624
|
-
console.log("AIChatPanel - \u274C NOT scrolling (conditions not met)");
|
|
4625
4593
|
}
|
|
4626
4594
|
}, [response, idle]);
|
|
4627
4595
|
const idleRef = (0, import_react12.useRef)(idle);
|
|
@@ -6311,40 +6279,12 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6311
6279
|
null,
|
|
6312
6280
|
0
|
|
6313
6281
|
);
|
|
6314
|
-
console.log("AIAgentPanel - Context effect running", {
|
|
6315
|
-
sectionsCount: mergedContext.sections.length,
|
|
6316
|
-
sectionIds: mergedContext.sections.map((s) => s.id),
|
|
6317
|
-
contextLength: contextString.length,
|
|
6318
|
-
contextHash: contextString.substring(0, 50) + "..." + contextString.substring(contextString.length - 50)
|
|
6319
|
-
});
|
|
6320
6282
|
if (prevContextRef.current === null) {
|
|
6321
|
-
console.log("AIAgentPanel - First render, initializing context ref");
|
|
6322
6283
|
prevContextRef.current = contextString;
|
|
6323
6284
|
return;
|
|
6324
6285
|
}
|
|
6325
6286
|
const changed = prevContextRef.current !== contextString;
|
|
6326
6287
|
if (changed) {
|
|
6327
|
-
console.log("AIAgentPanel - \u2705 Context CHANGED, showing notification");
|
|
6328
|
-
console.log("AIAgentPanel - String length old/new:", prevContextRef.current.length, contextString.length);
|
|
6329
|
-
if (prevContextRef.current.length !== contextString.length) {
|
|
6330
|
-
console.log("AIAgentPanel - Length difference:", contextString.length - prevContextRef.current.length);
|
|
6331
|
-
}
|
|
6332
|
-
try {
|
|
6333
|
-
const oldSections = JSON.parse(prevContextRef.current);
|
|
6334
|
-
const newSections = JSON.parse(contextString);
|
|
6335
|
-
console.log("AIAgentPanel - Section count old/new:", oldSections.length, newSections.length);
|
|
6336
|
-
newSections.forEach((newSec, idx) => {
|
|
6337
|
-
const oldSec = oldSections[idx];
|
|
6338
|
-
if (!oldSec || JSON.stringify(oldSec.data) !== JSON.stringify(newSec.data)) {
|
|
6339
|
-
console.log(`AIAgentPanel - Section "${newSec.id}" changed:`, {
|
|
6340
|
-
oldDataLength: oldSec ? JSON.stringify(oldSec.data).length : 0,
|
|
6341
|
-
newDataLength: JSON.stringify(newSec.data).length
|
|
6342
|
-
});
|
|
6343
|
-
}
|
|
6344
|
-
});
|
|
6345
|
-
} catch (e) {
|
|
6346
|
-
console.log("AIAgentPanel - Could not parse for diff:", e);
|
|
6347
|
-
}
|
|
6348
6288
|
prevContextRef.current = contextString;
|
|
6349
6289
|
if (contextNotificationTimeoutRef.current) {
|
|
6350
6290
|
clearTimeout(contextNotificationTimeoutRef.current);
|
|
@@ -6355,17 +6295,6 @@ var AIAgentPanel = import_react14.default.forwardRef(({
|
|
|
6355
6295
|
setShowContextNotification(false);
|
|
6356
6296
|
contextNotificationTimeoutRef.current = null;
|
|
6357
6297
|
}, 3e3);
|
|
6358
|
-
} else {
|
|
6359
|
-
console.log("AIAgentPanel - \u274C Context UNCHANGED (strings match)");
|
|
6360
|
-
console.log("AIAgentPanel - Current context data:", mergedContext.sections.map((s) => ({
|
|
6361
|
-
id: s.id,
|
|
6362
|
-
dataKeys: Object.keys(s.data || {}),
|
|
6363
|
-
dataLength: JSON.stringify(s.data).length,
|
|
6364
|
-
dataPreview: JSON.stringify(s.data).substring(0, 200)
|
|
6365
|
-
})));
|
|
6366
|
-
console.log("AIAgentPanel - prevContextRef length:", prevContextRef.current.length);
|
|
6367
|
-
console.log("AIAgentPanel - new contextString length:", contextString.length);
|
|
6368
|
-
console.log("AIAgentPanel - Are they identical?", prevContextRef.current === contextString);
|
|
6369
6298
|
}
|
|
6370
6299
|
}, [mergedContext.sections]);
|
|
6371
6300
|
(0, import_react14.useEffect)(() => {
|
package/dist/index.mjs
CHANGED
|
@@ -4305,13 +4305,7 @@ var AIChatPanel = ({
|
|
|
4305
4305
|
}
|
|
4306
4306
|
}), [thumbsDownClick, interactionClicked]);
|
|
4307
4307
|
const scrollToBottom = useCallback2((force = false) => {
|
|
4308
|
-
var _a2
|
|
4309
|
-
console.log("\u{1F535} scrollToBottom called", {
|
|
4310
|
-
force,
|
|
4311
|
-
idle: idleRef.current,
|
|
4312
|
-
calledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4313
|
-
stackTrace: (_a2 = new Error().stack) == null ? void 0 : _a2.split("\n").slice(2, 4).join("\n")
|
|
4314
|
-
});
|
|
4308
|
+
var _a2;
|
|
4315
4309
|
if (scrollRAFRef.current) {
|
|
4316
4310
|
cancelAnimationFrame(scrollRAFRef.current);
|
|
4317
4311
|
}
|
|
@@ -4322,19 +4316,10 @@ var AIChatPanel = ({
|
|
|
4322
4316
|
const scrollHeight = scrollElement.scrollHeight;
|
|
4323
4317
|
const clientHeight = scrollElement.clientHeight;
|
|
4324
4318
|
const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
|
|
4325
|
-
console.log("\u{1F535} scrollToBottom: checking position", {
|
|
4326
|
-
scrollTop,
|
|
4327
|
-
scrollHeight,
|
|
4328
|
-
clientHeight,
|
|
4329
|
-
distanceFromBottom: scrollHeight - scrollTop - clientHeight,
|
|
4330
|
-
isNearBottom
|
|
4331
|
-
});
|
|
4332
4319
|
if (!isNearBottom) {
|
|
4333
|
-
console.log("\u{1F535} scrollToBottom: CANCELLED (not near bottom)");
|
|
4334
4320
|
return;
|
|
4335
4321
|
}
|
|
4336
4322
|
}
|
|
4337
|
-
console.log("\u{1F535} scrollToBottom: EXECUTING SCROLL", { force });
|
|
4338
4323
|
const now = Date.now();
|
|
4339
4324
|
if (now - lastScrollTimeRef.current < 100) {
|
|
4340
4325
|
scrollRAFRef.current = requestAnimationFrame(() => {
|
|
@@ -4344,11 +4329,10 @@ var AIChatPanel = ({
|
|
|
4344
4329
|
});
|
|
4345
4330
|
return;
|
|
4346
4331
|
}
|
|
4347
|
-
(
|
|
4332
|
+
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "auto" });
|
|
4348
4333
|
lastScrollTimeRef.current = now;
|
|
4349
4334
|
}, []);
|
|
4350
4335
|
const continueChat = useCallback2((promptText) => {
|
|
4351
|
-
console.log("AIChatPanel.continueChat called with:", promptText);
|
|
4352
4336
|
setThinkingBlocks([]);
|
|
4353
4337
|
setCurrentThinkingIndex(0);
|
|
4354
4338
|
setError(null);
|
|
@@ -4564,31 +4548,15 @@ var AIChatPanel = ({
|
|
|
4564
4548
|
userHasScrolledRef.current = userHasScrolled;
|
|
4565
4549
|
}, [userHasScrolled]);
|
|
4566
4550
|
useEffect7(() => {
|
|
4567
|
-
console.log("AIChatPanel - Auto-scroll effect triggered", {
|
|
4568
|
-
idle,
|
|
4569
|
-
responseLength: response.length,
|
|
4570
|
-
effectRanAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4571
|
-
});
|
|
4572
4551
|
if (idle) {
|
|
4573
|
-
console.log("AIChatPanel - Auto-scroll effect: SKIPPED (idle=true)");
|
|
4574
4552
|
return;
|
|
4575
4553
|
}
|
|
4576
4554
|
const currentResponseLength = response.length;
|
|
4577
4555
|
const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
|
|
4578
|
-
console.log("AIChatPanel - Auto-scroll checks:", {
|
|
4579
|
-
currentResponseLength,
|
|
4580
|
-
prevLength: prevResponseLengthRef.current,
|
|
4581
|
-
responseGotLonger,
|
|
4582
|
-
userHasScrolled: userHasScrolledRef.current,
|
|
4583
|
-
scrollToEnd: scrollToEndRef.current
|
|
4584
|
-
});
|
|
4585
4556
|
prevResponseLengthRef.current = currentResponseLength;
|
|
4586
4557
|
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
4587
4558
|
if (shouldAutoScroll && response && responseGotLonger) {
|
|
4588
|
-
console.log("AIChatPanel - \u2705 SCROLLING TO BOTTOM");
|
|
4589
4559
|
scrollToBottom(false);
|
|
4590
|
-
} else {
|
|
4591
|
-
console.log("AIChatPanel - \u274C NOT scrolling (conditions not met)");
|
|
4592
4560
|
}
|
|
4593
4561
|
}, [response, idle]);
|
|
4594
4562
|
const idleRef = useRef5(idle);
|
|
@@ -6278,40 +6246,12 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6278
6246
|
null,
|
|
6279
6247
|
0
|
|
6280
6248
|
);
|
|
6281
|
-
console.log("AIAgentPanel - Context effect running", {
|
|
6282
|
-
sectionsCount: mergedContext.sections.length,
|
|
6283
|
-
sectionIds: mergedContext.sections.map((s) => s.id),
|
|
6284
|
-
contextLength: contextString.length,
|
|
6285
|
-
contextHash: contextString.substring(0, 50) + "..." + contextString.substring(contextString.length - 50)
|
|
6286
|
-
});
|
|
6287
6249
|
if (prevContextRef.current === null) {
|
|
6288
|
-
console.log("AIAgentPanel - First render, initializing context ref");
|
|
6289
6250
|
prevContextRef.current = contextString;
|
|
6290
6251
|
return;
|
|
6291
6252
|
}
|
|
6292
6253
|
const changed = prevContextRef.current !== contextString;
|
|
6293
6254
|
if (changed) {
|
|
6294
|
-
console.log("AIAgentPanel - \u2705 Context CHANGED, showing notification");
|
|
6295
|
-
console.log("AIAgentPanel - String length old/new:", prevContextRef.current.length, contextString.length);
|
|
6296
|
-
if (prevContextRef.current.length !== contextString.length) {
|
|
6297
|
-
console.log("AIAgentPanel - Length difference:", contextString.length - prevContextRef.current.length);
|
|
6298
|
-
}
|
|
6299
|
-
try {
|
|
6300
|
-
const oldSections = JSON.parse(prevContextRef.current);
|
|
6301
|
-
const newSections = JSON.parse(contextString);
|
|
6302
|
-
console.log("AIAgentPanel - Section count old/new:", oldSections.length, newSections.length);
|
|
6303
|
-
newSections.forEach((newSec, idx) => {
|
|
6304
|
-
const oldSec = oldSections[idx];
|
|
6305
|
-
if (!oldSec || JSON.stringify(oldSec.data) !== JSON.stringify(newSec.data)) {
|
|
6306
|
-
console.log(`AIAgentPanel - Section "${newSec.id}" changed:`, {
|
|
6307
|
-
oldDataLength: oldSec ? JSON.stringify(oldSec.data).length : 0,
|
|
6308
|
-
newDataLength: JSON.stringify(newSec.data).length
|
|
6309
|
-
});
|
|
6310
|
-
}
|
|
6311
|
-
});
|
|
6312
|
-
} catch (e) {
|
|
6313
|
-
console.log("AIAgentPanel - Could not parse for diff:", e);
|
|
6314
|
-
}
|
|
6315
6255
|
prevContextRef.current = contextString;
|
|
6316
6256
|
if (contextNotificationTimeoutRef.current) {
|
|
6317
6257
|
clearTimeout(contextNotificationTimeoutRef.current);
|
|
@@ -6322,17 +6262,6 @@ var AIAgentPanel = React13.forwardRef(({
|
|
|
6322
6262
|
setShowContextNotification(false);
|
|
6323
6263
|
contextNotificationTimeoutRef.current = null;
|
|
6324
6264
|
}, 3e3);
|
|
6325
|
-
} else {
|
|
6326
|
-
console.log("AIAgentPanel - \u274C Context UNCHANGED (strings match)");
|
|
6327
|
-
console.log("AIAgentPanel - Current context data:", mergedContext.sections.map((s) => ({
|
|
6328
|
-
id: s.id,
|
|
6329
|
-
dataKeys: Object.keys(s.data || {}),
|
|
6330
|
-
dataLength: JSON.stringify(s.data).length,
|
|
6331
|
-
dataPreview: JSON.stringify(s.data).substring(0, 200)
|
|
6332
|
-
})));
|
|
6333
|
-
console.log("AIAgentPanel - prevContextRef length:", prevContextRef.current.length);
|
|
6334
|
-
console.log("AIAgentPanel - new contextString length:", contextString.length);
|
|
6335
|
-
console.log("AIAgentPanel - Are they identical?", prevContextRef.current === contextString);
|
|
6336
6265
|
}
|
|
6337
6266
|
}, [mergedContext.sections]);
|
|
6338
6267
|
useEffect9(() => {
|
package/package.json
CHANGED
package/src/AIAgentPanel.css
CHANGED
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
--ai-panel-transition: 0.2s ease;
|
|
18
18
|
|
|
19
19
|
/* Sidebar Colors */
|
|
20
|
-
--ai-sidebar-bg: #
|
|
20
|
+
--ai-sidebar-bg: #ffffff;
|
|
21
21
|
--ai-sidebar-border: #e5e7eb;
|
|
22
|
-
--ai-sidebar-text: #
|
|
22
|
+
--ai-sidebar-text: #111827;
|
|
23
23
|
--ai-sidebar-text-muted: #6b7280;
|
|
24
|
-
--ai-sidebar-hover: #
|
|
25
|
-
--ai-sidebar-active: #
|
|
24
|
+
--ai-sidebar-hover: #f9fafb;
|
|
25
|
+
--ai-sidebar-active: #f3f4f6;
|
|
26
26
|
|
|
27
27
|
/* Header */
|
|
28
28
|
--ai-header-bg: #ffffff;
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
|
|
38
38
|
/* Conversation List */
|
|
39
39
|
--ai-conversation-bg: transparent;
|
|
40
|
-
--ai-conversation-hover: rgba(0, 0, 0, 0.
|
|
41
|
-
--ai-conversation-active: rgba(0, 0, 0, 0.
|
|
40
|
+
--ai-conversation-hover: rgba(0, 0, 0, 0.03);
|
|
41
|
+
--ai-conversation-active: rgba(0, 0, 0, 0.05);
|
|
42
42
|
--ai-conversation-title-color: #1f2937;
|
|
43
43
|
--ai-conversation-preview-color: #6b7280;
|
|
44
44
|
--ai-conversation-meta-color: #9ca3af;
|
|
45
45
|
|
|
46
46
|
/* Group Labels */
|
|
47
|
-
--ai-group-label-color: #
|
|
48
|
-
--ai-group-label-size: 0.
|
|
47
|
+
--ai-group-label-color: #6b7280;
|
|
48
|
+
--ai-group-label-size: 0.6875rem;
|
|
49
49
|
|
|
50
50
|
/* Buttons */
|
|
51
51
|
--ai-button-primary-bg: #3b82f6;
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
--ai-button-secondary-text: #374151;
|
|
56
56
|
--ai-button-secondary-border: #d1d5db;
|
|
57
57
|
--ai-button-secondary-hover: #e5e7eb;
|
|
58
|
-
--ai-button-ghost-hover:
|
|
58
|
+
--ai-button-ghost-hover: #f3f4f6;
|
|
59
59
|
--ai-button-destructive-bg: #ef4444;
|
|
60
60
|
--ai-button-destructive-text: #ffffff;
|
|
61
61
|
--ai-button-destructive-hover: #dc2626;
|
|
62
|
-
--ai-button-radius:
|
|
62
|
+
--ai-button-radius: 4px;
|
|
63
63
|
|
|
64
64
|
/* Input */
|
|
65
65
|
--ai-input-bg: #ffffff;
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
--ai-input-placeholder: #9ca3af;
|
|
69
69
|
--ai-input-focus-border: #3b82f6;
|
|
70
70
|
--ai-input-focus-ring: rgba(59, 130, 246, 0.2);
|
|
71
|
-
--ai-input-radius:
|
|
71
|
+
--ai-input-radius: 4px;
|
|
72
72
|
|
|
73
73
|
/* Select */
|
|
74
74
|
--ai-select-bg: #ffffff;
|
|
@@ -119,24 +119,24 @@
|
|
|
119
119
|
CSS Variables - Dark Theme
|
|
120
120
|
-------------------------------------------------------- */
|
|
121
121
|
.dark-theme {
|
|
122
|
-
--ai-sidebar-bg: #
|
|
123
|
-
--ai-sidebar-border: #
|
|
122
|
+
--ai-sidebar-bg: #111827;
|
|
123
|
+
--ai-sidebar-border: #1f2937;
|
|
124
124
|
--ai-sidebar-text: #f3f4f6;
|
|
125
125
|
--ai-sidebar-text-muted: #9ca3af;
|
|
126
|
-
--ai-sidebar-hover: #
|
|
127
|
-
--ai-sidebar-active: #
|
|
126
|
+
--ai-sidebar-hover: #1f2937;
|
|
127
|
+
--ai-sidebar-active: #374151;
|
|
128
128
|
|
|
129
|
-
--ai-header-bg: #
|
|
130
|
-
--ai-header-border: #
|
|
129
|
+
--ai-header-bg: #0d1117;
|
|
130
|
+
--ai-header-border: #1f2937;
|
|
131
131
|
|
|
132
132
|
--ai-agent-badge-bg: #1e3a5f;
|
|
133
133
|
--ai-agent-badge-text: #60a5fa;
|
|
134
134
|
--ai-agent-selector-bg: #1f2937;
|
|
135
135
|
--ai-agent-selector-border: #374151;
|
|
136
136
|
|
|
137
|
-
--ai-conversation-hover: rgba(255, 255, 255, 0.
|
|
137
|
+
--ai-conversation-hover: rgba(255, 255, 255, 0.05);
|
|
138
138
|
--ai-conversation-active: rgba(255, 255, 255, 0.08);
|
|
139
|
-
--ai-conversation-title-color: #
|
|
139
|
+
--ai-conversation-title-color: #e5e7eb;
|
|
140
140
|
--ai-conversation-preview-color: #9ca3af;
|
|
141
141
|
--ai-conversation-meta-color: #6b7280;
|
|
142
142
|
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
--ai-button-secondary-text: #f3f4f6;
|
|
150
150
|
--ai-button-secondary-border: #4b5563;
|
|
151
151
|
--ai-button-secondary-hover: #4b5563;
|
|
152
|
-
--ai-button-ghost-hover:
|
|
152
|
+
--ai-button-ghost-hover: #1f2937;
|
|
153
153
|
|
|
154
154
|
--ai-input-bg: #1f2937;
|
|
155
155
|
--ai-input-border: #374151;
|
|
@@ -395,7 +395,7 @@
|
|
|
395
395
|
.ai-agent-panel__conversations {
|
|
396
396
|
flex: 1;
|
|
397
397
|
overflow-y: auto;
|
|
398
|
-
padding: 8px;
|
|
398
|
+
padding: 8px 0;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
401
|
.ai-agent-panel__empty {
|
|
@@ -427,16 +427,16 @@
|
|
|
427
427
|
|
|
428
428
|
/* Groups */
|
|
429
429
|
.ai-agent-panel__group {
|
|
430
|
-
margin-bottom:
|
|
430
|
+
margin-bottom: 24px;
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
.ai-agent-panel__group-label {
|
|
434
434
|
font-size: var(--ai-group-label-size);
|
|
435
|
-
font-weight:
|
|
435
|
+
font-weight: 400;
|
|
436
436
|
color: var(--ai-group-label-color);
|
|
437
437
|
text-transform: uppercase;
|
|
438
|
-
letter-spacing: 0.
|
|
439
|
-
padding: 8px
|
|
438
|
+
letter-spacing: 0.1em;
|
|
439
|
+
padding: 8px 12px 4px;
|
|
440
440
|
}
|
|
441
441
|
|
|
442
442
|
.ai-agent-panel__group-label--clickable {
|
|
@@ -445,11 +445,11 @@
|
|
|
445
445
|
justify-content: space-between;
|
|
446
446
|
cursor: pointer;
|
|
447
447
|
user-select: none;
|
|
448
|
-
transition:
|
|
448
|
+
transition: opacity 0.15s;
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
.ai-agent-panel__group-label--clickable:hover {
|
|
452
|
-
|
|
452
|
+
opacity: 0.7;
|
|
453
453
|
}
|
|
454
454
|
|
|
455
455
|
.ai-agent-panel__group-chevron {
|
|
@@ -466,10 +466,11 @@
|
|
|
466
466
|
.ai-agent-panel__conversation {
|
|
467
467
|
display: flex;
|
|
468
468
|
align-items: flex-start;
|
|
469
|
-
padding:
|
|
470
|
-
|
|
469
|
+
padding: 6px 12px;
|
|
470
|
+
margin: 0;
|
|
471
|
+
border-radius: 0;
|
|
471
472
|
cursor: pointer;
|
|
472
|
-
transition: background-color 0.
|
|
473
|
+
transition: background-color 0.1s ease;
|
|
473
474
|
gap: 8px;
|
|
474
475
|
}
|
|
475
476
|
|
|
@@ -488,12 +489,12 @@
|
|
|
488
489
|
|
|
489
490
|
.ai-agent-panel__conversation-title {
|
|
490
491
|
font-weight: 400;
|
|
491
|
-
font-size:
|
|
492
|
-
color: var(--ai-conversation-
|
|
492
|
+
font-size: 13px;
|
|
493
|
+
color: var(--ai-conversation-title-color);
|
|
493
494
|
white-space: nowrap;
|
|
494
495
|
overflow: hidden;
|
|
495
496
|
text-overflow: ellipsis;
|
|
496
|
-
|
|
497
|
+
line-height: 1.5;
|
|
497
498
|
}
|
|
498
499
|
|
|
499
500
|
.ai-agent-panel__conversation-preview {
|
|
@@ -1169,24 +1170,28 @@
|
|
|
1169
1170
|
-------------------------------------------------------- */
|
|
1170
1171
|
|
|
1171
1172
|
.ai-agent-panel__group--active {
|
|
1172
|
-
|
|
1173
|
-
border-radius: 6px;
|
|
1174
|
-
margin-bottom: 8px;
|
|
1175
|
-
padding: 4px;
|
|
1173
|
+
margin-bottom: 24px;
|
|
1176
1174
|
}
|
|
1177
1175
|
|
|
1178
1176
|
.ai-agent-panel__group--active .ai-agent-panel__group-label {
|
|
1179
|
-
color: var(--ai-
|
|
1180
|
-
font-weight:
|
|
1177
|
+
color: var(--ai-group-label-color);
|
|
1178
|
+
font-weight: 400;
|
|
1179
|
+
padding: 8px 12px 4px;
|
|
1181
1180
|
}
|
|
1182
1181
|
|
|
1183
1182
|
.ai-agent-panel__conversation--active-item {
|
|
1184
1183
|
display: flex;
|
|
1185
1184
|
align-items: center;
|
|
1186
1185
|
justify-content: space-between;
|
|
1187
|
-
background-color:
|
|
1188
|
-
|
|
1189
|
-
margin:
|
|
1186
|
+
background-color: transparent;
|
|
1187
|
+
padding: 6px 12px;
|
|
1188
|
+
margin: 0;
|
|
1189
|
+
transition: background-color 0.1s ease;
|
|
1190
|
+
cursor: pointer;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
.ai-agent-panel__conversation--active-item:hover {
|
|
1194
|
+
background-color: var(--ai-conversation-hover);
|
|
1190
1195
|
}
|
|
1191
1196
|
|
|
1192
1197
|
.ai-agent-panel__conversation--active-item .ai-agent-panel__conversation-content {
|
|
@@ -1201,8 +1206,7 @@
|
|
|
1201
1206
|
}
|
|
1202
1207
|
|
|
1203
1208
|
.ai-agent-panel__conversation--current {
|
|
1204
|
-
background-color:
|
|
1205
|
-
border-left: 2px solid var(--ai-button-primary-bg);
|
|
1209
|
+
background-color: rgba(59, 130, 246, 0.08) !important;
|
|
1206
1210
|
}
|
|
1207
1211
|
|
|
1208
1212
|
.ai-agent-panel__conversation--in-active {
|
|
@@ -1243,8 +1247,9 @@
|
|
|
1243
1247
|
/* Active badge for conversations in history */
|
|
1244
1248
|
.ai-agent-panel__active-badge {
|
|
1245
1249
|
color: var(--ai-button-primary-bg);
|
|
1246
|
-
font-size:
|
|
1247
|
-
margin-right:
|
|
1250
|
+
font-size: 7px;
|
|
1251
|
+
margin-right: 4px;
|
|
1252
|
+
opacity: 0.8;
|
|
1248
1253
|
}
|
|
1249
1254
|
|
|
1250
1255
|
/* Loading dot indicator */
|
|
@@ -1272,7 +1277,7 @@
|
|
|
1272
1277
|
.ai-agent-panel__group-divider {
|
|
1273
1278
|
height: 1px;
|
|
1274
1279
|
background-color: var(--ai-sidebar-border);
|
|
1275
|
-
margin:
|
|
1280
|
+
margin: 20px 0;
|
|
1276
1281
|
}
|
|
1277
1282
|
|
|
1278
1283
|
/* Chat wrapper for multi-conversation support */
|
package/src/AIAgentPanel.tsx
CHANGED
|
@@ -1541,16 +1541,8 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
1541
1541
|
0
|
|
1542
1542
|
);
|
|
1543
1543
|
|
|
1544
|
-
console.log('AIAgentPanel - Context effect running', {
|
|
1545
|
-
sectionsCount: mergedContext.sections.length,
|
|
1546
|
-
sectionIds: mergedContext.sections.map(s => s.id),
|
|
1547
|
-
contextLength: contextString.length,
|
|
1548
|
-
contextHash: contextString.substring(0, 50) + '...' + contextString.substring(contextString.length - 50)
|
|
1549
|
-
});
|
|
1550
|
-
|
|
1551
1544
|
// Skip on first render
|
|
1552
1545
|
if (prevContextRef.current === null) {
|
|
1553
|
-
console.log('AIAgentPanel - First render, initializing context ref');
|
|
1554
1546
|
prevContextRef.current = contextString;
|
|
1555
1547
|
return;
|
|
1556
1548
|
}
|
|
@@ -1559,32 +1551,6 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
1559
1551
|
const changed = prevContextRef.current !== contextString;
|
|
1560
1552
|
|
|
1561
1553
|
if (changed) {
|
|
1562
|
-
console.log('AIAgentPanel - ✅ Context CHANGED, showing notification');
|
|
1563
|
-
console.log('AIAgentPanel - String length old/new:', prevContextRef.current.length, contextString.length);
|
|
1564
|
-
|
|
1565
|
-
// Find what changed
|
|
1566
|
-
if (prevContextRef.current.length !== contextString.length) {
|
|
1567
|
-
console.log('AIAgentPanel - Length difference:', contextString.length - prevContextRef.current.length);
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
// Show detailed diff for debugging
|
|
1571
|
-
try {
|
|
1572
|
-
const oldSections = JSON.parse(prevContextRef.current);
|
|
1573
|
-
const newSections = JSON.parse(contextString);
|
|
1574
|
-
console.log('AIAgentPanel - Section count old/new:', oldSections.length, newSections.length);
|
|
1575
|
-
newSections.forEach((newSec: any, idx: number) => {
|
|
1576
|
-
const oldSec = oldSections[idx];
|
|
1577
|
-
if (!oldSec || JSON.stringify(oldSec.data) !== JSON.stringify(newSec.data)) {
|
|
1578
|
-
console.log(`AIAgentPanel - Section "${newSec.id}" changed:`, {
|
|
1579
|
-
oldDataLength: oldSec ? JSON.stringify(oldSec.data).length : 0,
|
|
1580
|
-
newDataLength: JSON.stringify(newSec.data).length
|
|
1581
|
-
});
|
|
1582
|
-
}
|
|
1583
|
-
});
|
|
1584
|
-
} catch (e) {
|
|
1585
|
-
console.log('AIAgentPanel - Could not parse for diff:', e);
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
1554
|
prevContextRef.current = contextString;
|
|
1589
1555
|
|
|
1590
1556
|
// Clear any existing timeout before setting a new one
|
|
@@ -1601,21 +1567,7 @@ const AIAgentPanel = React.forwardRef<AIAgentPanelHandle, AIAgentPanelProps>(({
|
|
|
1601
1567
|
setShowContextNotification(false);
|
|
1602
1568
|
contextNotificationTimeoutRef.current = null;
|
|
1603
1569
|
}, 3000);
|
|
1604
|
-
} else {
|
|
1605
|
-
console.log('AIAgentPanel - ❌ Context UNCHANGED (strings match)');
|
|
1606
|
-
console.log('AIAgentPanel - Current context data:', mergedContext.sections.map(s => ({
|
|
1607
|
-
id: s.id,
|
|
1608
|
-
dataKeys: Object.keys(s.data || {}),
|
|
1609
|
-
dataLength: JSON.stringify(s.data).length,
|
|
1610
|
-
dataPreview: JSON.stringify(s.data).substring(0, 200)
|
|
1611
|
-
})));
|
|
1612
|
-
console.log('AIAgentPanel - prevContextRef length:', prevContextRef.current.length);
|
|
1613
|
-
console.log('AIAgentPanel - new contextString length:', contextString.length);
|
|
1614
|
-
console.log('AIAgentPanel - Are they identical?', prevContextRef.current === contextString);
|
|
1615
1570
|
}
|
|
1616
|
-
|
|
1617
|
-
// Note: No cleanup on every re-render - only clear timeout when context changes
|
|
1618
|
-
// This prevents race conditions when switching rapidly
|
|
1619
1571
|
}, [mergedContext.sections]);
|
|
1620
1572
|
|
|
1621
1573
|
// Separate cleanup effect for unmount only
|
package/src/AIChatPanel.tsx
CHANGED
|
@@ -1474,13 +1474,6 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1474
1474
|
|
|
1475
1475
|
// Scroll to bottom - throttled using RAF to prevent layout thrashing
|
|
1476
1476
|
const scrollToBottom = useCallback((force: boolean = false) => {
|
|
1477
|
-
console.log('🔵 scrollToBottom called', {
|
|
1478
|
-
force,
|
|
1479
|
-
idle: idleRef.current,
|
|
1480
|
-
calledAt: new Date().toISOString(),
|
|
1481
|
-
stackTrace: new Error().stack?.split('\n').slice(2, 4).join('\n')
|
|
1482
|
-
});
|
|
1483
|
-
|
|
1484
1477
|
// Cancel any pending scroll
|
|
1485
1478
|
if (scrollRAFRef.current) {
|
|
1486
1479
|
cancelAnimationFrame(scrollRAFRef.current);
|
|
@@ -1496,23 +1489,12 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1496
1489
|
const clientHeight = scrollElement.clientHeight;
|
|
1497
1490
|
const isNearBottom = scrollHeight - scrollTop - clientHeight < 100;
|
|
1498
1491
|
|
|
1499
|
-
console.log('🔵 scrollToBottom: checking position', {
|
|
1500
|
-
scrollTop,
|
|
1501
|
-
scrollHeight,
|
|
1502
|
-
clientHeight,
|
|
1503
|
-
distanceFromBottom: scrollHeight - scrollTop - clientHeight,
|
|
1504
|
-
isNearBottom
|
|
1505
|
-
});
|
|
1506
|
-
|
|
1507
1492
|
// If user is not near bottom, don't scroll (prevents scroll on layout changes like toast)
|
|
1508
1493
|
if (!isNearBottom) {
|
|
1509
|
-
console.log('🔵 scrollToBottom: CANCELLED (not near bottom)');
|
|
1510
1494
|
return;
|
|
1511
1495
|
}
|
|
1512
1496
|
}
|
|
1513
1497
|
|
|
1514
|
-
console.log('🔵 scrollToBottom: EXECUTING SCROLL', { force });
|
|
1515
|
-
|
|
1516
1498
|
// Throttle to max once per 100ms to prevent performance issues during streaming
|
|
1517
1499
|
const now = Date.now();
|
|
1518
1500
|
if (now - lastScrollTimeRef.current < 100) {
|
|
@@ -1532,7 +1514,6 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1532
1514
|
// Continue chat (send message) - matches ChatPanel behavior exactly
|
|
1533
1515
|
// promptText is now required - comes from the isolated ChatInput component
|
|
1534
1516
|
const continueChat = useCallback((promptText: string) => {
|
|
1535
|
-
console.log('AIChatPanel.continueChat called with:', promptText);
|
|
1536
1517
|
// Clear thinking blocks for new response
|
|
1537
1518
|
setThinkingBlocks([]);
|
|
1538
1519
|
setCurrentThinkingIndex(0);
|
|
@@ -1853,15 +1834,8 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1853
1834
|
// Auto-scroll to bottom - only while streaming and user hasn't manually scrolled
|
|
1854
1835
|
// CRITICAL: Only depends on response and idle to avoid re-running on layout changes
|
|
1855
1836
|
useEffect(() => {
|
|
1856
|
-
console.log('AIChatPanel - Auto-scroll effect triggered', {
|
|
1857
|
-
idle,
|
|
1858
|
-
responseLength: response.length,
|
|
1859
|
-
effectRanAt: new Date().toISOString(),
|
|
1860
|
-
});
|
|
1861
|
-
|
|
1862
1837
|
// CRITICAL: Skip entirely if idle - no scrolling when not streaming
|
|
1863
1838
|
if (idle) {
|
|
1864
|
-
console.log('AIChatPanel - Auto-scroll effect: SKIPPED (idle=true)');
|
|
1865
1839
|
return;
|
|
1866
1840
|
}
|
|
1867
1841
|
|
|
@@ -1873,24 +1847,13 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
1873
1847
|
const currentResponseLength = response.length;
|
|
1874
1848
|
const responseGotLonger = currentResponseLength > prevResponseLengthRef.current;
|
|
1875
1849
|
|
|
1876
|
-
console.log('AIChatPanel - Auto-scroll checks:', {
|
|
1877
|
-
currentResponseLength,
|
|
1878
|
-
prevLength: prevResponseLengthRef.current,
|
|
1879
|
-
responseGotLonger,
|
|
1880
|
-
userHasScrolled: userHasScrolledRef.current,
|
|
1881
|
-
scrollToEnd: scrollToEndRef.current,
|
|
1882
|
-
});
|
|
1883
|
-
|
|
1884
1850
|
prevResponseLengthRef.current = currentResponseLength;
|
|
1885
1851
|
|
|
1886
1852
|
// Only scroll if response actually grew - use refs to avoid unnecessary effect runs
|
|
1887
1853
|
const shouldAutoScroll = scrollToEndRef.current || !userHasScrolledRef.current;
|
|
1888
1854
|
if (shouldAutoScroll && response && responseGotLonger) {
|
|
1889
|
-
console.log('AIChatPanel - ✅ SCROLLING TO BOTTOM');
|
|
1890
1855
|
// Use non-forced scroll - will only scroll if near bottom
|
|
1891
1856
|
scrollToBottom(false);
|
|
1892
|
-
} else {
|
|
1893
|
-
console.log('AIChatPanel - ❌ NOT scrolling (conditions not met)');
|
|
1894
1857
|
}
|
|
1895
1858
|
}, [response, idle]); // ONLY response and idle - no other dependencies!
|
|
1896
1859
|
|