@xinghunm/ai-chat 1.3.3 → 1.4.0
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/README.md +86 -30
- package/dist/index.d.mts +72 -1
- package/dist/index.d.ts +72 -1
- package/dist/index.js +505 -33
- package/dist/index.mjs +505 -33
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/ai-chat/index.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect11 } from "react";
|
|
3
3
|
import styled17 from "@emotion/styled";
|
|
4
4
|
import { ConfigProvider } from "@xinghunm/compass-ui";
|
|
5
5
|
|
|
@@ -53,7 +53,10 @@ var DEFAULT_AI_CHAT_LABELS = {
|
|
|
53
53
|
modelUnavailable: "No model available",
|
|
54
54
|
skillLoading: "Loading skills...",
|
|
55
55
|
skillEmpty: "No matching skills",
|
|
56
|
-
removeSkillAriaLabel: "Remove skill"
|
|
56
|
+
removeSkillAriaLabel: "Remove skill",
|
|
57
|
+
sessionHistoryLoading: "Loading conversations...",
|
|
58
|
+
sessionHistoryLoadFailed: "Failed to load conversations",
|
|
59
|
+
sessionHistoryEmpty: "No conversations yet"
|
|
57
60
|
};
|
|
58
61
|
|
|
59
62
|
// src/lib/chat-session.ts
|
|
@@ -81,6 +84,20 @@ var createDraftChatSession = ({
|
|
|
81
84
|
// src/store/chat-store.ts
|
|
82
85
|
var DEFAULT_CHAT_SESSION_TITLE = "New Chat";
|
|
83
86
|
var IMAGE_MESSAGE_SESSION_TITLE = "Image message";
|
|
87
|
+
var createHistoryMessagePaginationState = (page) => ({
|
|
88
|
+
previousCursor: page?.previousCursor ?? null,
|
|
89
|
+
hasMorePrevious: page?.hasMorePrevious ?? Boolean(page && page.previousCursor !== null),
|
|
90
|
+
isLoadingPrevious: false,
|
|
91
|
+
error: null
|
|
92
|
+
});
|
|
93
|
+
var normalizeHistoryMessages = (sessionId, messages) => messages.map((message) => ({ ...message, sessionId }));
|
|
94
|
+
var mergeOlderHistoryMessages = (sessionId, olderMessages, currentMessages) => {
|
|
95
|
+
const currentMessageIds = new Set(currentMessages.map((message) => message.id));
|
|
96
|
+
const uniqueOlderMessages = normalizeHistoryMessages(sessionId, olderMessages).filter(
|
|
97
|
+
(message) => !currentMessageIds.has(message.id)
|
|
98
|
+
);
|
|
99
|
+
return [...uniqueOlderMessages, ...currentMessages];
|
|
100
|
+
};
|
|
84
101
|
var resolveSessionTitleFromMessage = (message) => {
|
|
85
102
|
const trimmedContent = message.content.trim();
|
|
86
103
|
if (trimmedContent) {
|
|
@@ -183,6 +200,9 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
183
200
|
isStreamingBySession: {},
|
|
184
201
|
isStoppingBySession: {},
|
|
185
202
|
errorBySession: {},
|
|
203
|
+
sessionMessageLoadStatusBySession: {},
|
|
204
|
+
sessionMessageLoadErrorBySession: {},
|
|
205
|
+
historyMessagePaginationBySession: {},
|
|
186
206
|
// ---- Session management ------------------------------------------------
|
|
187
207
|
createSession: (session) => {
|
|
188
208
|
const state = get();
|
|
@@ -196,6 +216,15 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
196
216
|
const nextErrorBySession = { ...state.errorBySession };
|
|
197
217
|
const nextIsStreamingBySession = { ...state.isStreamingBySession };
|
|
198
218
|
const nextIsStoppingBySession = { ...state.isStoppingBySession };
|
|
219
|
+
const nextSessionMessageLoadStatusBySession = {
|
|
220
|
+
...state.sessionMessageLoadStatusBySession
|
|
221
|
+
};
|
|
222
|
+
const nextSessionMessageLoadErrorBySession = {
|
|
223
|
+
...state.sessionMessageLoadErrorBySession
|
|
224
|
+
};
|
|
225
|
+
const nextHistoryMessagePaginationBySession = {
|
|
226
|
+
...state.historyMessagePaginationBySession
|
|
227
|
+
};
|
|
199
228
|
const sid = session.sessionId;
|
|
200
229
|
if (nextMessagesBySession[sid] === void 0)
|
|
201
230
|
nextMessagesBySession[sid] = [];
|
|
@@ -205,13 +234,25 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
205
234
|
nextIsStreamingBySession[sid] = false;
|
|
206
235
|
if (nextIsStoppingBySession[sid] === void 0)
|
|
207
236
|
nextIsStoppingBySession[sid] = false;
|
|
237
|
+
if (nextSessionMessageLoadStatusBySession[sid] === void 0) {
|
|
238
|
+
nextSessionMessageLoadStatusBySession[sid] = "loaded";
|
|
239
|
+
}
|
|
240
|
+
if (nextSessionMessageLoadErrorBySession[sid] === void 0) {
|
|
241
|
+
nextSessionMessageLoadErrorBySession[sid] = null;
|
|
242
|
+
}
|
|
243
|
+
if (nextHistoryMessagePaginationBySession[sid] === void 0) {
|
|
244
|
+
nextHistoryMessagePaginationBySession[sid] = createHistoryMessagePaginationState();
|
|
245
|
+
}
|
|
208
246
|
set({
|
|
209
247
|
sessions: nextSessions,
|
|
210
248
|
activeSessionId: sid,
|
|
211
249
|
messagesBySession: nextMessagesBySession,
|
|
212
250
|
errorBySession: nextErrorBySession,
|
|
213
251
|
isStreamingBySession: nextIsStreamingBySession,
|
|
214
|
-
isStoppingBySession: nextIsStoppingBySession
|
|
252
|
+
isStoppingBySession: nextIsStoppingBySession,
|
|
253
|
+
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
254
|
+
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
255
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
215
256
|
});
|
|
216
257
|
},
|
|
217
258
|
startNewChat: () => {
|
|
@@ -266,6 +307,27 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
266
307
|
nextErrorBySession[nextSessionId] = nextErrorBySession[previousSessionId] ?? null;
|
|
267
308
|
delete nextErrorBySession[previousSessionId];
|
|
268
309
|
}
|
|
310
|
+
const nextSessionMessageLoadStatusBySession = {
|
|
311
|
+
...state.sessionMessageLoadStatusBySession
|
|
312
|
+
};
|
|
313
|
+
if (previousSessionId in nextSessionMessageLoadStatusBySession) {
|
|
314
|
+
nextSessionMessageLoadStatusBySession[nextSessionId] = nextSessionMessageLoadStatusBySession[previousSessionId] ?? "idle";
|
|
315
|
+
delete nextSessionMessageLoadStatusBySession[previousSessionId];
|
|
316
|
+
}
|
|
317
|
+
const nextSessionMessageLoadErrorBySession = {
|
|
318
|
+
...state.sessionMessageLoadErrorBySession
|
|
319
|
+
};
|
|
320
|
+
if (previousSessionId in nextSessionMessageLoadErrorBySession) {
|
|
321
|
+
nextSessionMessageLoadErrorBySession[nextSessionId] = nextSessionMessageLoadErrorBySession[previousSessionId] ?? null;
|
|
322
|
+
delete nextSessionMessageLoadErrorBySession[previousSessionId];
|
|
323
|
+
}
|
|
324
|
+
const nextHistoryMessagePaginationBySession = {
|
|
325
|
+
...state.historyMessagePaginationBySession
|
|
326
|
+
};
|
|
327
|
+
if (previousSessionId in nextHistoryMessagePaginationBySession) {
|
|
328
|
+
nextHistoryMessagePaginationBySession[nextSessionId] = nextHistoryMessagePaginationBySession[previousSessionId] ?? createHistoryMessagePaginationState();
|
|
329
|
+
delete nextHistoryMessagePaginationBySession[previousSessionId];
|
|
330
|
+
}
|
|
269
331
|
const nextActiveSessionId = state.activeSessionId === previousSessionId ? nextSessionId : state.activeSessionId;
|
|
270
332
|
set({
|
|
271
333
|
sessions: nextSessions,
|
|
@@ -274,6 +336,9 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
274
336
|
isStreamingBySession: nextIsStreamingBySession,
|
|
275
337
|
isStoppingBySession: nextIsStoppingBySession,
|
|
276
338
|
errorBySession: nextErrorBySession,
|
|
339
|
+
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
340
|
+
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
341
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
277
342
|
activeSessionId: nextActiveSessionId
|
|
278
343
|
});
|
|
279
344
|
},
|
|
@@ -287,6 +352,61 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
287
352
|
);
|
|
288
353
|
set({ sessions: nextSessions });
|
|
289
354
|
},
|
|
355
|
+
hydrateHistorySessions: (sessions) => {
|
|
356
|
+
const state = get();
|
|
357
|
+
const localSessions = state.sessions.filter(
|
|
358
|
+
(session) => isDraftChatSessionId(session.sessionId)
|
|
359
|
+
);
|
|
360
|
+
const localSessionIds = new Set(localSessions.map((session) => session.sessionId));
|
|
361
|
+
const nextSessions = [
|
|
362
|
+
...localSessions,
|
|
363
|
+
...sessions.filter((session) => !localSessionIds.has(session.sessionId)).map((session) => ({
|
|
364
|
+
...session,
|
|
365
|
+
mode: session.mode ?? DEFAULT_CHAT_AGENT_MODE
|
|
366
|
+
}))
|
|
367
|
+
];
|
|
368
|
+
const nextMessagesBySession = { ...state.messagesBySession };
|
|
369
|
+
const nextErrorBySession = { ...state.errorBySession };
|
|
370
|
+
const nextIsStreamingBySession = { ...state.isStreamingBySession };
|
|
371
|
+
const nextIsStoppingBySession = { ...state.isStoppingBySession };
|
|
372
|
+
const nextSessionMessageLoadStatusBySession = {
|
|
373
|
+
...state.sessionMessageLoadStatusBySession
|
|
374
|
+
};
|
|
375
|
+
const nextSessionMessageLoadErrorBySession = {
|
|
376
|
+
...state.sessionMessageLoadErrorBySession
|
|
377
|
+
};
|
|
378
|
+
const nextHistoryMessagePaginationBySession = {
|
|
379
|
+
...state.historyMessagePaginationBySession
|
|
380
|
+
};
|
|
381
|
+
nextSessions.forEach((session) => {
|
|
382
|
+
const sid = session.sessionId;
|
|
383
|
+
if (nextErrorBySession[sid] === void 0)
|
|
384
|
+
nextErrorBySession[sid] = null;
|
|
385
|
+
if (nextIsStreamingBySession[sid] === void 0)
|
|
386
|
+
nextIsStreamingBySession[sid] = false;
|
|
387
|
+
if (nextIsStoppingBySession[sid] === void 0)
|
|
388
|
+
nextIsStoppingBySession[sid] = false;
|
|
389
|
+
if (nextSessionMessageLoadStatusBySession[sid] === void 0) {
|
|
390
|
+
nextSessionMessageLoadStatusBySession[sid] = "idle";
|
|
391
|
+
}
|
|
392
|
+
if (nextSessionMessageLoadErrorBySession[sid] === void 0) {
|
|
393
|
+
nextSessionMessageLoadErrorBySession[sid] = null;
|
|
394
|
+
}
|
|
395
|
+
if (nextHistoryMessagePaginationBySession[sid] === void 0) {
|
|
396
|
+
nextHistoryMessagePaginationBySession[sid] = createHistoryMessagePaginationState();
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
set({
|
|
400
|
+
sessions: nextSessions,
|
|
401
|
+
messagesBySession: nextMessagesBySession,
|
|
402
|
+
errorBySession: nextErrorBySession,
|
|
403
|
+
isStreamingBySession: nextIsStreamingBySession,
|
|
404
|
+
isStoppingBySession: nextIsStoppingBySession,
|
|
405
|
+
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
406
|
+
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
407
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
408
|
+
});
|
|
409
|
+
},
|
|
290
410
|
// ---- Message operations ------------------------------------------------
|
|
291
411
|
appendMessage: (sessionId, message) => {
|
|
292
412
|
const state = get();
|
|
@@ -313,6 +433,92 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
313
433
|
isStreamingBySession: nextIsStreamingBySession
|
|
314
434
|
});
|
|
315
435
|
},
|
|
436
|
+
hydrateHistorySessionMessages: (sessionId, messages) => {
|
|
437
|
+
const state = get();
|
|
438
|
+
set({
|
|
439
|
+
messagesBySession: {
|
|
440
|
+
...state.messagesBySession,
|
|
441
|
+
[sessionId]: normalizeHistoryMessages(sessionId, messages)
|
|
442
|
+
},
|
|
443
|
+
sessionMessageLoadStatusBySession: {
|
|
444
|
+
...state.sessionMessageLoadStatusBySession,
|
|
445
|
+
[sessionId]: "loaded"
|
|
446
|
+
},
|
|
447
|
+
sessionMessageLoadErrorBySession: {
|
|
448
|
+
...state.sessionMessageLoadErrorBySession,
|
|
449
|
+
[sessionId]: null
|
|
450
|
+
},
|
|
451
|
+
historyMessagePaginationBySession: {
|
|
452
|
+
...state.historyMessagePaginationBySession,
|
|
453
|
+
[sessionId]: createHistoryMessagePaginationState()
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
hydrateHistorySessionMessagesPage: (sessionId, page) => {
|
|
458
|
+
const state = get();
|
|
459
|
+
set({
|
|
460
|
+
messagesBySession: {
|
|
461
|
+
...state.messagesBySession,
|
|
462
|
+
[sessionId]: normalizeHistoryMessages(sessionId, page.messages)
|
|
463
|
+
},
|
|
464
|
+
sessionMessageLoadStatusBySession: {
|
|
465
|
+
...state.sessionMessageLoadStatusBySession,
|
|
466
|
+
[sessionId]: "loaded"
|
|
467
|
+
},
|
|
468
|
+
sessionMessageLoadErrorBySession: {
|
|
469
|
+
...state.sessionMessageLoadErrorBySession,
|
|
470
|
+
[sessionId]: null
|
|
471
|
+
},
|
|
472
|
+
historyMessagePaginationBySession: {
|
|
473
|
+
...state.historyMessagePaginationBySession,
|
|
474
|
+
[sessionId]: createHistoryMessagePaginationState(page)
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
},
|
|
478
|
+
prependHistorySessionMessagesPage: (sessionId, page) => {
|
|
479
|
+
const state = get();
|
|
480
|
+
set({
|
|
481
|
+
messagesBySession: {
|
|
482
|
+
...state.messagesBySession,
|
|
483
|
+
[sessionId]: mergeOlderHistoryMessages(
|
|
484
|
+
sessionId,
|
|
485
|
+
page.messages,
|
|
486
|
+
state.messagesBySession[sessionId] ?? []
|
|
487
|
+
)
|
|
488
|
+
},
|
|
489
|
+
historyMessagePaginationBySession: {
|
|
490
|
+
...state.historyMessagePaginationBySession,
|
|
491
|
+
[sessionId]: createHistoryMessagePaginationState(page)
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
},
|
|
495
|
+
setHistorySessionPreviousMessagesLoadStatus: (sessionId, isLoading, error2 = null) => {
|
|
496
|
+
const state = get();
|
|
497
|
+
const current = state.historyMessagePaginationBySession[sessionId] ?? createHistoryMessagePaginationState();
|
|
498
|
+
set({
|
|
499
|
+
historyMessagePaginationBySession: {
|
|
500
|
+
...state.historyMessagePaginationBySession,
|
|
501
|
+
[sessionId]: {
|
|
502
|
+
...current,
|
|
503
|
+
isLoadingPrevious: isLoading,
|
|
504
|
+
error: error2
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
},
|
|
509
|
+
setHistorySessionMessageLoadStatus: (sessionId, status, error2 = null) => {
|
|
510
|
+
const state = get();
|
|
511
|
+
set({
|
|
512
|
+
sessionMessageLoadStatusBySession: {
|
|
513
|
+
...state.sessionMessageLoadStatusBySession,
|
|
514
|
+
[sessionId]: status
|
|
515
|
+
},
|
|
516
|
+
sessionMessageLoadErrorBySession: {
|
|
517
|
+
...state.sessionMessageLoadErrorBySession,
|
|
518
|
+
[sessionId]: error2
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
},
|
|
316
522
|
startStreamingMessage: (sessionId, message) => {
|
|
317
523
|
const state = get();
|
|
318
524
|
set({
|
|
@@ -760,6 +966,10 @@ var AiChatProvider = (props) => {
|
|
|
760
966
|
handleQuestionnaireSubmit,
|
|
761
967
|
handleConfirmationSubmit,
|
|
762
968
|
messageRenderOrder,
|
|
969
|
+
historySessionList,
|
|
970
|
+
onLoadMoreSessions,
|
|
971
|
+
onSelectHistorySession,
|
|
972
|
+
onLoadMoreHistoryMessages,
|
|
763
973
|
enableImageAttachments = true,
|
|
764
974
|
children
|
|
765
975
|
} = props;
|
|
@@ -836,7 +1046,11 @@ var AiChatProvider = (props) => {
|
|
|
836
1046
|
handleConfirmationSubmit,
|
|
837
1047
|
messageRenderOrder,
|
|
838
1048
|
transformStreamPacket: defaultTransformStreamPacket,
|
|
839
|
-
enableImageAttachments
|
|
1049
|
+
enableImageAttachments,
|
|
1050
|
+
historySessionList,
|
|
1051
|
+
onLoadMoreSessions,
|
|
1052
|
+
onSelectHistorySession,
|
|
1053
|
+
onLoadMoreHistoryMessages
|
|
840
1054
|
}),
|
|
841
1055
|
[
|
|
842
1056
|
axiosInstance,
|
|
@@ -846,8 +1060,12 @@ var AiChatProvider = (props) => {
|
|
|
846
1060
|
enableImageAttachments,
|
|
847
1061
|
handleConfirmationSubmit,
|
|
848
1062
|
handleQuestionnaireSubmit,
|
|
1063
|
+
historySessionList,
|
|
849
1064
|
labels,
|
|
850
1065
|
messageRenderOrder,
|
|
1066
|
+
onLoadMoreSessions,
|
|
1067
|
+
onLoadMoreHistoryMessages,
|
|
1068
|
+
onSelectHistorySession,
|
|
851
1069
|
renderMessageBlock,
|
|
852
1070
|
sendRef,
|
|
853
1071
|
retryRef,
|
|
@@ -3163,15 +3381,11 @@ var Bubble = styled7.article`
|
|
|
3163
3381
|
|
|
3164
3382
|
&[data-role='user'] {
|
|
3165
3383
|
width: auto;
|
|
3166
|
-
max-width:
|
|
3384
|
+
max-width: 100%;
|
|
3167
3385
|
margin-left: auto;
|
|
3168
|
-
padding:
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
border: 1px solid rgba(255, 255, 255, 0.07);
|
|
3172
|
-
box-shadow:
|
|
3173
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.03),
|
|
3174
|
-
0 12px 30px rgba(0, 0, 0, 0.18);
|
|
3386
|
+
padding: 8px 12px;
|
|
3387
|
+
background: #282825;
|
|
3388
|
+
border-radius: 16px;
|
|
3175
3389
|
}
|
|
3176
3390
|
`;
|
|
3177
3391
|
var Header2 = styled7.div`
|
|
@@ -3503,6 +3717,7 @@ var HeroSubtitle = styled8.p`
|
|
|
3503
3717
|
// src/components/chat-thread/index.tsx
|
|
3504
3718
|
import { jsx as jsx10, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
|
|
3505
3719
|
var CHAT_THREAD_PINNED_THRESHOLD_PX = 32;
|
|
3720
|
+
var CHAT_THREAD_LOAD_PREVIOUS_THRESHOLD_PX = 80;
|
|
3506
3721
|
var isThreadPinnedToBottom = (container) => container.scrollHeight - container.clientHeight - container.scrollTop <= CHAT_THREAD_PINNED_THRESHOLD_PX;
|
|
3507
3722
|
var renderChatMessage = ({
|
|
3508
3723
|
message,
|
|
@@ -3576,9 +3791,13 @@ var ChatThreadView = ({
|
|
|
3576
3791
|
historyMessages,
|
|
3577
3792
|
streamingMessage,
|
|
3578
3793
|
error: error2,
|
|
3794
|
+
isLoadingPreviousMessages = false,
|
|
3795
|
+
previousMessagesError,
|
|
3579
3796
|
retryButtonLabel,
|
|
3580
3797
|
scrollToLatestLabel,
|
|
3798
|
+
sessionHistoryLoadingLabel,
|
|
3581
3799
|
onRetry,
|
|
3800
|
+
onLoadPreviousMessages,
|
|
3582
3801
|
onConfirmationSubmit,
|
|
3583
3802
|
onQuestionnaireSubmit,
|
|
3584
3803
|
renderMessageBlock
|
|
@@ -3593,6 +3812,7 @@ var ChatThreadView = ({
|
|
|
3593
3812
|
const latestHistoryMessage = historyMessages[historyMessages.length - 1];
|
|
3594
3813
|
const latestTurnRef = useRef5(null);
|
|
3595
3814
|
const reservedSpaceFrameRef = useRef5(null);
|
|
3815
|
+
const isLoadingPreviousRef = useRef5(false);
|
|
3596
3816
|
const isPinnedRef = useRef5(true);
|
|
3597
3817
|
const lastHistoryMessageIdRef = useRef5(latestHistoryMessage?.id);
|
|
3598
3818
|
const lastStreamingMessageIdRef = useRef5(streamingMessage?.id);
|
|
@@ -3639,17 +3859,45 @@ var ChatThreadView = ({
|
|
|
3639
3859
|
},
|
|
3640
3860
|
[markThreadPinned, scrollToBottom]
|
|
3641
3861
|
);
|
|
3862
|
+
const handleLoadPreviousMessages = useCallback3(async () => {
|
|
3863
|
+
const container = containerRef.current;
|
|
3864
|
+
if (!container || !onLoadPreviousMessages || isLoadingPreviousMessages) {
|
|
3865
|
+
return;
|
|
3866
|
+
}
|
|
3867
|
+
if (isLoadingPreviousRef.current) {
|
|
3868
|
+
return;
|
|
3869
|
+
}
|
|
3870
|
+
isLoadingPreviousRef.current = true;
|
|
3871
|
+
const previousScrollHeight = container.scrollHeight;
|
|
3872
|
+
const previousScrollTop = container.scrollTop;
|
|
3873
|
+
try {
|
|
3874
|
+
await onLoadPreviousMessages();
|
|
3875
|
+
} catch {
|
|
3876
|
+
return;
|
|
3877
|
+
} finally {
|
|
3878
|
+
isLoadingPreviousRef.current = false;
|
|
3879
|
+
}
|
|
3880
|
+
window.requestAnimationFrame(() => {
|
|
3881
|
+
const nextContainer = containerRef.current;
|
|
3882
|
+
if (!nextContainer)
|
|
3883
|
+
return;
|
|
3884
|
+
nextContainer.scrollTop = nextContainer.scrollHeight - previousScrollHeight + previousScrollTop;
|
|
3885
|
+
});
|
|
3886
|
+
}, [isLoadingPreviousMessages, onLoadPreviousMessages]);
|
|
3642
3887
|
const handleContainerScroll = useCallback3(() => {
|
|
3643
3888
|
const container = containerRef.current;
|
|
3644
3889
|
if (!container)
|
|
3645
3890
|
return;
|
|
3891
|
+
if (onLoadPreviousMessages && container.scrollTop <= CHAT_THREAD_LOAD_PREVIOUS_THRESHOLD_PX) {
|
|
3892
|
+
void handleLoadPreviousMessages();
|
|
3893
|
+
}
|
|
3646
3894
|
const nextPinned = isThreadPinnedToBottom(container);
|
|
3647
3895
|
isPinnedRef.current = nextPinned;
|
|
3648
3896
|
setIsDetached(!nextPinned);
|
|
3649
3897
|
if (nextPinned) {
|
|
3650
3898
|
setPendingNewMessageCount(0);
|
|
3651
3899
|
}
|
|
3652
|
-
}, []);
|
|
3900
|
+
}, [handleLoadPreviousMessages, onLoadPreviousMessages]);
|
|
3653
3901
|
useLayoutEffect3(() => {
|
|
3654
3902
|
const nextHistoryMessageId = latestHistoryMessage?.id;
|
|
3655
3903
|
if (lastHistoryMessageIdRef.current === nextHistoryMessageId) {
|
|
@@ -3777,6 +4025,8 @@ var ChatThreadView = ({
|
|
|
3777
4025
|
}, [latestTurn, scrollToBottom]);
|
|
3778
4026
|
return /* @__PURE__ */ jsxs7(ThreadViewport, { children: [
|
|
3779
4027
|
/* @__PURE__ */ jsxs7(Container, { ref: containerRef, "data-testid": "chat-thread", onScroll: handleContainerScroll, children: [
|
|
4028
|
+
isLoadingPreviousMessages ? /* @__PURE__ */ jsx10(PreviousMessagesStateRow, { "data-testid": "chat-thread-loading-previous", children: sessionHistoryLoadingLabel }) : null,
|
|
4029
|
+
previousMessagesError ? /* @__PURE__ */ jsx10(PreviousMessagesStateRow, { "data-testid": "chat-thread-load-previous-error", children: previousMessagesError }) : null,
|
|
3780
4030
|
conversationTurns.map((turn, turnIndex) => {
|
|
3781
4031
|
const isLatestTurn = turnIndex === conversationTurns.length - 1;
|
|
3782
4032
|
return /* @__PURE__ */ jsxs7(
|
|
@@ -3833,14 +4083,25 @@ var EMPTY_MESSAGES = [];
|
|
|
3833
4083
|
var ChatThread = () => {
|
|
3834
4084
|
const activeSessionId = useChatStore((s) => s.activeSessionId);
|
|
3835
4085
|
const hasSessions = useChatStore((s) => s.sessions.length > 0);
|
|
3836
|
-
const
|
|
3837
|
-
(s) => s.sessions.find((
|
|
4086
|
+
const activeSession = useChatStore(
|
|
4087
|
+
(s) => s.sessions.find((session) => session.sessionId === s.activeSessionId)
|
|
3838
4088
|
);
|
|
4089
|
+
const activeSessionMode = activeSession?.mode ?? DEFAULT_CHAT_AGENT_MODE;
|
|
3839
4090
|
const messages = useChatStore(
|
|
3840
4091
|
(s) => s.messagesBySession[s.activeSessionId ?? ""] ?? EMPTY_MESSAGES
|
|
3841
4092
|
);
|
|
4093
|
+
const sessionMessageLoadStatus = useChatStore(
|
|
4094
|
+
(s) => s.sessionMessageLoadStatusBySession[s.activeSessionId ?? ""]
|
|
4095
|
+
);
|
|
3842
4096
|
const streamingMessage = useChatStore((s) => s.streamingMessageBySession[s.activeSessionId ?? ""]);
|
|
3843
4097
|
const error2 = useChatStore((s) => s.errorBySession[s.activeSessionId ?? ""]);
|
|
4098
|
+
const historyMessagePagination = useChatStore(
|
|
4099
|
+
(s) => s.historyMessagePaginationBySession[s.activeSessionId ?? ""]
|
|
4100
|
+
);
|
|
4101
|
+
const prependHistorySessionMessagesPage = useChatStore((s) => s.prependHistorySessionMessagesPage);
|
|
4102
|
+
const setHistorySessionPreviousMessagesLoadStatus = useChatStore(
|
|
4103
|
+
(s) => s.setHistorySessionPreviousMessagesLoadStatus
|
|
4104
|
+
);
|
|
3844
4105
|
const updateQA = useChatStore((s) => s.updateQuestionnaireAnswers);
|
|
3845
4106
|
const clearSessionError = useChatStore((s) => s.clearSessionError);
|
|
3846
4107
|
const {
|
|
@@ -3849,6 +4110,7 @@ var ChatThread = () => {
|
|
|
3849
4110
|
renderMessageBlock,
|
|
3850
4111
|
handleQuestionnaireSubmit: customQuestionnaireSubmit,
|
|
3851
4112
|
handleConfirmationSubmit: customConfirmationSubmit,
|
|
4113
|
+
onLoadMoreHistoryMessages,
|
|
3852
4114
|
labels
|
|
3853
4115
|
} = useChatContext();
|
|
3854
4116
|
const handleRetry = useCallback3(() => {
|
|
@@ -3911,6 +4173,42 @@ var ChatThread = () => {
|
|
|
3911
4173
|
},
|
|
3912
4174
|
[activeSessionId, activeSessionMode, sendRef, customConfirmationSubmit]
|
|
3913
4175
|
);
|
|
4176
|
+
const handleLoadPreviousMessages = useCallback3(async () => {
|
|
4177
|
+
if (!activeSession || !onLoadMoreHistoryMessages || !historyMessagePagination?.hasMorePrevious || !historyMessagePagination.previousCursor || historyMessagePagination.isLoadingPrevious) {
|
|
4178
|
+
return;
|
|
4179
|
+
}
|
|
4180
|
+
setHistorySessionPreviousMessagesLoadStatus(activeSession.sessionId, true);
|
|
4181
|
+
try {
|
|
4182
|
+
const page = await onLoadMoreHistoryMessages({
|
|
4183
|
+
session: activeSession,
|
|
4184
|
+
cursor: historyMessagePagination.previousCursor
|
|
4185
|
+
});
|
|
4186
|
+
if (page) {
|
|
4187
|
+
prependHistorySessionMessagesPage(activeSession.sessionId, page);
|
|
4188
|
+
return;
|
|
4189
|
+
}
|
|
4190
|
+
setHistorySessionPreviousMessagesLoadStatus(activeSession.sessionId, false);
|
|
4191
|
+
} catch (error3) {
|
|
4192
|
+
setHistorySessionPreviousMessagesLoadStatus(
|
|
4193
|
+
activeSession.sessionId,
|
|
4194
|
+
false,
|
|
4195
|
+
error3 instanceof Error ? error3.message : String(error3)
|
|
4196
|
+
);
|
|
4197
|
+
throw error3;
|
|
4198
|
+
}
|
|
4199
|
+
}, [
|
|
4200
|
+
activeSession,
|
|
4201
|
+
historyMessagePagination,
|
|
4202
|
+
onLoadMoreHistoryMessages,
|
|
4203
|
+
prependHistorySessionMessagesPage,
|
|
4204
|
+
setHistorySessionPreviousMessagesLoadStatus
|
|
4205
|
+
]);
|
|
4206
|
+
const canLoadPreviousMessages = Boolean(
|
|
4207
|
+
activeSession && onLoadMoreHistoryMessages && historyMessagePagination?.hasMorePrevious && historyMessagePagination.previousCursor && !historyMessagePagination.isLoadingPrevious
|
|
4208
|
+
);
|
|
4209
|
+
if (hasSessions && sessionMessageLoadStatus === "loading" && messages.length === 0 && !streamingMessage) {
|
|
4210
|
+
return /* @__PURE__ */ jsx10(ThreadStateViewport, { "data-testid": "chat-thread-loading-state", children: /* @__PURE__ */ jsx10(ThreadStateText, { children: labels.sessionHistoryLoading }) });
|
|
4211
|
+
}
|
|
3914
4212
|
if (!hasSessions || messages.length === 0 && !streamingMessage) {
|
|
3915
4213
|
return /* @__PURE__ */ jsx10(ChatThreadEmptyState, {});
|
|
3916
4214
|
}
|
|
@@ -3921,9 +4219,13 @@ var ChatThread = () => {
|
|
|
3921
4219
|
historyMessages: messages,
|
|
3922
4220
|
streamingMessage,
|
|
3923
4221
|
error: error2,
|
|
4222
|
+
isLoadingPreviousMessages: historyMessagePagination?.isLoadingPrevious,
|
|
4223
|
+
previousMessagesError: historyMessagePagination?.error,
|
|
3924
4224
|
retryButtonLabel: labels.retryButton,
|
|
3925
4225
|
scrollToLatestLabel: labels.scrollToLatest,
|
|
4226
|
+
sessionHistoryLoadingLabel: labels.sessionHistoryLoading,
|
|
3926
4227
|
onRetry: handleRetry,
|
|
4228
|
+
onLoadPreviousMessages: canLoadPreviousMessages ? handleLoadPreviousMessages : void 0,
|
|
3927
4229
|
onConfirmationSubmit: handleConfirmation,
|
|
3928
4230
|
onQuestionnaireSubmit: handleQuestionnaireSubmit,
|
|
3929
4231
|
renderMessageBlock
|
|
@@ -3937,6 +4239,18 @@ var ThreadViewport = styled9.div`
|
|
|
3937
4239
|
flex: 1;
|
|
3938
4240
|
min-height: 0;
|
|
3939
4241
|
`;
|
|
4242
|
+
var ThreadStateViewport = styled9.div`
|
|
4243
|
+
display: flex;
|
|
4244
|
+
flex: 1;
|
|
4245
|
+
min-height: 0;
|
|
4246
|
+
align-items: center;
|
|
4247
|
+
justify-content: center;
|
|
4248
|
+
padding: 24px;
|
|
4249
|
+
`;
|
|
4250
|
+
var ThreadStateText = styled9.div`
|
|
4251
|
+
color: var(--text-secondary, rgba(255, 255, 255, 0.64));
|
|
4252
|
+
font-size: 14px;
|
|
4253
|
+
`;
|
|
3940
4254
|
var Container = styled9.div`
|
|
3941
4255
|
display: flex;
|
|
3942
4256
|
flex: 1;
|
|
@@ -3944,7 +4258,7 @@ var Container = styled9.div`
|
|
|
3944
4258
|
gap: 18px;
|
|
3945
4259
|
min-height: 0;
|
|
3946
4260
|
overflow: auto;
|
|
3947
|
-
padding: 24px
|
|
4261
|
+
padding: 24px 16px 88px;
|
|
3948
4262
|
overscroll-behavior: contain;
|
|
3949
4263
|
|
|
3950
4264
|
&::-webkit-scrollbar {
|
|
@@ -3963,10 +4277,23 @@ var Container = styled9.div`
|
|
|
3963
4277
|
var MessageSlot = styled9.div`
|
|
3964
4278
|
display: flex;
|
|
3965
4279
|
`;
|
|
4280
|
+
var PreviousMessagesStateRow = styled9.div`
|
|
4281
|
+
width: 100%;
|
|
4282
|
+
max-width: var(--chat-content-max-width, 48rem);
|
|
4283
|
+
margin-right: auto;
|
|
4284
|
+
margin-left: auto;
|
|
4285
|
+
color: var(--text-secondary, rgba(255, 255, 255, 0.64));
|
|
4286
|
+
font-size: 13px;
|
|
4287
|
+
text-align: center;
|
|
4288
|
+
`;
|
|
3966
4289
|
var ConversationTurn = styled9.div`
|
|
3967
4290
|
display: flex;
|
|
3968
4291
|
flex-direction: column;
|
|
3969
4292
|
gap: 18px;
|
|
4293
|
+
width: 100%;
|
|
4294
|
+
max-width: var(--chat-content-max-width, 48rem);
|
|
4295
|
+
margin-right: auto;
|
|
4296
|
+
margin-left: auto;
|
|
3970
4297
|
`;
|
|
3971
4298
|
var ErrorText = styled9.div`
|
|
3972
4299
|
color: #ff7b72;
|
|
@@ -7754,7 +8081,7 @@ var PrimaryButton = styled13(Button)`
|
|
|
7754
8081
|
min-width: 24px;
|
|
7755
8082
|
width: 24px;
|
|
7756
8083
|
height: 24px;
|
|
7757
|
-
background: ${({ $canSend }) => $canSend ? "#fcfbf8" : "rgba(
|
|
8084
|
+
background: ${({ $canSend }) => $canSend ? "#fcfbf8" : "rgba(252,251,248,0.3);"};
|
|
7758
8085
|
color: ${({ $canSend }) => $canSend ? "#5b5448" : "rgba(255, 255, 255, 0.72)"};
|
|
7759
8086
|
border-radius: 12px;
|
|
7760
8087
|
border: 1px solid ${({ $canSend }) => $canSend ? "rgba(198, 188, 170, 0.38)" : "transparent"};
|
|
@@ -7765,7 +8092,7 @@ var PrimaryButton = styled13(Button)`
|
|
|
7765
8092
|
}
|
|
7766
8093
|
|
|
7767
8094
|
&:hover:not(:disabled) {
|
|
7768
|
-
background: ${({ $canSend }) => $canSend ? "#f7f4ec" : "rgba(
|
|
8095
|
+
background: ${({ $canSend }) => $canSend ? "#f7f4ec" : "rgba(252,251,248,0.3);"};
|
|
7769
8096
|
color: ${({ $canSend }) => $canSend ? "#4f493f" : "rgba(255, 255, 255, 0.72)"};
|
|
7770
8097
|
border-color: ${({ $canSend }) => $canSend ? "rgba(198, 188, 170, 0.46)" : "transparent"};
|
|
7771
8098
|
}
|
|
@@ -7833,7 +8160,7 @@ var StopSpinner = styled13.span`
|
|
|
7833
8160
|
import { jsx as jsx16, jsxs as jsxs11 } from "@emotion/react/jsx-runtime";
|
|
7834
8161
|
var CHAT_COMPOSER_LINE_HEIGHT_PX = 20;
|
|
7835
8162
|
var CHAT_COMPOSER_MAX_ROWS = 7;
|
|
7836
|
-
var CHAT_COMPOSER_PADDING_TOP_PX =
|
|
8163
|
+
var CHAT_COMPOSER_PADDING_TOP_PX = 12;
|
|
7837
8164
|
var CHAT_COMPOSER_PADDING_BOTTOM_PX = 12;
|
|
7838
8165
|
var CHAT_COMPOSER_PADDING_BLOCK_PX = CHAT_COMPOSER_PADDING_TOP_PX + CHAT_COMPOSER_PADDING_BOTTOM_PX;
|
|
7839
8166
|
var CHAT_COMPOSER_MIN_ROWS = 4;
|
|
@@ -8068,6 +8395,10 @@ var ChatComposerView = ({
|
|
|
8068
8395
|
setActiveSkillNavigation({ queryKey: "", index: 0 });
|
|
8069
8396
|
};
|
|
8070
8397
|
const handleKeyDown = (event) => {
|
|
8398
|
+
const isImeComposing = event.nativeEvent.isComposing || event.keyCode === 229;
|
|
8399
|
+
if (event.key === "Enter" && isImeComposing) {
|
|
8400
|
+
return;
|
|
8401
|
+
}
|
|
8071
8402
|
if (skillQueryMatch) {
|
|
8072
8403
|
if (event.key === "ArrowDown" && filteredSkills.length > 0) {
|
|
8073
8404
|
event.preventDefault();
|
|
@@ -8345,7 +8676,7 @@ var Surface = styled14.div`
|
|
|
8345
8676
|
'input'
|
|
8346
8677
|
'footer';
|
|
8347
8678
|
width: 100%;
|
|
8348
|
-
max-width:
|
|
8679
|
+
max-width: var(--chat-content-max-width, 48rem);
|
|
8349
8680
|
margin: 0 auto;
|
|
8350
8681
|
background: var(--border-color);
|
|
8351
8682
|
border-radius: 20px;
|
|
@@ -8606,6 +8937,7 @@ var SkillButton = styled14.button`
|
|
|
8606
8937
|
`;
|
|
8607
8938
|
|
|
8608
8939
|
// src/components/chat-conversation-list/index.tsx
|
|
8940
|
+
import { useEffect as useEffect10, useMemo as useMemo7, useRef as useRef12 } from "react";
|
|
8609
8941
|
import styled16 from "@emotion/styled";
|
|
8610
8942
|
|
|
8611
8943
|
// src/components/chat-conversation-list/components/chat-session-item.tsx
|
|
@@ -8619,6 +8951,7 @@ var ChatSessionItem = memo2(
|
|
|
8619
8951
|
{
|
|
8620
8952
|
type: "button",
|
|
8621
8953
|
"data-active": isActive,
|
|
8954
|
+
"data-testid": `chat-session-item-${session.sessionId}`,
|
|
8622
8955
|
onClick: () => onClick(session.sessionId),
|
|
8623
8956
|
children: /* @__PURE__ */ jsxs12(SessionMeta, { children: [
|
|
8624
8957
|
/* @__PURE__ */ jsx17(SessionTitle, { children: session.title }),
|
|
@@ -8666,14 +8999,130 @@ var ModeBadge = styled15.span`
|
|
|
8666
8999
|
background: rgba(255, 255, 255, 0.04);
|
|
8667
9000
|
`;
|
|
8668
9001
|
|
|
9002
|
+
// src/components/chat-conversation-list/lib/history-session-selection.ts
|
|
9003
|
+
var shouldLoadHistorySessionMessages = ({
|
|
9004
|
+
sessionId,
|
|
9005
|
+
messagesBySession,
|
|
9006
|
+
loadStatusBySession,
|
|
9007
|
+
isStreamingBySession
|
|
9008
|
+
}) => {
|
|
9009
|
+
if (isStreamingBySession[sessionId])
|
|
9010
|
+
return false;
|
|
9011
|
+
if (loadStatusBySession[sessionId] === "loading")
|
|
9012
|
+
return false;
|
|
9013
|
+
if (loadStatusBySession[sessionId] === "error")
|
|
9014
|
+
return true;
|
|
9015
|
+
if (loadStatusBySession[sessionId] === "loaded")
|
|
9016
|
+
return false;
|
|
9017
|
+
return messagesBySession[sessionId] === void 0;
|
|
9018
|
+
};
|
|
9019
|
+
|
|
8669
9020
|
// src/components/chat-conversation-list/index.tsx
|
|
8670
9021
|
import { jsx as jsx18, jsxs as jsxs13 } from "@emotion/react/jsx-runtime";
|
|
9022
|
+
var SCROLL_LOAD_MORE_THRESHOLD_PX = 80;
|
|
9023
|
+
var shouldLoadMoreSessions = ({
|
|
9024
|
+
scrollTop,
|
|
9025
|
+
clientHeight,
|
|
9026
|
+
scrollHeight,
|
|
9027
|
+
threshold = SCROLL_LOAD_MORE_THRESHOLD_PX
|
|
9028
|
+
}) => scrollHeight - scrollTop - clientHeight <= threshold;
|
|
9029
|
+
var isHistorySessionMessagesPage = (value) => typeof value === "object" && value !== null && Array.isArray(value.messages);
|
|
8671
9030
|
var ChatConversationList = () => {
|
|
8672
|
-
const { labels } = useChatContext();
|
|
8673
|
-
const
|
|
9031
|
+
const { labels, historySessionList, onLoadMoreSessions, onSelectHistorySession, store } = useChatContext();
|
|
9032
|
+
const localSessions = useChatStore((s) => s.sessions);
|
|
8674
9033
|
const activeSessionId = useChatStore((s) => s.activeSessionId);
|
|
8675
9034
|
const startNewChat = useChatStore((s) => s.startNewChat);
|
|
8676
9035
|
const setActiveSession = useChatStore((s) => s.setActiveSession);
|
|
9036
|
+
const hydrateHistorySessions = useChatStore((s) => s.hydrateHistorySessions);
|
|
9037
|
+
const hydrateHistorySessionMessages = useChatStore((s) => s.hydrateHistorySessionMessages);
|
|
9038
|
+
const hydrateHistorySessionMessagesPage = useChatStore((s) => s.hydrateHistorySessionMessagesPage);
|
|
9039
|
+
const setHistorySessionMessageLoadStatus = useChatStore(
|
|
9040
|
+
(s) => s.setHistorySessionMessageLoadStatus
|
|
9041
|
+
);
|
|
9042
|
+
const isLoadingMoreRef = useRef12(false);
|
|
9043
|
+
const hasSeenLoadingMoreRef = useRef12(false);
|
|
9044
|
+
useEffect10(() => {
|
|
9045
|
+
if (!historySessionList)
|
|
9046
|
+
return;
|
|
9047
|
+
hydrateHistorySessions(historySessionList.sessions);
|
|
9048
|
+
}, [historySessionList, hydrateHistorySessions]);
|
|
9049
|
+
useEffect10(() => {
|
|
9050
|
+
if (historySessionList?.isLoading) {
|
|
9051
|
+
hasSeenLoadingMoreRef.current = true;
|
|
9052
|
+
return;
|
|
9053
|
+
}
|
|
9054
|
+
if (hasSeenLoadingMoreRef.current) {
|
|
9055
|
+
hasSeenLoadingMoreRef.current = false;
|
|
9056
|
+
isLoadingMoreRef.current = false;
|
|
9057
|
+
}
|
|
9058
|
+
}, [historySessionList?.isLoading]);
|
|
9059
|
+
useEffect10(() => {
|
|
9060
|
+
isLoadingMoreRef.current = false;
|
|
9061
|
+
hasSeenLoadingMoreRef.current = false;
|
|
9062
|
+
}, [historySessionList?.sessions.length, historySessionList?.hasMore]);
|
|
9063
|
+
const sessions = useMemo7(() => {
|
|
9064
|
+
if (!historySessionList) {
|
|
9065
|
+
return localSessions;
|
|
9066
|
+
}
|
|
9067
|
+
const localSessionIds = new Set(localSessions.map((session) => session.sessionId));
|
|
9068
|
+
return [
|
|
9069
|
+
...localSessions,
|
|
9070
|
+
...historySessionList.sessions.filter((session) => !localSessionIds.has(session.sessionId))
|
|
9071
|
+
];
|
|
9072
|
+
}, [historySessionList, localSessions]);
|
|
9073
|
+
const handleSessionListScroll = (event) => {
|
|
9074
|
+
if (!historySessionList?.hasMore || historySessionList.isLoading || !onLoadMoreSessions || isLoadingMoreRef.current) {
|
|
9075
|
+
return;
|
|
9076
|
+
}
|
|
9077
|
+
const target = event.currentTarget;
|
|
9078
|
+
if (shouldLoadMoreSessions({
|
|
9079
|
+
scrollTop: target.scrollTop,
|
|
9080
|
+
clientHeight: target.clientHeight,
|
|
9081
|
+
scrollHeight: target.scrollHeight
|
|
9082
|
+
})) {
|
|
9083
|
+
isLoadingMoreRef.current = true;
|
|
9084
|
+
void Promise.resolve(onLoadMoreSessions()).catch(() => {
|
|
9085
|
+
isLoadingMoreRef.current = false;
|
|
9086
|
+
hasSeenLoadingMoreRef.current = false;
|
|
9087
|
+
});
|
|
9088
|
+
}
|
|
9089
|
+
};
|
|
9090
|
+
const handleSelectSession = async (sessionId) => {
|
|
9091
|
+
setActiveSession(sessionId);
|
|
9092
|
+
const session = sessions.find((item) => item.sessionId === sessionId);
|
|
9093
|
+
if (!session || !onSelectHistorySession) {
|
|
9094
|
+
return;
|
|
9095
|
+
}
|
|
9096
|
+
const state = store.getState();
|
|
9097
|
+
const shouldLoad = shouldLoadHistorySessionMessages({
|
|
9098
|
+
sessionId,
|
|
9099
|
+
messagesBySession: state.messagesBySession,
|
|
9100
|
+
loadStatusBySession: state.sessionMessageLoadStatusBySession,
|
|
9101
|
+
isStreamingBySession: state.isStreamingBySession
|
|
9102
|
+
});
|
|
9103
|
+
if (!shouldLoad) {
|
|
9104
|
+
return;
|
|
9105
|
+
}
|
|
9106
|
+
setHistorySessionMessageLoadStatus(sessionId, "loading");
|
|
9107
|
+
try {
|
|
9108
|
+
const result = await onSelectHistorySession(session);
|
|
9109
|
+
if (Array.isArray(result)) {
|
|
9110
|
+
hydrateHistorySessionMessages(sessionId, result);
|
|
9111
|
+
return;
|
|
9112
|
+
}
|
|
9113
|
+
if (isHistorySessionMessagesPage(result)) {
|
|
9114
|
+
hydrateHistorySessionMessagesPage(sessionId, result);
|
|
9115
|
+
return;
|
|
9116
|
+
}
|
|
9117
|
+
setHistorySessionMessageLoadStatus(sessionId, "loaded");
|
|
9118
|
+
} catch (error2) {
|
|
9119
|
+
setHistorySessionMessageLoadStatus(
|
|
9120
|
+
sessionId,
|
|
9121
|
+
"error",
|
|
9122
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
9123
|
+
);
|
|
9124
|
+
}
|
|
9125
|
+
};
|
|
8677
9126
|
const modeLabels = {
|
|
8678
9127
|
ask: labels.modeLabelAsk,
|
|
8679
9128
|
plan: labels.modeLabelPlan,
|
|
@@ -8684,16 +9133,21 @@ var ChatConversationList = () => {
|
|
|
8684
9133
|
/* @__PURE__ */ jsx18(Title3, { children: "Sessions" }),
|
|
8685
9134
|
/* @__PURE__ */ jsx18(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: startNewChat, children: labels.newChat })
|
|
8686
9135
|
] }),
|
|
8687
|
-
/* @__PURE__ */
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
9136
|
+
/* @__PURE__ */ jsxs13(List2, { "data-testid": "chat-session-list", onScroll: handleSessionListScroll, children: [
|
|
9137
|
+
sessions.map((session) => /* @__PURE__ */ jsx18(
|
|
9138
|
+
ChatSessionItem,
|
|
9139
|
+
{
|
|
9140
|
+
session,
|
|
9141
|
+
isActive: activeSessionId === session.sessionId,
|
|
9142
|
+
modeLabel: modeLabels[session.mode ?? DEFAULT_CHAT_AGENT_MODE] ?? "",
|
|
9143
|
+
onClick: (sessionId) => void handleSelectSession(sessionId)
|
|
9144
|
+
},
|
|
9145
|
+
session.sessionId
|
|
9146
|
+
)),
|
|
9147
|
+
historySessionList?.isLoading ? /* @__PURE__ */ jsx18(StateRow, { "data-testid": "chat-session-history-loading", children: labels.sessionHistoryLoading }) : null,
|
|
9148
|
+
historySessionList?.error ? /* @__PURE__ */ jsx18(StateRow, { "data-testid": "chat-session-history-error", children: historySessionList.error || labels.sessionHistoryLoadFailed }) : null,
|
|
9149
|
+
historySessionList && !historySessionList.isLoading && !historySessionList.error && sessions.length === 0 ? /* @__PURE__ */ jsx18(StateRow, { "data-testid": "chat-session-history-empty", children: labels.sessionHistoryEmpty }) : null
|
|
9150
|
+
] })
|
|
8697
9151
|
] });
|
|
8698
9152
|
};
|
|
8699
9153
|
var Container3 = styled16.aside`
|
|
@@ -8731,6 +9185,11 @@ var List2 = styled16.div`
|
|
|
8731
9185
|
gap: 8px;
|
|
8732
9186
|
overflow: auto;
|
|
8733
9187
|
`;
|
|
9188
|
+
var StateRow = styled16.div`
|
|
9189
|
+
padding: 12px;
|
|
9190
|
+
font-size: 13px;
|
|
9191
|
+
color: var(--text-secondary);
|
|
9192
|
+
`;
|
|
8734
9193
|
|
|
8735
9194
|
// src/components/ai-chat/index.tsx
|
|
8736
9195
|
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs14 } from "@emotion/react/jsx-runtime";
|
|
@@ -8792,7 +9251,7 @@ var AiChatWorkspaceContent = ({
|
|
|
8792
9251
|
})
|
|
8793
9252
|
);
|
|
8794
9253
|
const shouldShowComposerOnly = showComposerOnlyBeforeFirstMessage && !showConversationList && !isConversationStarted;
|
|
8795
|
-
|
|
9254
|
+
useEffect11(() => {
|
|
8796
9255
|
onConversationStartedChange?.(isConversationStarted);
|
|
8797
9256
|
}, [isConversationStarted, onConversationStartedChange]);
|
|
8798
9257
|
return /* @__PURE__ */ jsxs14(Root, { "data-testid": "ai-chat", children: [
|
|
@@ -8931,12 +9390,25 @@ var Root = styled17.div`
|
|
|
8931
9390
|
overflow: hidden;
|
|
8932
9391
|
`;
|
|
8933
9392
|
var Workspace = styled17.section`
|
|
9393
|
+
--chat-layout-rem: 16px;
|
|
9394
|
+
--chat-content-margin: calc(var(--chat-layout-rem) * 1);
|
|
9395
|
+
--chat-content-max-width: calc(var(--chat-layout-rem) * 40);
|
|
9396
|
+
|
|
8934
9397
|
flex: 1;
|
|
8935
9398
|
display: flex;
|
|
8936
9399
|
flex-direction: column;
|
|
8937
9400
|
gap: 12px;
|
|
8938
9401
|
min-height: 0;
|
|
8939
9402
|
overflow: hidden;
|
|
9403
|
+
|
|
9404
|
+
@media (min-width: 640px) {
|
|
9405
|
+
--chat-content-margin: calc(var(--chat-layout-rem) * 1.5);
|
|
9406
|
+
}
|
|
9407
|
+
|
|
9408
|
+
@media (min-width: 1024px) {
|
|
9409
|
+
--chat-content-margin: calc(var(--chat-layout-rem) * 4);
|
|
9410
|
+
--chat-content-max-width: calc(var(--chat-layout-rem) * 48);
|
|
9411
|
+
}
|
|
8940
9412
|
`;
|
|
8941
9413
|
var QuickActionsRow = styled17.div`
|
|
8942
9414
|
display: flex;
|