@xinghunm/ai-chat 1.4.2 → 1.4.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.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +111 -14
- package/dist/index.mjs +111 -14
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -738,6 +738,7 @@ interface ChatState {
|
|
|
738
738
|
sessionMessageLoadStatusBySession: Record<string, ChatSessionMessageLoadStatus>;
|
|
739
739
|
sessionMessageLoadErrorBySession: Record<string, string | null>;
|
|
740
740
|
historyMessagePaginationBySession: Record<string, ChatHistoryMessagePaginationState>;
|
|
741
|
+
timelineAnchorStateBySession: Record<string, Record<string, ChatTimelineAnchorStateSnapshot>>;
|
|
741
742
|
}
|
|
742
743
|
interface ChatHistoryMessagePaginationState {
|
|
743
744
|
previousCursor: string | null;
|
|
@@ -745,6 +746,11 @@ interface ChatHistoryMessagePaginationState {
|
|
|
745
746
|
isLoadingPrevious: boolean;
|
|
746
747
|
error: string | null;
|
|
747
748
|
}
|
|
749
|
+
interface ChatTimelineAnchorStateSnapshot {
|
|
750
|
+
previousBlockKeys: string[];
|
|
751
|
+
timelineBlockAnchors: Record<string, number>;
|
|
752
|
+
visibleTimelineBlockKeys: Record<string, true>;
|
|
753
|
+
}
|
|
748
754
|
interface ChatActions {
|
|
749
755
|
createSession: (session: ChatSession) => void;
|
|
750
756
|
startNewChat: () => void;
|
|
@@ -758,6 +764,7 @@ interface ChatActions {
|
|
|
758
764
|
prependHistorySessionMessagesPage: (sessionId: string, page: ChatHistorySessionMessagesPage) => void;
|
|
759
765
|
setHistorySessionPreviousMessagesLoadStatus: (sessionId: string, isLoading: boolean, error?: string | null) => void;
|
|
760
766
|
setHistorySessionMessageLoadStatus: (sessionId: string, status: ChatSessionMessageLoadStatus, error?: string | null) => void;
|
|
767
|
+
setTimelineAnchorState: (sessionId: string, messageId: string, snapshot: ChatTimelineAnchorStateSnapshot) => void;
|
|
761
768
|
startStreamingMessage: (sessionId: string, message: ChatMessage) => void;
|
|
762
769
|
updateStreamingMessage: (sessionId: string, content: string) => void;
|
|
763
770
|
patchStreamingMessage: (sessionId: string, patch: ChatStreamMessagePatch) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -738,6 +738,7 @@ interface ChatState {
|
|
|
738
738
|
sessionMessageLoadStatusBySession: Record<string, ChatSessionMessageLoadStatus>;
|
|
739
739
|
sessionMessageLoadErrorBySession: Record<string, string | null>;
|
|
740
740
|
historyMessagePaginationBySession: Record<string, ChatHistoryMessagePaginationState>;
|
|
741
|
+
timelineAnchorStateBySession: Record<string, Record<string, ChatTimelineAnchorStateSnapshot>>;
|
|
741
742
|
}
|
|
742
743
|
interface ChatHistoryMessagePaginationState {
|
|
743
744
|
previousCursor: string | null;
|
|
@@ -745,6 +746,11 @@ interface ChatHistoryMessagePaginationState {
|
|
|
745
746
|
isLoadingPrevious: boolean;
|
|
746
747
|
error: string | null;
|
|
747
748
|
}
|
|
749
|
+
interface ChatTimelineAnchorStateSnapshot {
|
|
750
|
+
previousBlockKeys: string[];
|
|
751
|
+
timelineBlockAnchors: Record<string, number>;
|
|
752
|
+
visibleTimelineBlockKeys: Record<string, true>;
|
|
753
|
+
}
|
|
748
754
|
interface ChatActions {
|
|
749
755
|
createSession: (session: ChatSession) => void;
|
|
750
756
|
startNewChat: () => void;
|
|
@@ -758,6 +764,7 @@ interface ChatActions {
|
|
|
758
764
|
prependHistorySessionMessagesPage: (sessionId: string, page: ChatHistorySessionMessagesPage) => void;
|
|
759
765
|
setHistorySessionPreviousMessagesLoadStatus: (sessionId: string, isLoading: boolean, error?: string | null) => void;
|
|
760
766
|
setHistorySessionMessageLoadStatus: (sessionId: string, status: ChatSessionMessageLoadStatus, error?: string | null) => void;
|
|
767
|
+
setTimelineAnchorState: (sessionId: string, messageId: string, snapshot: ChatTimelineAnchorStateSnapshot) => void;
|
|
761
768
|
startStreamingMessage: (sessionId: string, message: ChatMessage) => void;
|
|
762
769
|
updateStreamingMessage: (sessionId: string, content: string) => void;
|
|
763
770
|
patchStreamingMessage: (sessionId: string, patch: ChatStreamMessagePatch) => void;
|
package/dist/index.js
CHANGED
|
@@ -157,6 +157,18 @@ var resolveSessionTitleFromMessage = (message) => {
|
|
|
157
157
|
}
|
|
158
158
|
return DEFAULT_CHAT_SESSION_TITLE;
|
|
159
159
|
};
|
|
160
|
+
var areStringArraysEqual = (left, right) => left.length === right.length && left.every((value, index3) => value === right[index3]);
|
|
161
|
+
var areNumberRecordsEqual = (left, right) => {
|
|
162
|
+
const leftKeys = Object.keys(left);
|
|
163
|
+
const rightKeys = Object.keys(right);
|
|
164
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => right[key] === left[key]);
|
|
165
|
+
};
|
|
166
|
+
var areTrueRecordsEqual = (left, right) => {
|
|
167
|
+
const leftKeys = Object.keys(left);
|
|
168
|
+
const rightKeys = Object.keys(right);
|
|
169
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => right[key] === true);
|
|
170
|
+
};
|
|
171
|
+
var isSameTimelineAnchorSnapshot = (current, next) => current !== void 0 && areStringArraysEqual(current.previousBlockKeys, next.previousBlockKeys) && areNumberRecordsEqual(current.timelineBlockAnchors, next.timelineBlockAnchors) && areTrueRecordsEqual(current.visibleTimelineBlockKeys, next.visibleTimelineBlockKeys);
|
|
160
172
|
var mergeStreamingBlocks = (existingBlocks, incomingBlocks) => {
|
|
161
173
|
const nextBlocks = [...existingBlocks ?? []];
|
|
162
174
|
incomingBlocks.forEach((incomingBlock) => {
|
|
@@ -249,6 +261,7 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
249
261
|
sessionMessageLoadStatusBySession: {},
|
|
250
262
|
sessionMessageLoadErrorBySession: {},
|
|
251
263
|
historyMessagePaginationBySession: {},
|
|
264
|
+
timelineAnchorStateBySession: {},
|
|
252
265
|
// ---- Session management ------------------------------------------------
|
|
253
266
|
createSession: (session) => {
|
|
254
267
|
const state = get();
|
|
@@ -267,6 +280,9 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
267
280
|
const nextHistoryMessagePaginationBySession = {
|
|
268
281
|
...state.historyMessagePaginationBySession
|
|
269
282
|
};
|
|
283
|
+
const nextTimelineAnchorStateBySession = {
|
|
284
|
+
...state.timelineAnchorStateBySession
|
|
285
|
+
};
|
|
270
286
|
const sid = session.sessionId;
|
|
271
287
|
if (nextMessagesBySession[sid] === void 0)
|
|
272
288
|
nextMessagesBySession[sid] = [];
|
|
@@ -294,7 +310,8 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
294
310
|
isStoppingBySession: nextIsStoppingBySession,
|
|
295
311
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
296
312
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
297
|
-
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
313
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
314
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession
|
|
298
315
|
});
|
|
299
316
|
},
|
|
300
317
|
startNewChat: () => {
|
|
@@ -364,10 +381,17 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
364
381
|
const nextHistoryMessagePaginationBySession = {
|
|
365
382
|
...state.historyMessagePaginationBySession
|
|
366
383
|
};
|
|
384
|
+
const nextTimelineAnchorStateBySession = {
|
|
385
|
+
...state.timelineAnchorStateBySession
|
|
386
|
+
};
|
|
367
387
|
if (previousSessionId in nextHistoryMessagePaginationBySession) {
|
|
368
388
|
nextHistoryMessagePaginationBySession[nextSessionId] = nextHistoryMessagePaginationBySession[previousSessionId] ?? createHistoryMessagePaginationState();
|
|
369
389
|
delete nextHistoryMessagePaginationBySession[previousSessionId];
|
|
370
390
|
}
|
|
391
|
+
if (previousSessionId in nextTimelineAnchorStateBySession) {
|
|
392
|
+
nextTimelineAnchorStateBySession[nextSessionId] = nextTimelineAnchorStateBySession[previousSessionId] ?? {};
|
|
393
|
+
delete nextTimelineAnchorStateBySession[previousSessionId];
|
|
394
|
+
}
|
|
371
395
|
const nextActiveSessionId = state.activeSessionId === previousSessionId ? nextSessionId : state.activeSessionId;
|
|
372
396
|
set({
|
|
373
397
|
sessions: nextSessions,
|
|
@@ -379,6 +403,7 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
379
403
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
380
404
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
381
405
|
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
406
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession,
|
|
382
407
|
activeSessionId: nextActiveSessionId
|
|
383
408
|
});
|
|
384
409
|
},
|
|
@@ -419,6 +444,9 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
419
444
|
const nextHistoryMessagePaginationBySession = {
|
|
420
445
|
...state.historyMessagePaginationBySession
|
|
421
446
|
};
|
|
447
|
+
const nextTimelineAnchorStateBySession = {
|
|
448
|
+
...state.timelineAnchorStateBySession
|
|
449
|
+
};
|
|
422
450
|
nextSessions.forEach((session) => {
|
|
423
451
|
const sid = session.sessionId;
|
|
424
452
|
if (nextErrorBySession[sid] === void 0)
|
|
@@ -445,7 +473,8 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
445
473
|
isStoppingBySession: nextIsStoppingBySession,
|
|
446
474
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
447
475
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
448
|
-
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
476
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
477
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession
|
|
449
478
|
});
|
|
450
479
|
},
|
|
451
480
|
// ---- Message operations ------------------------------------------------
|
|
@@ -560,6 +589,23 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
|
|
|
560
589
|
}
|
|
561
590
|
});
|
|
562
591
|
},
|
|
592
|
+
setTimelineAnchorState: (sessionId, messageId, snapshot) => {
|
|
593
|
+
const state = get();
|
|
594
|
+
const currentSessionSnapshots = state.timelineAnchorStateBySession[sessionId] ?? {};
|
|
595
|
+
const currentSnapshot = currentSessionSnapshots[messageId];
|
|
596
|
+
if (isSameTimelineAnchorSnapshot(currentSnapshot, snapshot)) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
set({
|
|
600
|
+
timelineAnchorStateBySession: {
|
|
601
|
+
...state.timelineAnchorStateBySession,
|
|
602
|
+
[sessionId]: {
|
|
603
|
+
...currentSessionSnapshots,
|
|
604
|
+
[messageId]: snapshot
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
},
|
|
563
609
|
startStreamingMessage: (sessionId, message) => {
|
|
564
610
|
const state = get();
|
|
565
611
|
set({
|
|
@@ -1550,13 +1596,39 @@ var createTimelineAnchorState = ({
|
|
|
1550
1596
|
timelineBlockAnchors: {},
|
|
1551
1597
|
visibleTimelineBlockKeys: {}
|
|
1552
1598
|
});
|
|
1599
|
+
var restoreTimelineAnchorState = ({
|
|
1600
|
+
messageId,
|
|
1601
|
+
currentBlockKeys,
|
|
1602
|
+
persistedState
|
|
1603
|
+
}) => {
|
|
1604
|
+
if (!persistedState) {
|
|
1605
|
+
return createTimelineAnchorState({ messageId, currentBlockKeys });
|
|
1606
|
+
}
|
|
1607
|
+
const currentBlockKeySet = new Set(currentBlockKeys);
|
|
1608
|
+
return {
|
|
1609
|
+
messageId,
|
|
1610
|
+
previousBlockKeys: persistedState.previousBlockKeys.filter(
|
|
1611
|
+
(blockKey) => currentBlockKeySet.has(blockKey)
|
|
1612
|
+
),
|
|
1613
|
+
timelineBlockAnchors: Object.fromEntries(
|
|
1614
|
+
Object.entries(persistedState.timelineBlockAnchors).filter(
|
|
1615
|
+
([blockKey]) => currentBlockKeySet.has(blockKey)
|
|
1616
|
+
)
|
|
1617
|
+
),
|
|
1618
|
+
visibleTimelineBlockKeys: Object.fromEntries(
|
|
1619
|
+
Object.entries(persistedState.visibleTimelineBlockKeys).filter(
|
|
1620
|
+
([blockKey]) => currentBlockKeySet.has(blockKey)
|
|
1621
|
+
)
|
|
1622
|
+
)
|
|
1623
|
+
};
|
|
1624
|
+
};
|
|
1553
1625
|
var createInitialTimelineAnchorState = ({
|
|
1554
|
-
messageId
|
|
1555
|
-
}) => ({
|
|
1556
1626
|
messageId,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1627
|
+
currentBlockKeys,
|
|
1628
|
+
persistedState
|
|
1629
|
+
}) => ({
|
|
1630
|
+
...restoreTimelineAnchorState({ messageId, currentBlockKeys, persistedState }),
|
|
1631
|
+
previousBlockKeys: persistedState?.previousBlockKeys ?? []
|
|
1560
1632
|
});
|
|
1561
1633
|
var timelineAnchorReducer = (state, action) => {
|
|
1562
1634
|
switch (action.type) {
|
|
@@ -1564,7 +1636,7 @@ var timelineAnchorReducer = (state, action) => {
|
|
|
1564
1636
|
if (state.messageId === action.messageId) {
|
|
1565
1637
|
return state;
|
|
1566
1638
|
}
|
|
1567
|
-
return
|
|
1639
|
+
return restoreTimelineAnchorState(action);
|
|
1568
1640
|
case "sync-anchors": {
|
|
1569
1641
|
const previousBlockKeys = new Set(state.previousBlockKeys);
|
|
1570
1642
|
const nextAnchors = action.currentBlockKeys.reduce(
|
|
@@ -1633,10 +1705,15 @@ var useTimelineBlockAnchors = ({
|
|
|
1633
1705
|
message,
|
|
1634
1706
|
messageRenderOrder
|
|
1635
1707
|
}) => {
|
|
1708
|
+
const { store } = useChatContext();
|
|
1636
1709
|
const currentTimelineBlockKeys = (0, import_react6.useMemo)(
|
|
1637
1710
|
() => blocks.map((block, index3) => getTimelineBlockKey(block, index3)).filter((blockKey) => Boolean(blockKey)),
|
|
1638
1711
|
[blocks]
|
|
1639
1712
|
);
|
|
1713
|
+
const persistedState = (0, import_react6.useMemo)(
|
|
1714
|
+
() => store.getState().timelineAnchorStateBySession[message.sessionId]?.[message.id],
|
|
1715
|
+
[message.id, message.sessionId, store]
|
|
1716
|
+
);
|
|
1640
1717
|
const timelineTextStreamLength = (0, import_react6.useMemo)(
|
|
1641
1718
|
() => getTimelineDisplayUnitCount(getTimelineTextStream(message.content, blocks)),
|
|
1642
1719
|
[blocks, message.content]
|
|
@@ -1645,7 +1722,8 @@ var useTimelineBlockAnchors = ({
|
|
|
1645
1722
|
timelineAnchorReducer,
|
|
1646
1723
|
{
|
|
1647
1724
|
messageId: message.id,
|
|
1648
|
-
currentBlockKeys: currentTimelineBlockKeys
|
|
1725
|
+
currentBlockKeys: currentTimelineBlockKeys,
|
|
1726
|
+
persistedState
|
|
1649
1727
|
},
|
|
1650
1728
|
createInitialTimelineAnchorState
|
|
1651
1729
|
);
|
|
@@ -1680,9 +1758,10 @@ var useTimelineBlockAnchors = ({
|
|
|
1680
1758
|
dispatch({
|
|
1681
1759
|
type: "reset-message",
|
|
1682
1760
|
messageId: message.id,
|
|
1683
|
-
currentBlockKeys: currentTimelineBlockKeys
|
|
1761
|
+
currentBlockKeys: currentTimelineBlockKeys,
|
|
1762
|
+
persistedState
|
|
1684
1763
|
});
|
|
1685
|
-
}, [currentTimelineBlockKeys, message.id]);
|
|
1764
|
+
}, [currentTimelineBlockKeys, message.id, persistedState]);
|
|
1686
1765
|
(0, import_react6.useEffect)(() => {
|
|
1687
1766
|
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
1688
1767
|
return;
|
|
@@ -1709,6 +1788,24 @@ var useTimelineBlockAnchors = ({
|
|
|
1709
1788
|
effectiveTimelineBlockAnchors,
|
|
1710
1789
|
messageRenderOrder
|
|
1711
1790
|
]);
|
|
1791
|
+
(0, import_react6.useEffect)(() => {
|
|
1792
|
+
if (messageRenderOrder !== "timeline") {
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
store.getState().setTimelineAnchorState(message.sessionId, message.id, {
|
|
1796
|
+
previousBlockKeys: state.previousBlockKeys,
|
|
1797
|
+
timelineBlockAnchors: state.timelineBlockAnchors,
|
|
1798
|
+
visibleTimelineBlockKeys: state.visibleTimelineBlockKeys
|
|
1799
|
+
});
|
|
1800
|
+
}, [
|
|
1801
|
+
message.id,
|
|
1802
|
+
message.sessionId,
|
|
1803
|
+
messageRenderOrder,
|
|
1804
|
+
state.previousBlockKeys,
|
|
1805
|
+
state.timelineBlockAnchors,
|
|
1806
|
+
state.visibleTimelineBlockKeys,
|
|
1807
|
+
store
|
|
1808
|
+
]);
|
|
1712
1809
|
return {
|
|
1713
1810
|
timelineBlockAnchors: messageRenderOrder === "timeline" ? effectiveTimelineBlockAnchors : {},
|
|
1714
1811
|
visibleTimelineBlockKeys: messageRenderOrder === "timeline" ? state.visibleTimelineBlockKeys : {}
|
|
@@ -3018,10 +3115,10 @@ var areExecutionProposalsEqual = (previousProposal, nextProposal) => previousPro
|
|
|
3018
3115
|
(warning, index3) => warning === nextProposal.warnings?.[index3]
|
|
3019
3116
|
);
|
|
3020
3117
|
var areResultSummariesEqual = (previousSummary, nextSummary) => previousSummary.summaryId === nextSummary.summaryId && previousSummary.status === nextSummary.status && previousSummary.headline === nextSummary.headline && previousSummary.details.length === nextSummary.details.length && previousSummary.details.every((detail, index3) => detail === nextSummary.details[index3]);
|
|
3021
|
-
var
|
|
3118
|
+
var areStringArraysEqual2 = (previousValues, nextValues) => previousValues.length === nextValues.length && previousValues.every((value, index3) => value === nextValues[index3]);
|
|
3022
3119
|
var areQuestionAnswersEqual = (previousAnswer, nextAnswer) => {
|
|
3023
3120
|
if (Array.isArray(previousAnswer) || Array.isArray(nextAnswer)) {
|
|
3024
|
-
return Array.isArray(previousAnswer) && Array.isArray(nextAnswer) &&
|
|
3121
|
+
return Array.isArray(previousAnswer) && Array.isArray(nextAnswer) && areStringArraysEqual2(previousAnswer, nextAnswer);
|
|
3025
3122
|
}
|
|
3026
3123
|
return previousAnswer === nextAnswer;
|
|
3027
3124
|
};
|
|
@@ -3108,7 +3205,7 @@ var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
|
|
|
3108
3205
|
}
|
|
3109
3206
|
});
|
|
3110
3207
|
};
|
|
3111
|
-
var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content &&
|
|
3208
|
+
var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content && areStringArraysEqual2(previousMessage.skills ?? [], nextMessage.skills ?? []) && areMessageBlocksEqual(previousMessage.blocks, nextMessage.blocks) && previousMessage.localOnly === nextMessage.localOnly && areChatAttachmentsEqual(previousMessage.attachments, nextMessage.attachments) && previousMessage.status === nextMessage.status && previousMessage.createdAt === nextMessage.createdAt && previousMode === nextMode && previousConfirmationSubmit === nextConfirmationSubmit && previousQuestionnaireSubmit === nextQuestionnaireSubmit && previousRenderMessageBlock === nextRenderMessageBlock;
|
|
3112
3209
|
var ChatMessageItemView = ({
|
|
3113
3210
|
message,
|
|
3114
3211
|
mode = "agent",
|
package/dist/index.mjs
CHANGED
|
@@ -110,6 +110,18 @@ var resolveSessionTitleFromMessage = (message) => {
|
|
|
110
110
|
}
|
|
111
111
|
return DEFAULT_CHAT_SESSION_TITLE;
|
|
112
112
|
};
|
|
113
|
+
var areStringArraysEqual = (left, right) => left.length === right.length && left.every((value, index3) => value === right[index3]);
|
|
114
|
+
var areNumberRecordsEqual = (left, right) => {
|
|
115
|
+
const leftKeys = Object.keys(left);
|
|
116
|
+
const rightKeys = Object.keys(right);
|
|
117
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => right[key] === left[key]);
|
|
118
|
+
};
|
|
119
|
+
var areTrueRecordsEqual = (left, right) => {
|
|
120
|
+
const leftKeys = Object.keys(left);
|
|
121
|
+
const rightKeys = Object.keys(right);
|
|
122
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => right[key] === true);
|
|
123
|
+
};
|
|
124
|
+
var isSameTimelineAnchorSnapshot = (current, next) => current !== void 0 && areStringArraysEqual(current.previousBlockKeys, next.previousBlockKeys) && areNumberRecordsEqual(current.timelineBlockAnchors, next.timelineBlockAnchors) && areTrueRecordsEqual(current.visibleTimelineBlockKeys, next.visibleTimelineBlockKeys);
|
|
113
125
|
var mergeStreamingBlocks = (existingBlocks, incomingBlocks) => {
|
|
114
126
|
const nextBlocks = [...existingBlocks ?? []];
|
|
115
127
|
incomingBlocks.forEach((incomingBlock) => {
|
|
@@ -202,6 +214,7 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
202
214
|
sessionMessageLoadStatusBySession: {},
|
|
203
215
|
sessionMessageLoadErrorBySession: {},
|
|
204
216
|
historyMessagePaginationBySession: {},
|
|
217
|
+
timelineAnchorStateBySession: {},
|
|
205
218
|
// ---- Session management ------------------------------------------------
|
|
206
219
|
createSession: (session) => {
|
|
207
220
|
const state = get();
|
|
@@ -220,6 +233,9 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
220
233
|
const nextHistoryMessagePaginationBySession = {
|
|
221
234
|
...state.historyMessagePaginationBySession
|
|
222
235
|
};
|
|
236
|
+
const nextTimelineAnchorStateBySession = {
|
|
237
|
+
...state.timelineAnchorStateBySession
|
|
238
|
+
};
|
|
223
239
|
const sid = session.sessionId;
|
|
224
240
|
if (nextMessagesBySession[sid] === void 0)
|
|
225
241
|
nextMessagesBySession[sid] = [];
|
|
@@ -247,7 +263,8 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
247
263
|
isStoppingBySession: nextIsStoppingBySession,
|
|
248
264
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
249
265
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
250
|
-
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
266
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
267
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession
|
|
251
268
|
});
|
|
252
269
|
},
|
|
253
270
|
startNewChat: () => {
|
|
@@ -317,10 +334,17 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
317
334
|
const nextHistoryMessagePaginationBySession = {
|
|
318
335
|
...state.historyMessagePaginationBySession
|
|
319
336
|
};
|
|
337
|
+
const nextTimelineAnchorStateBySession = {
|
|
338
|
+
...state.timelineAnchorStateBySession
|
|
339
|
+
};
|
|
320
340
|
if (previousSessionId in nextHistoryMessagePaginationBySession) {
|
|
321
341
|
nextHistoryMessagePaginationBySession[nextSessionId] = nextHistoryMessagePaginationBySession[previousSessionId] ?? createHistoryMessagePaginationState();
|
|
322
342
|
delete nextHistoryMessagePaginationBySession[previousSessionId];
|
|
323
343
|
}
|
|
344
|
+
if (previousSessionId in nextTimelineAnchorStateBySession) {
|
|
345
|
+
nextTimelineAnchorStateBySession[nextSessionId] = nextTimelineAnchorStateBySession[previousSessionId] ?? {};
|
|
346
|
+
delete nextTimelineAnchorStateBySession[previousSessionId];
|
|
347
|
+
}
|
|
324
348
|
const nextActiveSessionId = state.activeSessionId === previousSessionId ? nextSessionId : state.activeSessionId;
|
|
325
349
|
set({
|
|
326
350
|
sessions: nextSessions,
|
|
@@ -332,6 +356,7 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
332
356
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
333
357
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
334
358
|
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
359
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession,
|
|
335
360
|
activeSessionId: nextActiveSessionId
|
|
336
361
|
});
|
|
337
362
|
},
|
|
@@ -372,6 +397,9 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
372
397
|
const nextHistoryMessagePaginationBySession = {
|
|
373
398
|
...state.historyMessagePaginationBySession
|
|
374
399
|
};
|
|
400
|
+
const nextTimelineAnchorStateBySession = {
|
|
401
|
+
...state.timelineAnchorStateBySession
|
|
402
|
+
};
|
|
375
403
|
nextSessions.forEach((session) => {
|
|
376
404
|
const sid = session.sessionId;
|
|
377
405
|
if (nextErrorBySession[sid] === void 0)
|
|
@@ -398,7 +426,8 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
398
426
|
isStoppingBySession: nextIsStoppingBySession,
|
|
399
427
|
sessionMessageLoadStatusBySession: nextSessionMessageLoadStatusBySession,
|
|
400
428
|
sessionMessageLoadErrorBySession: nextSessionMessageLoadErrorBySession,
|
|
401
|
-
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession
|
|
429
|
+
historyMessagePaginationBySession: nextHistoryMessagePaginationBySession,
|
|
430
|
+
timelineAnchorStateBySession: nextTimelineAnchorStateBySession
|
|
402
431
|
});
|
|
403
432
|
},
|
|
404
433
|
// ---- Message operations ------------------------------------------------
|
|
@@ -513,6 +542,23 @@ var createChatStore = (initialState) => createStore((set, get) => ({
|
|
|
513
542
|
}
|
|
514
543
|
});
|
|
515
544
|
},
|
|
545
|
+
setTimelineAnchorState: (sessionId, messageId, snapshot) => {
|
|
546
|
+
const state = get();
|
|
547
|
+
const currentSessionSnapshots = state.timelineAnchorStateBySession[sessionId] ?? {};
|
|
548
|
+
const currentSnapshot = currentSessionSnapshots[messageId];
|
|
549
|
+
if (isSameTimelineAnchorSnapshot(currentSnapshot, snapshot)) {
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
set({
|
|
553
|
+
timelineAnchorStateBySession: {
|
|
554
|
+
...state.timelineAnchorStateBySession,
|
|
555
|
+
[sessionId]: {
|
|
556
|
+
...currentSessionSnapshots,
|
|
557
|
+
[messageId]: snapshot
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
},
|
|
516
562
|
startStreamingMessage: (sessionId, message) => {
|
|
517
563
|
const state = get();
|
|
518
564
|
set({
|
|
@@ -1503,13 +1549,39 @@ var createTimelineAnchorState = ({
|
|
|
1503
1549
|
timelineBlockAnchors: {},
|
|
1504
1550
|
visibleTimelineBlockKeys: {}
|
|
1505
1551
|
});
|
|
1552
|
+
var restoreTimelineAnchorState = ({
|
|
1553
|
+
messageId,
|
|
1554
|
+
currentBlockKeys,
|
|
1555
|
+
persistedState
|
|
1556
|
+
}) => {
|
|
1557
|
+
if (!persistedState) {
|
|
1558
|
+
return createTimelineAnchorState({ messageId, currentBlockKeys });
|
|
1559
|
+
}
|
|
1560
|
+
const currentBlockKeySet = new Set(currentBlockKeys);
|
|
1561
|
+
return {
|
|
1562
|
+
messageId,
|
|
1563
|
+
previousBlockKeys: persistedState.previousBlockKeys.filter(
|
|
1564
|
+
(blockKey) => currentBlockKeySet.has(blockKey)
|
|
1565
|
+
),
|
|
1566
|
+
timelineBlockAnchors: Object.fromEntries(
|
|
1567
|
+
Object.entries(persistedState.timelineBlockAnchors).filter(
|
|
1568
|
+
([blockKey]) => currentBlockKeySet.has(blockKey)
|
|
1569
|
+
)
|
|
1570
|
+
),
|
|
1571
|
+
visibleTimelineBlockKeys: Object.fromEntries(
|
|
1572
|
+
Object.entries(persistedState.visibleTimelineBlockKeys).filter(
|
|
1573
|
+
([blockKey]) => currentBlockKeySet.has(blockKey)
|
|
1574
|
+
)
|
|
1575
|
+
)
|
|
1576
|
+
};
|
|
1577
|
+
};
|
|
1506
1578
|
var createInitialTimelineAnchorState = ({
|
|
1507
|
-
messageId
|
|
1508
|
-
}) => ({
|
|
1509
1579
|
messageId,
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1580
|
+
currentBlockKeys,
|
|
1581
|
+
persistedState
|
|
1582
|
+
}) => ({
|
|
1583
|
+
...restoreTimelineAnchorState({ messageId, currentBlockKeys, persistedState }),
|
|
1584
|
+
previousBlockKeys: persistedState?.previousBlockKeys ?? []
|
|
1513
1585
|
});
|
|
1514
1586
|
var timelineAnchorReducer = (state, action) => {
|
|
1515
1587
|
switch (action.type) {
|
|
@@ -1517,7 +1589,7 @@ var timelineAnchorReducer = (state, action) => {
|
|
|
1517
1589
|
if (state.messageId === action.messageId) {
|
|
1518
1590
|
return state;
|
|
1519
1591
|
}
|
|
1520
|
-
return
|
|
1592
|
+
return restoreTimelineAnchorState(action);
|
|
1521
1593
|
case "sync-anchors": {
|
|
1522
1594
|
const previousBlockKeys = new Set(state.previousBlockKeys);
|
|
1523
1595
|
const nextAnchors = action.currentBlockKeys.reduce(
|
|
@@ -1586,10 +1658,15 @@ var useTimelineBlockAnchors = ({
|
|
|
1586
1658
|
message,
|
|
1587
1659
|
messageRenderOrder
|
|
1588
1660
|
}) => {
|
|
1661
|
+
const { store } = useChatContext();
|
|
1589
1662
|
const currentTimelineBlockKeys = useMemo3(
|
|
1590
1663
|
() => blocks.map((block, index3) => getTimelineBlockKey(block, index3)).filter((blockKey) => Boolean(blockKey)),
|
|
1591
1664
|
[blocks]
|
|
1592
1665
|
);
|
|
1666
|
+
const persistedState = useMemo3(
|
|
1667
|
+
() => store.getState().timelineAnchorStateBySession[message.sessionId]?.[message.id],
|
|
1668
|
+
[message.id, message.sessionId, store]
|
|
1669
|
+
);
|
|
1593
1670
|
const timelineTextStreamLength = useMemo3(
|
|
1594
1671
|
() => getTimelineDisplayUnitCount(getTimelineTextStream(message.content, blocks)),
|
|
1595
1672
|
[blocks, message.content]
|
|
@@ -1598,7 +1675,8 @@ var useTimelineBlockAnchors = ({
|
|
|
1598
1675
|
timelineAnchorReducer,
|
|
1599
1676
|
{
|
|
1600
1677
|
messageId: message.id,
|
|
1601
|
-
currentBlockKeys: currentTimelineBlockKeys
|
|
1678
|
+
currentBlockKeys: currentTimelineBlockKeys,
|
|
1679
|
+
persistedState
|
|
1602
1680
|
},
|
|
1603
1681
|
createInitialTimelineAnchorState
|
|
1604
1682
|
);
|
|
@@ -1633,9 +1711,10 @@ var useTimelineBlockAnchors = ({
|
|
|
1633
1711
|
dispatch({
|
|
1634
1712
|
type: "reset-message",
|
|
1635
1713
|
messageId: message.id,
|
|
1636
|
-
currentBlockKeys: currentTimelineBlockKeys
|
|
1714
|
+
currentBlockKeys: currentTimelineBlockKeys,
|
|
1715
|
+
persistedState
|
|
1637
1716
|
});
|
|
1638
|
-
}, [currentTimelineBlockKeys, message.id]);
|
|
1717
|
+
}, [currentTimelineBlockKeys, message.id, persistedState]);
|
|
1639
1718
|
useEffect3(() => {
|
|
1640
1719
|
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
1641
1720
|
return;
|
|
@@ -1662,6 +1741,24 @@ var useTimelineBlockAnchors = ({
|
|
|
1662
1741
|
effectiveTimelineBlockAnchors,
|
|
1663
1742
|
messageRenderOrder
|
|
1664
1743
|
]);
|
|
1744
|
+
useEffect3(() => {
|
|
1745
|
+
if (messageRenderOrder !== "timeline") {
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
store.getState().setTimelineAnchorState(message.sessionId, message.id, {
|
|
1749
|
+
previousBlockKeys: state.previousBlockKeys,
|
|
1750
|
+
timelineBlockAnchors: state.timelineBlockAnchors,
|
|
1751
|
+
visibleTimelineBlockKeys: state.visibleTimelineBlockKeys
|
|
1752
|
+
});
|
|
1753
|
+
}, [
|
|
1754
|
+
message.id,
|
|
1755
|
+
message.sessionId,
|
|
1756
|
+
messageRenderOrder,
|
|
1757
|
+
state.previousBlockKeys,
|
|
1758
|
+
state.timelineBlockAnchors,
|
|
1759
|
+
state.visibleTimelineBlockKeys,
|
|
1760
|
+
store
|
|
1761
|
+
]);
|
|
1665
1762
|
return {
|
|
1666
1763
|
timelineBlockAnchors: messageRenderOrder === "timeline" ? effectiveTimelineBlockAnchors : {},
|
|
1667
1764
|
visibleTimelineBlockKeys: messageRenderOrder === "timeline" ? state.visibleTimelineBlockKeys : {}
|
|
@@ -2975,10 +3072,10 @@ var areExecutionProposalsEqual = (previousProposal, nextProposal) => previousPro
|
|
|
2975
3072
|
(warning, index3) => warning === nextProposal.warnings?.[index3]
|
|
2976
3073
|
);
|
|
2977
3074
|
var areResultSummariesEqual = (previousSummary, nextSummary) => previousSummary.summaryId === nextSummary.summaryId && previousSummary.status === nextSummary.status && previousSummary.headline === nextSummary.headline && previousSummary.details.length === nextSummary.details.length && previousSummary.details.every((detail, index3) => detail === nextSummary.details[index3]);
|
|
2978
|
-
var
|
|
3075
|
+
var areStringArraysEqual2 = (previousValues, nextValues) => previousValues.length === nextValues.length && previousValues.every((value, index3) => value === nextValues[index3]);
|
|
2979
3076
|
var areQuestionAnswersEqual = (previousAnswer, nextAnswer) => {
|
|
2980
3077
|
if (Array.isArray(previousAnswer) || Array.isArray(nextAnswer)) {
|
|
2981
|
-
return Array.isArray(previousAnswer) && Array.isArray(nextAnswer) &&
|
|
3078
|
+
return Array.isArray(previousAnswer) && Array.isArray(nextAnswer) && areStringArraysEqual2(previousAnswer, nextAnswer);
|
|
2982
3079
|
}
|
|
2983
3080
|
return previousAnswer === nextAnswer;
|
|
2984
3081
|
};
|
|
@@ -3065,7 +3162,7 @@ var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
|
|
|
3065
3162
|
}
|
|
3066
3163
|
});
|
|
3067
3164
|
};
|
|
3068
|
-
var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content &&
|
|
3165
|
+
var isSameMessage = (previousMessage, nextMessage, previousMode, nextMode, previousConfirmationSubmit, nextConfirmationSubmit, previousQuestionnaireSubmit, nextQuestionnaireSubmit, previousRenderMessageBlock, nextRenderMessageBlock) => previousMessage.id === nextMessage.id && previousMessage.sessionId === nextMessage.sessionId && previousMessage.role === nextMessage.role && previousMessage.content === nextMessage.content && areStringArraysEqual2(previousMessage.skills ?? [], nextMessage.skills ?? []) && areMessageBlocksEqual(previousMessage.blocks, nextMessage.blocks) && previousMessage.localOnly === nextMessage.localOnly && areChatAttachmentsEqual(previousMessage.attachments, nextMessage.attachments) && previousMessage.status === nextMessage.status && previousMessage.createdAt === nextMessage.createdAt && previousMode === nextMode && previousConfirmationSubmit === nextConfirmationSubmit && previousQuestionnaireSubmit === nextQuestionnaireSubmit && previousRenderMessageBlock === nextRenderMessageBlock;
|
|
3069
3166
|
var ChatMessageItemView = ({
|
|
3070
3167
|
message,
|
|
3071
3168
|
mode = "agent",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xinghunm/ai-chat",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "AI chat React component library",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@emotion/react": ">=11",
|
|
21
21
|
"@emotion/styled": ">=11",
|
|
22
|
-
"@xinghunm/compass-ui": "0.
|
|
22
|
+
"@xinghunm/compass-ui": "0.9.0",
|
|
23
23
|
"axios": ">=1.0",
|
|
24
24
|
"react": ">=18",
|
|
25
25
|
"react-dom": ">=18",
|