@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.
Files changed (100) hide show
  1. package/dist/{chunk-5LS7KNAU.js → chunk-2DLM3NXE.js} +5 -5
  2. package/dist/{chunk-RFGXKRRL.js → chunk-6DVSTVUU.js} +6 -6
  3. package/dist/{chunk-EUT6SQW7.js → chunk-6KR74SOJ.js} +3 -3
  4. package/dist/{chunk-ZASHVL45.cjs → chunk-AOOORZI5.cjs} +3 -3
  5. package/dist/{chunk-ZASHVL45.cjs.map → chunk-AOOORZI5.cjs.map} +1 -1
  6. package/dist/{chunk-Z572FXXM.js → chunk-APWQTZCR.js} +2 -2
  7. package/dist/{chunk-M23ZPKOK.js → chunk-E7C3F2SK.js} +2 -2
  8. package/dist/{chunk-XOA32PN3.cjs → chunk-EOGXNLZC.cjs} +22 -22
  9. package/dist/{chunk-XOA32PN3.cjs.map → chunk-EOGXNLZC.cjs.map} +1 -1
  10. package/dist/{chunk-6VY6PXAN.cjs → chunk-GDHV5W5C.cjs} +33 -33
  11. package/dist/{chunk-6VY6PXAN.cjs.map → chunk-GDHV5W5C.cjs.map} +1 -1
  12. package/dist/{chunk-4NKKPGDN.js → chunk-H7ORPMRH.js} +19 -21
  13. package/dist/{chunk-4NKKPGDN.js.map → chunk-H7ORPMRH.js.map} +1 -1
  14. package/dist/{chunk-D7QWYQBQ.cjs → chunk-ITVLOEGF.cjs} +71 -71
  15. package/dist/{chunk-D7QWYQBQ.cjs.map → chunk-ITVLOEGF.cjs.map} +1 -1
  16. package/dist/{chunk-RPHRBZG6.cjs → chunk-K4W3II7M.cjs} +3 -3
  17. package/dist/{chunk-RPHRBZG6.cjs.map → chunk-K4W3II7M.cjs.map} +1 -1
  18. package/dist/{chunk-IMDYBINC.js → chunk-KP4K6I5O.js} +3 -3
  19. package/dist/{chunk-H3DF7COI.cjs → chunk-L4YJU3AG.cjs} +15 -15
  20. package/dist/{chunk-H3DF7COI.cjs.map → chunk-L4YJU3AG.cjs.map} +1 -1
  21. package/dist/{chunk-GXHZCGVJ.cjs → chunk-LSVQNRX4.cjs} +19 -21
  22. package/dist/chunk-LSVQNRX4.cjs.map +1 -0
  23. package/dist/{chunk-U4N65JUW.js → chunk-MEFCA6VD.js} +3 -3
  24. package/dist/{chunk-FC6I2NWF.js → chunk-MW7LEMFG.js} +2 -2
  25. package/dist/{chunk-QARWK4LN.cjs → chunk-NXAXZPEO.cjs} +10 -10
  26. package/dist/{chunk-QARWK4LN.cjs.map → chunk-NXAXZPEO.cjs.map} +1 -1
  27. package/dist/{chunk-PC5WWTDM.js → chunk-P2ROGTMF.js} +3 -3
  28. package/dist/{chunk-ZIT4TC5R.cjs → chunk-PUE4XMZK.cjs} +163 -163
  29. package/dist/{chunk-ZIT4TC5R.cjs.map → chunk-PUE4XMZK.cjs.map} +1 -1
  30. package/dist/{chunk-WDJT7NJ5.js → chunk-QVZD2LLU.js} +5 -5
  31. package/dist/{chunk-4EY5JSMK.cjs → chunk-RRGTBH3L.cjs} +5 -5
  32. package/dist/{chunk-4EY5JSMK.cjs.map → chunk-RRGTBH3L.cjs.map} +1 -1
  33. package/dist/{chunk-Q4XWYP5U.js → chunk-T6LNAX4R.js} +4 -4
  34. package/dist/{chunk-7KNVRRI4.cjs → chunk-UIAXQJPV.cjs} +22 -22
  35. package/dist/{chunk-7KNVRRI4.cjs.map → chunk-UIAXQJPV.cjs.map} +1 -1
  36. package/dist/{chunk-F5LMTKQD.js → chunk-VFGBRGFB.js} +3 -3
  37. package/dist/{chunk-YNW3DQFY.cjs → chunk-VJMPYY5O.cjs} +25 -25
  38. package/dist/{chunk-YNW3DQFY.cjs.map → chunk-VJMPYY5O.cjs.map} +1 -1
  39. package/dist/{chunk-TRR6XUEP.js → chunk-VVOI2OC3.js} +2 -2
  40. package/dist/{chunk-4JITKV2S.cjs → chunk-VW7NXM2O.cjs} +45 -45
  41. package/dist/{chunk-4JITKV2S.cjs.map → chunk-VW7NXM2O.cjs.map} +1 -1
  42. package/dist/{chunk-WGTKYVBK.cjs → chunk-VWGFJJD6.cjs} +10 -10
  43. package/dist/{chunk-WGTKYVBK.cjs.map → chunk-VWGFJJD6.cjs.map} +1 -1
  44. package/dist/{chunk-GLDXZK76.cjs → chunk-WMIB6JSA.cjs} +4 -4
  45. package/dist/{chunk-GLDXZK76.cjs.map → chunk-WMIB6JSA.cjs.map} +1 -1
  46. package/dist/{chunk-KCYGLC7Q.js → chunk-WWEQT2WX.js} +5 -5
  47. package/dist/{chunk-N4ORXOZK.cjs → chunk-Z7NI2TQD.cjs} +10 -10
  48. package/dist/{chunk-N4ORXOZK.cjs.map → chunk-Z7NI2TQD.cjs.map} +1 -1
  49. package/dist/{chunk-J5TAB64U.js → chunk-ZT3CZCDS.js} +2 -2
  50. package/dist/components/case-studies/index.cjs +14 -14
  51. package/dist/components/case-studies/index.js +3 -3
  52. package/dist/components/chat/index.cjs +2 -2
  53. package/dist/components/chat/index.js +1 -1
  54. package/dist/components/chat/utils/history-merge.d.ts +0 -6
  55. package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
  56. package/dist/components/contact/index.cjs +4 -4
  57. package/dist/components/contact/index.js +3 -3
  58. package/dist/components/docs/index.cjs +7 -7
  59. package/dist/components/docs/index.js +6 -6
  60. package/dist/components/embeds/index.cjs +4 -4
  61. package/dist/components/embeds/index.js +3 -3
  62. package/dist/components/faq/index.cjs +4 -4
  63. package/dist/components/faq/index.js +3 -3
  64. package/dist/components/features/index.cjs +3 -3
  65. package/dist/components/features/index.js +2 -2
  66. package/dist/components/help-center-pages/index.cjs +23 -23
  67. package/dist/components/help-center-pages/index.js +14 -14
  68. package/dist/components/index.cjs +39 -39
  69. package/dist/components/index.js +13 -13
  70. package/dist/components/meeting-scheduler/index.cjs +24 -24
  71. package/dist/components/meeting-scheduler/index.js +2 -2
  72. package/dist/components/navigation/index.cjs +6 -6
  73. package/dist/components/navigation/index.js +5 -5
  74. package/dist/components/onboarding-guides/index.cjs +6 -6
  75. package/dist/components/onboarding-guides/index.js +5 -5
  76. package/dist/components/tickets/index.cjs +7 -7
  77. package/dist/components/tickets/index.js +6 -6
  78. package/dist/components/ui/index.cjs +3 -3
  79. package/dist/components/ui/index.js +2 -2
  80. package/dist/index.cjs +7 -7
  81. package/dist/index.js +6 -6
  82. package/package.json +1 -1
  83. package/src/components/chat/utils/__tests__/history-merge.test.ts +0 -62
  84. package/src/components/chat/utils/history-merge.ts +17 -31
  85. package/dist/chunk-GXHZCGVJ.cjs.map +0 -1
  86. /package/dist/{chunk-5LS7KNAU.js.map → chunk-2DLM3NXE.js.map} +0 -0
  87. /package/dist/{chunk-RFGXKRRL.js.map → chunk-6DVSTVUU.js.map} +0 -0
  88. /package/dist/{chunk-EUT6SQW7.js.map → chunk-6KR74SOJ.js.map} +0 -0
  89. /package/dist/{chunk-Z572FXXM.js.map → chunk-APWQTZCR.js.map} +0 -0
  90. /package/dist/{chunk-M23ZPKOK.js.map → chunk-E7C3F2SK.js.map} +0 -0
  91. /package/dist/{chunk-IMDYBINC.js.map → chunk-KP4K6I5O.js.map} +0 -0
  92. /package/dist/{chunk-U4N65JUW.js.map → chunk-MEFCA6VD.js.map} +0 -0
  93. /package/dist/{chunk-FC6I2NWF.js.map → chunk-MW7LEMFG.js.map} +0 -0
  94. /package/dist/{chunk-PC5WWTDM.js.map → chunk-P2ROGTMF.js.map} +0 -0
  95. /package/dist/{chunk-WDJT7NJ5.js.map → chunk-QVZD2LLU.js.map} +0 -0
  96. /package/dist/{chunk-Q4XWYP5U.js.map → chunk-T6LNAX4R.js.map} +0 -0
  97. /package/dist/{chunk-F5LMTKQD.js.map → chunk-VFGBRGFB.js.map} +0 -0
  98. /package/dist/{chunk-TRR6XUEP.js.map → chunk-VVOI2OC3.js.map} +0 -0
  99. /package/dist/{chunk-KCYGLC7Q.js.map → chunk-WWEQT2WX.js.map} +0 -0
  100. /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 under its author kind; empty text is no
164
- * identity (system rows persist with `content: ''`). `''` for any other row.
165
- * The kind is part of the key because technician (`authorType: 'admin'`) and
166
- * system rows share role `user` with the host's own sends: without it a
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 key = userTwinKey(row);
199
- if (key !== '') signals.userContents.set(key, (signals.userContents.get(key) ?? 0) + 1);
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 key = userTwinKey(m);
215
- if (key === '') return 'unknown';
216
- return signals.userContents.has(key) ? 'twin' : 'distinct';
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(userTwinKey(m)));
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 twinKey = userTwinKey(m);
577
- const seen = (seenUserSyntheticByContent.get(twinKey) ?? 0) + 1;
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(twinKey) ?? 0) < seen) return true;
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 && userTwinKey(lastPersisted) === twinKey) return false;
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 key = userTwinKey(pm);
719
- const left = key === '' ? 0 : (userTwinsLeft.get(key) ?? 0);
704
+ const text = userText(pm);
705
+ const left = text === '' ? 0 : (userTwinsLeft.get(text) ?? 0);
720
706
  if (left === 0) continue;
721
- userTwinsLeft.set(key, left - 1);
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);