@flamingo-stack/openframe-frontend-core 0.0.660-snapshot.20260923164839 → 0.0.660
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-5LS7KNAU.js → chunk-2DLM3NXE.js} +5 -5
- package/dist/{chunk-RFGXKRRL.js → chunk-6DVSTVUU.js} +6 -6
- package/dist/{chunk-EUT6SQW7.js → chunk-6KR74SOJ.js} +3 -3
- package/dist/{chunk-ZASHVL45.cjs → chunk-AOOORZI5.cjs} +3 -3
- package/dist/{chunk-ZASHVL45.cjs.map → chunk-AOOORZI5.cjs.map} +1 -1
- package/dist/{chunk-Z572FXXM.js → chunk-APWQTZCR.js} +2 -2
- package/dist/{chunk-M23ZPKOK.js → chunk-E7C3F2SK.js} +2 -2
- package/dist/{chunk-XOA32PN3.cjs → chunk-EOGXNLZC.cjs} +22 -22
- package/dist/{chunk-XOA32PN3.cjs.map → chunk-EOGXNLZC.cjs.map} +1 -1
- package/dist/{chunk-6VY6PXAN.cjs → chunk-GDHV5W5C.cjs} +33 -33
- package/dist/{chunk-6VY6PXAN.cjs.map → chunk-GDHV5W5C.cjs.map} +1 -1
- package/dist/{chunk-4NKKPGDN.js → chunk-H7ORPMRH.js} +19 -21
- package/dist/{chunk-4NKKPGDN.js.map → chunk-H7ORPMRH.js.map} +1 -1
- package/dist/{chunk-D7QWYQBQ.cjs → chunk-ITVLOEGF.cjs} +71 -71
- package/dist/{chunk-D7QWYQBQ.cjs.map → chunk-ITVLOEGF.cjs.map} +1 -1
- package/dist/{chunk-RPHRBZG6.cjs → chunk-K4W3II7M.cjs} +3 -3
- package/dist/{chunk-RPHRBZG6.cjs.map → chunk-K4W3II7M.cjs.map} +1 -1
- package/dist/{chunk-IMDYBINC.js → chunk-KP4K6I5O.js} +3 -3
- package/dist/{chunk-H3DF7COI.cjs → chunk-L4YJU3AG.cjs} +15 -15
- package/dist/{chunk-H3DF7COI.cjs.map → chunk-L4YJU3AG.cjs.map} +1 -1
- package/dist/{chunk-GXHZCGVJ.cjs → chunk-LSVQNRX4.cjs} +19 -21
- package/dist/chunk-LSVQNRX4.cjs.map +1 -0
- package/dist/{chunk-U4N65JUW.js → chunk-MEFCA6VD.js} +3 -3
- package/dist/{chunk-FC6I2NWF.js → chunk-MW7LEMFG.js} +2 -2
- package/dist/{chunk-QARWK4LN.cjs → chunk-NXAXZPEO.cjs} +10 -10
- package/dist/{chunk-QARWK4LN.cjs.map → chunk-NXAXZPEO.cjs.map} +1 -1
- package/dist/{chunk-PC5WWTDM.js → chunk-P2ROGTMF.js} +3 -3
- package/dist/{chunk-ZIT4TC5R.cjs → chunk-PUE4XMZK.cjs} +163 -163
- package/dist/{chunk-ZIT4TC5R.cjs.map → chunk-PUE4XMZK.cjs.map} +1 -1
- package/dist/{chunk-WDJT7NJ5.js → chunk-QVZD2LLU.js} +5 -5
- package/dist/{chunk-4EY5JSMK.cjs → chunk-RRGTBH3L.cjs} +5 -5
- package/dist/{chunk-4EY5JSMK.cjs.map → chunk-RRGTBH3L.cjs.map} +1 -1
- package/dist/{chunk-Q4XWYP5U.js → chunk-T6LNAX4R.js} +4 -4
- package/dist/{chunk-7KNVRRI4.cjs → chunk-UIAXQJPV.cjs} +22 -22
- package/dist/{chunk-7KNVRRI4.cjs.map → chunk-UIAXQJPV.cjs.map} +1 -1
- package/dist/{chunk-F5LMTKQD.js → chunk-VFGBRGFB.js} +3 -3
- package/dist/{chunk-YNW3DQFY.cjs → chunk-VJMPYY5O.cjs} +25 -25
- package/dist/{chunk-YNW3DQFY.cjs.map → chunk-VJMPYY5O.cjs.map} +1 -1
- package/dist/{chunk-TRR6XUEP.js → chunk-VVOI2OC3.js} +2 -2
- package/dist/{chunk-4JITKV2S.cjs → chunk-VW7NXM2O.cjs} +45 -45
- package/dist/{chunk-4JITKV2S.cjs.map → chunk-VW7NXM2O.cjs.map} +1 -1
- package/dist/{chunk-WGTKYVBK.cjs → chunk-VWGFJJD6.cjs} +10 -10
- package/dist/{chunk-WGTKYVBK.cjs.map → chunk-VWGFJJD6.cjs.map} +1 -1
- package/dist/{chunk-GLDXZK76.cjs → chunk-WMIB6JSA.cjs} +4 -4
- package/dist/{chunk-GLDXZK76.cjs.map → chunk-WMIB6JSA.cjs.map} +1 -1
- package/dist/{chunk-KCYGLC7Q.js → chunk-WWEQT2WX.js} +5 -5
- package/dist/{chunk-N4ORXOZK.cjs → chunk-Z7NI2TQD.cjs} +10 -10
- package/dist/{chunk-N4ORXOZK.cjs.map → chunk-Z7NI2TQD.cjs.map} +1 -1
- package/dist/{chunk-J5TAB64U.js → chunk-ZT3CZCDS.js} +2 -2
- package/dist/components/case-studies/index.cjs +14 -14
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/utils/history-merge.d.ts +0 -6
- package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +7 -7
- package/dist/components/docs/index.js +6 -6
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +4 -4
- package/dist/components/faq/index.js +3 -3
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/help-center-pages/index.cjs +23 -23
- package/dist/components/help-center-pages/index.js +14 -14
- package/dist/components/index.cjs +39 -39
- package/dist/components/index.js +13 -13
- package/dist/components/meeting-scheduler/index.cjs +24 -24
- package/dist/components/meeting-scheduler/index.js +2 -2
- package/dist/components/navigation/index.cjs +6 -6
- package/dist/components/navigation/index.js +5 -5
- package/dist/components/onboarding-guides/index.cjs +6 -6
- package/dist/components/onboarding-guides/index.js +5 -5
- package/dist/components/tickets/index.cjs +7 -7
- package/dist/components/tickets/index.js +6 -6
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/index.cjs +7 -7
- package/dist/index.js +6 -6
- package/package.json +1 -1
- package/src/components/chat/utils/__tests__/history-merge.test.ts +0 -62
- package/src/components/chat/utils/history-merge.ts +17 -31
- package/dist/chunk-GXHZCGVJ.cjs.map +0 -1
- /package/dist/{chunk-5LS7KNAU.js.map → chunk-2DLM3NXE.js.map} +0 -0
- /package/dist/{chunk-RFGXKRRL.js.map → chunk-6DVSTVUU.js.map} +0 -0
- /package/dist/{chunk-EUT6SQW7.js.map → chunk-6KR74SOJ.js.map} +0 -0
- /package/dist/{chunk-Z572FXXM.js.map → chunk-APWQTZCR.js.map} +0 -0
- /package/dist/{chunk-M23ZPKOK.js.map → chunk-E7C3F2SK.js.map} +0 -0
- /package/dist/{chunk-IMDYBINC.js.map → chunk-KP4K6I5O.js.map} +0 -0
- /package/dist/{chunk-U4N65JUW.js.map → chunk-MEFCA6VD.js.map} +0 -0
- /package/dist/{chunk-FC6I2NWF.js.map → chunk-MW7LEMFG.js.map} +0 -0
- /package/dist/{chunk-PC5WWTDM.js.map → chunk-P2ROGTMF.js.map} +0 -0
- /package/dist/{chunk-WDJT7NJ5.js.map → chunk-QVZD2LLU.js.map} +0 -0
- /package/dist/{chunk-Q4XWYP5U.js.map → chunk-T6LNAX4R.js.map} +0 -0
- /package/dist/{chunk-F5LMTKQD.js.map → chunk-VFGBRGFB.js.map} +0 -0
- /package/dist/{chunk-TRR6XUEP.js.map → chunk-VVOI2OC3.js.map} +0 -0
- /package/dist/{chunk-KCYGLC7Q.js.map → chunk-WWEQT2WX.js.map} +0 -0
- /package/dist/{chunk-J5TAB64U.js.map → chunk-ZT3CZCDS.js.map} +0 -0
|
@@ -24,12 +24,6 @@ export interface MergeableChatMessage {
|
|
|
24
24
|
role: string;
|
|
25
25
|
content: MessageContent;
|
|
26
26
|
timestamp?: Date;
|
|
27
|
-
/** Who authored a `user`-role row: the host's own user (`'user'` / unset),
|
|
28
|
-
* a technician (`'admin'`) or the system (`'system'`). Every host renders
|
|
29
|
-
* technician and system lines under role `user`, so a user row's twin must
|
|
30
|
-
* match on this as well as on text - otherwise the end user's "?" is taken
|
|
31
|
-
* for the twin of the technician's "?" and dropped from the thread. */
|
|
32
|
-
authorType?: string;
|
|
33
27
|
/** Highest CONTENT chunk streamSeq that composed this message (text / tool /
|
|
34
28
|
* approval / error / compaction — never the non-persisted MESSAGE_END /
|
|
35
29
|
* TOKEN_USAGE control chunks). Hosts stamp it on realtime synthetics so the
|
|
@@ -160,17 +154,10 @@ function sharesRequestKey(keys: ReadonlySet<string>, others: ReadonlySet<string>
|
|
|
160
154
|
return false;
|
|
161
155
|
}
|
|
162
156
|
|
|
163
|
-
/** A user row's identity is its text
|
|
164
|
-
*
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
* technician who typed the same text is the own bubble's "twin", and the own
|
|
168
|
-
* bubble is dropped while its row is not in the snapshot yet. An unset
|
|
169
|
-
* authorType is the own user (hosts stamp `'admin'` on their own sends where
|
|
170
|
-
* the operator IS the admin, so the rule stays symmetric per host). */
|
|
171
|
-
function userTwinKey(m: MergeableChatMessage): string {
|
|
172
|
-
if (m.role !== 'user' || typeof m.content !== 'string' || m.content === '') return '';
|
|
173
|
-
return `${m.authorType ?? 'user'}\u0000${m.content}`;
|
|
157
|
+
/** A user row's identity is its text; empty text is no identity (system rows
|
|
158
|
+
* persist with `content: ''`). `''` for any other row. */
|
|
159
|
+
function userText(m: MergeableChatMessage): string {
|
|
160
|
+
return m.role === 'user' && typeof m.content === 'string' ? m.content : '';
|
|
174
161
|
}
|
|
175
162
|
|
|
176
163
|
/** What a set of rows says about the turns they render, so another copy of one
|
|
@@ -195,8 +182,8 @@ function collectTwinSignals(rows: readonly MergeableChatMessage[]): TwinSignals
|
|
|
195
182
|
if (text !== '') signals.assistantTexts.set(text, (signals.assistantTexts.get(text) ?? 0) + 1);
|
|
196
183
|
continue;
|
|
197
184
|
}
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
185
|
+
const text = userText(row);
|
|
186
|
+
if (text !== '') signals.userContents.set(text, (signals.userContents.get(text) ?? 0) + 1);
|
|
200
187
|
}
|
|
201
188
|
return signals;
|
|
202
189
|
}
|
|
@@ -211,9 +198,9 @@ type TwinVerdict = 'twin' | 'distinct' | 'unknown';
|
|
|
211
198
|
* request id, no answer text), so "no match" says nothing about it. */
|
|
212
199
|
function twinVerdict(signals: TwinSignals, m: MergeableChatMessage): TwinVerdict {
|
|
213
200
|
if (m.role !== 'assistant') {
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
-
return signals.userContents.has(
|
|
201
|
+
const text = userText(m);
|
|
202
|
+
if (text === '') return 'unknown';
|
|
203
|
+
return signals.userContents.has(text) ? 'twin' : 'distinct';
|
|
217
204
|
}
|
|
218
205
|
const keys = turnRequestKeys(m.content);
|
|
219
206
|
if (keys.size > 0) return sharesRequestKey(keys, signals.requestKeys) ? 'twin' : 'distinct';
|
|
@@ -542,7 +529,7 @@ export function mergeHistoryWithRealtime<M extends MergeableChatMessage>(input:
|
|
|
542
529
|
// optimistic messages are minted on send, never by chunk replay, so
|
|
543
530
|
// their timestamps are trustworthy.
|
|
544
531
|
const canBeInSnapshot = (m.timestamp?.getTime() ?? 0) <= historyFetchedAt;
|
|
545
|
-
return !(canBeInSnapshot && windowSignals.userContents.has(
|
|
532
|
+
return !(canBeInSnapshot && windowSignals.userContents.has(m.content));
|
|
546
533
|
}
|
|
547
534
|
// Freshness rule: a synthetic whose turn is represented in the snapshot
|
|
548
535
|
// (under its persisted Mongo id) must be dropped or the turn renders
|
|
@@ -573,11 +560,10 @@ export function mergeHistoryWithRealtime<M extends MergeableChatMessage>(input:
|
|
|
573
560
|
// already does for DIRECT/SYSTEM), which also stops the replay at the
|
|
574
561
|
// source via a correct `optStartSeq`.
|
|
575
562
|
if (m.role === 'user' && isUserRequestSyntheticId(m.id) && typeof m.content === 'string') {
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
seenUserSyntheticByContent.set(twinKey, seen);
|
|
563
|
+
const seen = (seenUserSyntheticByContent.get(m.content) ?? 0) + 1;
|
|
564
|
+
seenUserSyntheticByContent.set(m.content, seen);
|
|
579
565
|
// No persisted row for THIS occurrence slot → keep (nothing renders it).
|
|
580
|
-
if ((windowSignals.userContents.get(
|
|
566
|
+
if ((windowSignals.userContents.get(m.content) ?? 0) < seen) return true;
|
|
581
567
|
// A same-text persisted twin exists for this slot. User rows carry no
|
|
582
568
|
// persisted seq, so that twin may be THIS message's OWN row (drop — it
|
|
583
569
|
// renders the message) OR an OLDER identical-text turn while this is a
|
|
@@ -596,7 +582,7 @@ export function mergeHistoryWithRealtime<M extends MergeableChatMessage>(input:
|
|
|
596
582
|
if (typeof m.streamSeq !== 'number' || historyMaxStreamSeq <= 0) return false;
|
|
597
583
|
if (historyMaxStreamSeq >= m.streamSeq) return false;
|
|
598
584
|
const lastPersisted = processedToUse[processedToUse.length - 1];
|
|
599
|
-
if (lastPersisted &&
|
|
585
|
+
if (lastPersisted && lastPersisted.role === 'user' && lastPersisted.content === m.content) return false;
|
|
600
586
|
return true;
|
|
601
587
|
}
|
|
602
588
|
// Per-message seq coverage for the remaining synthetics (assistant /
|
|
@@ -715,10 +701,10 @@ export function computeHistoryPrepend<M extends MergeableChatMessage>(
|
|
|
715
701
|
for (let i = newEnd - 1; i >= 0; i--) {
|
|
716
702
|
const pm = processedHistory[i];
|
|
717
703
|
if (pm.role === 'user') {
|
|
718
|
-
const
|
|
719
|
-
const left =
|
|
704
|
+
const text = userText(pm);
|
|
705
|
+
const left = text === '' ? 0 : (userTwinsLeft.get(text) ?? 0);
|
|
720
706
|
if (left === 0) continue;
|
|
721
|
-
userTwinsLeft.set(
|
|
707
|
+
userTwinsLeft.set(text, left - 1);
|
|
722
708
|
twinIndices.add(i);
|
|
723
709
|
} else if (pm.role === 'assistant') {
|
|
724
710
|
const keys = turnRequestKeys(pm.content);
|