@flamingo-stack/openframe-frontend-core 0.0.249 → 0.0.250
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/{chunk-PCXI7ZB2.js → chunk-D2BC3NZ2.js} +135 -30
- package/dist/chunk-D2BC3NZ2.js.map +1 -0
- package/dist/{chunk-5ZVPKTXM.js → chunk-DZJ53RX6.js} +2 -2
- package/dist/{chunk-4EED3YEI.cjs → chunk-NCXHTQH2.cjs} +663 -558
- package/dist/chunk-NCXHTQH2.cjs.map +1 -0
- package/dist/{chunk-3DZ7QYNA.cjs → chunk-PDKBCCCD.cjs} +11 -11
- package/dist/{chunk-3DZ7QYNA.cjs.map → chunk-PDKBCCCD.cjs.map} +1 -1
- package/dist/{chunk-LHZYI23D.cjs → chunk-PDYT7T6K.cjs} +32 -29
- package/dist/chunk-PDYT7T6K.cjs.map +1 -0
- package/dist/{chunk-PVAYXHYF.js → chunk-PSG7H4KG.js} +2 -2
- package/dist/{chunk-VAKBNCV6.js → chunk-SGEO3W3F.js} +6 -3
- package/dist/chunk-SGEO3W3F.js.map +1 -0
- package/dist/{chunk-3VTHSACO.cjs → chunk-UMH4RR2F.cjs} +25 -25
- package/dist/{chunk-3VTHSACO.cjs.map → chunk-UMH4RR2F.cjs.map} +1 -1
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +12 -2
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.js +11 -1
- package/dist/components/chat/utils/history-merge.d.ts +92 -0
- package/dist/components/chat/utils/history-merge.d.ts.map +1 -0
- package/dist/components/chat/utils/index.d.ts +1 -0
- package/dist/components/chat/utils/index.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
- package/dist/components/index.cjs +59 -49
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +13 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/related-content/related-content-section.d.ts.map +1 -1
- package/dist/components/tickets/index.cjs +55 -55
- package/dist/components/tickets/index.js +3 -3
- package/dist/components/ui/index.cjs +12 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +11 -1
- package/dist/index.cjs +12 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -1
- package/package.json +1 -1
- package/src/components/chat/__tests__/chat-message-list.test.tsx +92 -0
- package/src/components/chat/chat-message-list.tsx +74 -49
- package/src/components/chat/utils/__tests__/history-merge.test.ts +339 -0
- package/src/components/chat/utils/history-merge.ts +255 -0
- package/src/components/chat/utils/index.ts +12 -0
- package/src/components/features/policy-configuration-panel.tsx +1 -0
- package/src/components/related-content/related-content-section.tsx +6 -2
- package/dist/chunk-4EED3YEI.cjs.map +0 -1
- package/dist/chunk-LHZYI23D.cjs.map +0 -1
- package/dist/chunk-PCXI7ZB2.js.map +0 -1
- package/dist/chunk-VAKBNCV6.js.map +0 -1
- /package/dist/{chunk-5ZVPKTXM.js.map → chunk-DZJ53RX6.js.map} +0 -0
- /package/dist/{chunk-PVAYXHYF.js.map → chunk-PSG7H4KG.js.map} +0 -0
|
@@ -2924,12 +2924,15 @@ var ChatMessageList = forwardRef12(
|
|
|
2924
2924
|
onLoadMoreRef.current = onLoadMore;
|
|
2925
2925
|
const isFetchingRef = useRef3(isFetchingNextPage);
|
|
2926
2926
|
isFetchingRef.current = isFetchingNextPage;
|
|
2927
|
+
const dialogIdRef = useRef3(dialogId);
|
|
2928
|
+
dialogIdRef.current = dialogId;
|
|
2927
2929
|
const prevRenderRef = useRef3({ dialogId: void 0, messageCount: 0, lastMessageId: void 0 });
|
|
2928
|
-
const
|
|
2930
|
+
const loadOlderAnchorRef = useRef3(null);
|
|
2929
2931
|
useEffect3(() => {
|
|
2930
2932
|
if (!autoScroll) return;
|
|
2931
2933
|
const dialogChanged = dialogId !== prevRenderRef.current.dialogId;
|
|
2932
2934
|
const prevCount = prevRenderRef.current.messageCount;
|
|
2935
|
+
const prevLastId = prevRenderRef.current.lastMessageId;
|
|
2933
2936
|
const newCount = messages.length;
|
|
2934
2937
|
const currentLastId = messages[messages.length - 1]?.id;
|
|
2935
2938
|
prevRenderRef.current = { dialogId, messageCount: newCount, lastMessageId: currentLastId };
|
|
@@ -2942,7 +2945,8 @@ var ChatMessageList = forwardRef12(
|
|
|
2942
2945
|
return;
|
|
2943
2946
|
}
|
|
2944
2947
|
if (newCount > prevCount) {
|
|
2945
|
-
const
|
|
2948
|
+
const prevLastIdx = prevLastId ? messages.findIndex((m) => m.id === prevLastId) : -1;
|
|
2949
|
+
const newSlice = prevLastIdx >= 0 ? messages.slice(prevLastIdx + 1) : messages.slice(prevCount);
|
|
2946
2950
|
const hasNewUser = newSlice.some((m) => m.role === "user");
|
|
2947
2951
|
if (hasNewUser) {
|
|
2948
2952
|
void scrollToBottom({ animation: "instant", ignoreEscapes: true });
|
|
@@ -2966,34 +2970,17 @@ var ChatMessageList = forwardRef12(
|
|
|
2966
2970
|
}, [autoScroll, messages, dialogId, scrollToBottom, contentRef]);
|
|
2967
2971
|
useLayoutEffect2(() => {
|
|
2968
2972
|
const el = scrollRef.current;
|
|
2969
|
-
|
|
2970
|
-
|
|
2973
|
+
const anchor = loadOlderAnchorRef.current;
|
|
2974
|
+
if (!el || !anchor) return;
|
|
2975
|
+
if (anchor.dialogId !== dialogId) {
|
|
2976
|
+
loadOlderAnchorRef.current = null;
|
|
2971
2977
|
return;
|
|
2972
2978
|
}
|
|
2973
|
-
const
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
if (prevFirstId && prevHeight > 0) {
|
|
2979
|
-
const prevIdx = messages.findIndex((m) => m.id === prevFirstId);
|
|
2980
|
-
if (prevIdx > 0) {
|
|
2981
|
-
const addedHeight = el.scrollHeight - prevHeight;
|
|
2982
|
-
if (addedHeight > 0) el.scrollTop += addedHeight;
|
|
2983
|
-
}
|
|
2984
|
-
}
|
|
2985
|
-
prependRef.current = {
|
|
2986
|
-
firstMessageId: currentFirstId,
|
|
2987
|
-
firstMessageContent: currentFirstContent,
|
|
2988
|
-
scrollHeight: el.scrollHeight
|
|
2989
|
-
};
|
|
2990
|
-
return;
|
|
2991
|
-
}
|
|
2992
|
-
prependRef.current.scrollHeight = el.scrollHeight;
|
|
2993
|
-
if (currentFirstContent !== prependRef.current.firstMessageContent) {
|
|
2994
|
-
prependRef.current.firstMessageContent = currentFirstContent;
|
|
2995
|
-
}
|
|
2996
|
-
}, [messages, scrollRef]);
|
|
2979
|
+
const addedHeight = el.scrollHeight - anchor.scrollHeight;
|
|
2980
|
+
if (addedHeight <= 0) return;
|
|
2981
|
+
loadOlderAnchorRef.current = null;
|
|
2982
|
+
el.scrollTop = anchor.scrollTop + addedHeight;
|
|
2983
|
+
}, [messages, dialogId, scrollRef]);
|
|
2997
2984
|
const messageElsRef = useRef3(/* @__PURE__ */ new Map());
|
|
2998
2985
|
const refCallbacksRef = useRef3(/* @__PURE__ */ new Map());
|
|
2999
2986
|
const getRegisterMessageEl = (id) => {
|
|
@@ -3065,6 +3052,14 @@ var ChatMessageList = forwardRef12(
|
|
|
3065
3052
|
const entry = entries[0];
|
|
3066
3053
|
if (!entry) return;
|
|
3067
3054
|
if (entry.isIntersecting && !isFetchingRef.current) {
|
|
3055
|
+
const el = scrollRef.current;
|
|
3056
|
+
if (el) {
|
|
3057
|
+
loadOlderAnchorRef.current = {
|
|
3058
|
+
dialogId: dialogIdRef.current,
|
|
3059
|
+
scrollHeight: el.scrollHeight,
|
|
3060
|
+
scrollTop: el.scrollTop
|
|
3061
|
+
};
|
|
3062
|
+
}
|
|
3068
3063
|
onLoadMoreRef.current?.();
|
|
3069
3064
|
}
|
|
3070
3065
|
},
|
|
@@ -3072,7 +3067,7 @@ var ChatMessageList = forwardRef12(
|
|
|
3072
3067
|
);
|
|
3073
3068
|
observer.observe(sentinelElement);
|
|
3074
3069
|
return () => observer.disconnect();
|
|
3075
|
-
}, [hasNextPage, scrollRef]);
|
|
3070
|
+
}, [hasNextPage, isFetchingNextPage, scrollRef]);
|
|
3076
3071
|
useImperativeHandle2(ref, () => scrollRef.current, [scrollRef]);
|
|
3077
3072
|
if (isLoading) {
|
|
3078
3073
|
return /* @__PURE__ */ jsx22(
|
|
@@ -20247,6 +20242,7 @@ var CategorySection = ({
|
|
|
20247
20242
|
/* @__PURE__ */ jsx175(
|
|
20248
20243
|
Button,
|
|
20249
20244
|
{
|
|
20245
|
+
type: "button",
|
|
20250
20246
|
variant: "transparent",
|
|
20251
20247
|
onClick: (e) => {
|
|
20252
20248
|
e.stopPropagation();
|
|
@@ -37808,6 +37804,110 @@ function extractIncompleteMessageState(lastMessage) {
|
|
|
37808
37804
|
};
|
|
37809
37805
|
}
|
|
37810
37806
|
|
|
37807
|
+
// src/components/chat/utils/history-merge.ts
|
|
37808
|
+
var SYNTHETIC_REALTIME_ID_PREFIXES = ["assistant-", "user-", "error-"];
|
|
37809
|
+
function isSyntheticRealtimeId(id) {
|
|
37810
|
+
return SYNTHETIC_REALTIME_ID_PREFIXES.some((prefix) => id.startsWith(prefix));
|
|
37811
|
+
}
|
|
37812
|
+
function flattenMessagePagesChronological(pages) {
|
|
37813
|
+
if (!pages) return [];
|
|
37814
|
+
return [...pages].reverse().flatMap((page) => [...page.messages].reverse());
|
|
37815
|
+
}
|
|
37816
|
+
function maxPersistedStreamSeq(pages) {
|
|
37817
|
+
let max = 0;
|
|
37818
|
+
if (!pages) return max;
|
|
37819
|
+
for (const page of pages) {
|
|
37820
|
+
for (const msg of page.messages) {
|
|
37821
|
+
const seq = msg.lastChunkStreamSeq;
|
|
37822
|
+
if (typeof seq === "number" && seq > max) max = seq;
|
|
37823
|
+
}
|
|
37824
|
+
}
|
|
37825
|
+
return max;
|
|
37826
|
+
}
|
|
37827
|
+
function mergeHistoryWithRealtime(input) {
|
|
37828
|
+
const {
|
|
37829
|
+
processedHistory,
|
|
37830
|
+
rawHistoryIds,
|
|
37831
|
+
existingMessages,
|
|
37832
|
+
streamingMessageId,
|
|
37833
|
+
historyFetchedAt,
|
|
37834
|
+
historyMaxStreamSeq = 0,
|
|
37835
|
+
realtimeSeenStreamSeq = 0
|
|
37836
|
+
} = input;
|
|
37837
|
+
if (processedHistory.length === 0) return existingMessages;
|
|
37838
|
+
const processedIds = new Set(processedHistory.map((m) => m.id));
|
|
37839
|
+
const seqCoverageKnown = realtimeSeenStreamSeq > 0 && historyMaxStreamSeq > 0;
|
|
37840
|
+
const historyCoversRealtime = seqCoverageKnown ? historyMaxStreamSeq >= realtimeSeenStreamSeq : null;
|
|
37841
|
+
const trailing = processedHistory[processedHistory.length - 1];
|
|
37842
|
+
const historyTrailingAssistant = trailing?.role === "assistant" ? trailing : null;
|
|
37843
|
+
const historyBatchId = historyTrailingAssistant && Array.isArray(historyTrailingAssistant.content) ? historyTrailingAssistant.content.find((s) => s.type === "approval_batch")?.data?.approvalRequestId ?? null : null;
|
|
37844
|
+
let processedToUse = processedHistory;
|
|
37845
|
+
const pinnedSyntheticIds = /* @__PURE__ */ new Set();
|
|
37846
|
+
const droppedSyntheticIds = /* @__PURE__ */ new Set();
|
|
37847
|
+
if (historyBatchId) {
|
|
37848
|
+
const batchTwins = existingMessages.filter(
|
|
37849
|
+
(m) => m.role === "assistant" && Array.isArray(m.content) && m.content.some(
|
|
37850
|
+
(s) => s.type === "approval_batch" && s.data?.approvalRequestId === historyBatchId
|
|
37851
|
+
)
|
|
37852
|
+
);
|
|
37853
|
+
const existingWithSameBatch = batchTwins.find((m) => m.id === streamingMessageId) ?? batchTwins[batchTwins.length - 1];
|
|
37854
|
+
if (existingWithSameBatch && Array.isArray(existingWithSameBatch.content)) {
|
|
37855
|
+
const histSize = Array.isArray(historyTrailingAssistant?.content) ? historyTrailingAssistant.content.length : 0;
|
|
37856
|
+
const realtimeSize = existingWithSameBatch.content.length;
|
|
37857
|
+
if (existingWithSameBatch.id === streamingMessageId || realtimeSize > histSize) {
|
|
37858
|
+
processedToUse = processedHistory.slice(0, -1);
|
|
37859
|
+
pinnedSyntheticIds.add(existingWithSameBatch.id);
|
|
37860
|
+
} else {
|
|
37861
|
+
droppedSyntheticIds.add(existingWithSameBatch.id);
|
|
37862
|
+
}
|
|
37863
|
+
}
|
|
37864
|
+
}
|
|
37865
|
+
const realtimeMessages = existingMessages.filter((m) => {
|
|
37866
|
+
if (pinnedSyntheticIds.has(m.id)) return true;
|
|
37867
|
+
if (droppedSyntheticIds.has(m.id)) return false;
|
|
37868
|
+
if (processedIds.has(m.id)) return false;
|
|
37869
|
+
if (rawHistoryIds?.has(m.id)) return false;
|
|
37870
|
+
if (m.role === "user" && m.id.startsWith("optimistic-") && typeof m.content === "string") {
|
|
37871
|
+
const canBeInSnapshot = (m.timestamp?.getTime() ?? 0) <= historyFetchedAt;
|
|
37872
|
+
return !(canBeInSnapshot && processedToUse.some((pm) => pm.role === "user" && pm.content === m.content));
|
|
37873
|
+
}
|
|
37874
|
+
if (isSyntheticRealtimeId(m.id) && m.id !== streamingMessageId) {
|
|
37875
|
+
const covered = historyCoversRealtime !== null ? historyCoversRealtime : (m.timestamp?.getTime() ?? 0) <= historyFetchedAt;
|
|
37876
|
+
if (covered) return false;
|
|
37877
|
+
}
|
|
37878
|
+
return true;
|
|
37879
|
+
});
|
|
37880
|
+
return [...processedToUse, ...realtimeMessages];
|
|
37881
|
+
}
|
|
37882
|
+
function computeHistoryPrepend(processedHistory, existingMessages) {
|
|
37883
|
+
const existingIds = new Set(existingMessages.map((m) => m.id));
|
|
37884
|
+
const newMessages = [];
|
|
37885
|
+
let boundaryMessageIndex = -1;
|
|
37886
|
+
for (let i = 0; i < processedHistory.length; i++) {
|
|
37887
|
+
if (existingIds.has(processedHistory[i].id)) {
|
|
37888
|
+
boundaryMessageIndex = i;
|
|
37889
|
+
break;
|
|
37890
|
+
}
|
|
37891
|
+
newMessages.push(processedHistory[i]);
|
|
37892
|
+
}
|
|
37893
|
+
let boundaryMessageId;
|
|
37894
|
+
let boundaryUpdates;
|
|
37895
|
+
if (boundaryMessageIndex >= 0) {
|
|
37896
|
+
const boundaryMessage = processedHistory[boundaryMessageIndex];
|
|
37897
|
+
const existingBoundary = existingMessages.find((m) => m.id === boundaryMessage.id);
|
|
37898
|
+
if (existingBoundary) {
|
|
37899
|
+
const existingContent = JSON.stringify(existingBoundary.content);
|
|
37900
|
+
const newContent = JSON.stringify(boundaryMessage.content);
|
|
37901
|
+
if (existingContent !== newContent) {
|
|
37902
|
+
boundaryMessageId = boundaryMessage.id;
|
|
37903
|
+
boundaryUpdates = { content: boundaryMessage.content };
|
|
37904
|
+
}
|
|
37905
|
+
}
|
|
37906
|
+
}
|
|
37907
|
+
if (newMessages.length === 0 && !boundaryUpdates) return null;
|
|
37908
|
+
return { newMessages, boundaryMessageId, boundaryUpdates };
|
|
37909
|
+
}
|
|
37910
|
+
|
|
37811
37911
|
// src/components/chat/utils/chip-action-class.ts
|
|
37812
37912
|
var CHIP_ACTION_BUTTON_CLASS = "text-[11px] font-medium text-ods-text-secondary hover:text-ods-text-primary bg-transparent hover:bg-ods-card-hover border border-ods-border rounded-md px-2 py-1 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus";
|
|
37813
37913
|
|
|
@@ -39283,6 +39383,11 @@ export {
|
|
|
39283
39383
|
useNatsChatAdapter,
|
|
39284
39384
|
useUnifiedChat,
|
|
39285
39385
|
extractIncompleteMessageState,
|
|
39386
|
+
SYNTHETIC_REALTIME_ID_PREFIXES,
|
|
39387
|
+
flattenMessagePagesChronological,
|
|
39388
|
+
maxPersistedStreamSeq,
|
|
39389
|
+
mergeHistoryWithRealtime,
|
|
39390
|
+
computeHistoryPrepend,
|
|
39286
39391
|
CHIP_ACTION_BUTTON_CLASS,
|
|
39287
39392
|
chatChipClass,
|
|
39288
39393
|
clickupTaskUrl,
|
|
@@ -39610,4 +39715,4 @@ export {
|
|
|
39610
39715
|
LogsList,
|
|
39611
39716
|
assets
|
|
39612
39717
|
};
|
|
39613
|
-
//# sourceMappingURL=chunk-
|
|
39718
|
+
//# sourceMappingURL=chunk-D2BC3NZ2.js.map
|