@flamingo-stack/openframe-frontend-core 0.0.243 → 0.0.244

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 (131) hide show
  1. package/dist/{chunk-MKVKVJQQ.js → chunk-APGMNHPY.js} +19 -32
  2. package/dist/chunk-APGMNHPY.js.map +1 -0
  3. package/dist/{chunk-3TDLFCCS.cjs → chunk-DV3YZWGN.cjs} +20 -33
  4. package/dist/chunk-DV3YZWGN.cjs.map +1 -0
  5. package/dist/{chunk-BKPS6M2F.cjs → chunk-EJ7J4QAD.cjs} +12 -12
  6. package/dist/{chunk-BKPS6M2F.cjs.map → chunk-EJ7J4QAD.cjs.map} +1 -1
  7. package/dist/{chunk-CZITXP77.cjs → chunk-EPXROXYC.cjs} +713 -645
  8. package/dist/chunk-EPXROXYC.cjs.map +1 -0
  9. package/dist/{chunk-SGJBUL2Y.cjs → chunk-FSS2MIEA.cjs} +3 -20
  10. package/dist/chunk-FSS2MIEA.cjs.map +1 -0
  11. package/dist/{chunk-VAUI3CND.js → chunk-LJGBFD52.js} +1 -18
  12. package/dist/chunk-LJGBFD52.js.map +1 -0
  13. package/dist/{chunk-FRRMXLU5.js → chunk-M7DPUWAL.js} +188 -120
  14. package/dist/chunk-M7DPUWAL.js.map +1 -0
  15. package/dist/{chunk-SEVJT2HP.js → chunk-NKGNRFSS.js} +8 -8
  16. package/dist/{chunk-VFKQMAUF.cjs → chunk-OB45JHDY.cjs} +3 -3
  17. package/dist/{chunk-VFKQMAUF.cjs.map → chunk-OB45JHDY.cjs.map} +1 -1
  18. package/dist/{chunk-4XLJWX2N.js → chunk-ORJREQ2W.js} +4 -4
  19. package/dist/{chunk-7ZHFCEJH.js → chunk-P5C732SC.js} +6 -6
  20. package/dist/{chunk-JJV3XGCY.js → chunk-PTSAF7T2.js} +2 -2
  21. package/dist/{chunk-VXP553WT.cjs → chunk-RJC3L5DT.cjs} +7 -7
  22. package/dist/{chunk-VXP553WT.cjs.map → chunk-RJC3L5DT.cjs.map} +1 -1
  23. package/dist/{chunk-MP5HOP7N.cjs → chunk-STKMIMLP.cjs} +12 -12
  24. package/dist/{chunk-MP5HOP7N.cjs.map → chunk-STKMIMLP.cjs.map} +1 -1
  25. package/dist/{chunk-V35PZSUA.js → chunk-WD2MZVJI.js} +5 -5
  26. package/dist/{chunk-DUZBTUXF.cjs → chunk-Z6GGYZDR.cjs} +27 -27
  27. package/dist/{chunk-DUZBTUXF.cjs.map → chunk-Z6GGYZDR.cjs.map} +1 -1
  28. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  29. package/dist/components/chat/hooks/use-chat-card-item.d.ts.map +1 -1
  30. package/dist/components/chat/index.cjs +16 -6
  31. package/dist/components/chat/index.cjs.map +1 -1
  32. package/dist/components/chat/index.js +15 -5
  33. package/dist/components/chat/types/entities/content-ref.d.ts +20 -5
  34. package/dist/components/chat/types/entities/content-ref.d.ts.map +1 -1
  35. package/dist/components/chat/utils/history-merge.d.ts +92 -0
  36. package/dist/components/chat/utils/history-merge.d.ts.map +1 -0
  37. package/dist/components/chat/utils/index.d.ts +1 -0
  38. package/dist/components/chat/utils/index.d.ts.map +1 -1
  39. package/dist/components/contact/index.cjs +7 -7
  40. package/dist/components/contact/index.js +6 -6
  41. package/dist/components/faq/faq-section.d.ts +1 -7
  42. package/dist/components/faq/faq-section.d.ts.map +1 -1
  43. package/dist/components/faq/index.cjs +3 -3
  44. package/dist/components/faq/index.js +2 -2
  45. package/dist/components/features/index.cjs +6 -6
  46. package/dist/components/features/index.js +5 -5
  47. package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
  48. package/dist/components/index.cjs +93 -87
  49. package/dist/components/index.cjs.map +1 -1
  50. package/dist/components/index.d.ts +0 -1
  51. package/dist/components/index.d.ts.map +1 -1
  52. package/dist/components/index.js +37 -31
  53. package/dist/components/index.js.map +1 -1
  54. package/dist/components/navigation/index.cjs +6 -6
  55. package/dist/components/navigation/index.js +5 -5
  56. package/dist/components/onboarding-guides/index.cjs +30 -30
  57. package/dist/components/onboarding-guides/index.cjs.map +1 -1
  58. package/dist/components/onboarding-guides/index.js +11 -11
  59. package/dist/components/tickets/index.cjs +73 -73
  60. package/dist/components/tickets/index.cjs.map +1 -1
  61. package/dist/components/tickets/index.js +15 -15
  62. package/dist/components/ui/index.cjs +19 -9
  63. package/dist/components/ui/index.cjs.map +1 -1
  64. package/dist/components/ui/index.js +23 -13
  65. package/dist/embed-shims/index.cjs +3 -3
  66. package/dist/embed-shims/index.cjs.map +1 -1
  67. package/dist/embed-shims/index.js +5 -5
  68. package/dist/index.cjs +11 -17
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/index.js +49 -55
  71. package/dist/types/index.d.ts +0 -1
  72. package/dist/types/index.d.ts.map +1 -1
  73. package/dist/utils/index.cjs +0 -81
  74. package/dist/utils/index.cjs.map +1 -1
  75. package/dist/utils/index.d.ts +1 -4
  76. package/dist/utils/index.d.ts.map +1 -1
  77. package/dist/utils/index.js +1 -74
  78. package/dist/utils/index.js.map +1 -1
  79. package/dist/utils/list-url.d.ts +0 -6
  80. package/dist/utils/list-url.d.ts.map +1 -1
  81. package/package.json +1 -7
  82. package/src/components/chat/__tests__/chat-message-list.test.tsx +92 -0
  83. package/src/components/chat/chat-message-list.tsx +74 -49
  84. package/src/components/chat/hooks/use-chat-card-item.ts +38 -3
  85. package/src/components/chat/types/entities/content-ref.ts +21 -5
  86. package/src/components/chat/utils/__tests__/history-merge.test.ts +339 -0
  87. package/src/components/chat/utils/history-merge.ts +255 -0
  88. package/src/components/chat/utils/index.ts +12 -0
  89. package/src/components/faq/faq-section.tsx +24 -69
  90. package/src/components/features/policy-configuration-panel.tsx +1 -0
  91. package/src/components/index.ts +0 -1
  92. package/src/types/index.ts +0 -1
  93. package/src/utils/index.ts +1 -16
  94. package/src/utils/list-url.ts +0 -9
  95. package/dist/chunk-3TDLFCCS.cjs.map +0 -1
  96. package/dist/chunk-CZITXP77.cjs.map +0 -1
  97. package/dist/chunk-F3GMWNAT.js +0 -285
  98. package/dist/chunk-F3GMWNAT.js.map +0 -1
  99. package/dist/chunk-FRRMXLU5.js.map +0 -1
  100. package/dist/chunk-HU252PYJ.cjs +0 -285
  101. package/dist/chunk-HU252PYJ.cjs.map +0 -1
  102. package/dist/chunk-MKVKVJQQ.js.map +0 -1
  103. package/dist/chunk-SGJBUL2Y.cjs.map +0 -1
  104. package/dist/chunk-VAUI3CND.js.map +0 -1
  105. package/dist/components/related-content/index.cjs +0 -26
  106. package/dist/components/related-content/index.cjs.map +0 -1
  107. package/dist/components/related-content/index.d.ts +0 -2
  108. package/dist/components/related-content/index.d.ts.map +0 -1
  109. package/dist/components/related-content/index.js +0 -26
  110. package/dist/components/related-content/index.js.map +0 -1
  111. package/dist/components/related-content/related-content-section.d.ts +0 -141
  112. package/dist/components/related-content/related-content-section.d.ts.map +0 -1
  113. package/dist/types/content-ref.d.ts +0 -35
  114. package/dist/types/content-ref.d.ts.map +0 -1
  115. package/dist/utils/content-ref-groups.d.ts +0 -58
  116. package/dist/utils/content-ref-groups.d.ts.map +0 -1
  117. package/dist/utils/extract-items.d.ts +0 -18
  118. package/dist/utils/extract-items.d.ts.map +0 -1
  119. package/dist/utils/suggestion-url.d.ts +0 -26
  120. package/dist/utils/suggestion-url.d.ts.map +0 -1
  121. package/src/components/related-content/index.ts +0 -9
  122. package/src/components/related-content/related-content-section.tsx +0 -612
  123. package/src/types/content-ref.ts +0 -34
  124. package/src/utils/content-ref-groups.ts +0 -89
  125. package/src/utils/extract-items.ts +0 -48
  126. package/src/utils/suggestion-url.ts +0 -39
  127. /package/dist/{chunk-SEVJT2HP.js.map → chunk-NKGNRFSS.js.map} +0 -0
  128. /package/dist/{chunk-4XLJWX2N.js.map → chunk-ORJREQ2W.js.map} +0 -0
  129. /package/dist/{chunk-7ZHFCEJH.js.map → chunk-P5C732SC.js.map} +0 -0
  130. /package/dist/{chunk-JJV3XGCY.js.map → chunk-PTSAF7T2.js.map} +0 -0
  131. /package/dist/{chunk-V35PZSUA.js.map → chunk-WD2MZVJI.js.map} +0 -0
@@ -1,25 +1,9 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }"use client";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }"use client";
2
2
 
3
3
 
4
4
 
5
5
  var _chunkFIG2RKZFcjs = require('./chunk-FIG2RKZF.cjs');
6
6
 
7
- // src/utils/suggestion-url.ts
8
- function buildSuggestionUrl(path, opts = {}) {
9
- const qs = new URLSearchParams();
10
- const { entityType, entityId } = opts;
11
- if (entityType && entityId !== void 0 && entityId !== null && entityId !== "") {
12
- qs.set("entityType", entityType);
13
- qs.set("entityId", String(entityId));
14
- }
15
- if (opts.count !== void 0) qs.set("count", String(opts.count));
16
- for (const [key, value] of Object.entries(_nullishCoalesce(opts.extraParams, () => ( {})))) {
17
- if (value !== void 0 && value !== "") qs.set(key, value);
18
- }
19
- const query = qs.toString();
20
- return `${_nullishCoalesce(opts.apiBaseUrl, () => ( ""))}${path}${query ? `?${query}` : ""}`;
21
- }
22
-
23
7
  // src/components/ui/chevron-button.tsx
24
8
  _chunkFIG2RKZFcjs.init_cn.call(void 0, );
25
9
  var _react = require('react'); var React = _interopRequireWildcard(_react);
@@ -56,6 +40,5 @@ ChevronButton.displayName = "ChevronButton";
56
40
 
57
41
 
58
42
 
59
-
60
- exports.buildSuggestionUrl = buildSuggestionUrl; exports.ChevronButton = ChevronButton;
61
- //# sourceMappingURL=chunk-SGJBUL2Y.cjs.map
43
+ exports.ChevronButton = ChevronButton;
44
+ //# sourceMappingURL=chunk-FSS2MIEA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-FSS2MIEA.cjs","../src/components/ui/chevron-button.tsx"],"names":[],"mappings":"AAAA,uWAAY;AACZ;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACFA,uCAAA,CAAA;AAFA,2EAAuB;AACvB,2CAAuC;AAkC/B,+CAAA;AAvBR,IAAM,cAAA,EAAsB,KAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,SAAA,EAAW,UAAA,EAAY,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,UAAA,EAAY,eAAA,EAAiB,WAAA,EAAa,GAAG,MAAM,CAAA,EAAG,GAAA,EAAA,GAAQ;AAC3G,IAAA,MAAM,KAAA,EAAA,CAAQ,WAAA,EAAa,uBAAA,EAAY,wBAAA,EAAA,GAAA,CAAiB,UAAA,IAAc,KAAA,EAAO,uBAAA,EAAY,wBAAA,CAAA;AACzF,IAAA,MAAM,YAAA,EAAc;AAAA,MAClB,EAAA,EAAI,SAAA;AAAA,MACJ,EAAA,EAAI,SAAA;AAAA,MACJ,EAAA,EAAI;AAAA,IACN,CAAA;AAEA,IAAA,uBACE,6BAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,kCAAA;AAAA,UACT,sQAAA;AAAA,UACA,gBAAA;AAAA,UACA;AAAA,QACF,CAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACL,eAAA;AAAA,UACA;AAAA,QACF,CAAA;AAAA,QACA,GAAA;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,kBAAA,6BAAA,IAAC,EAAA,EAAK,SAAA,EAAW,WAAA,CAAY,IAAI,EAAA,CAAG;AAAA,MAAA;AAAA,IACtC,CAAA;AAAA,EAEJ;AACF,CAAA;AACA,aAAA,CAAc,YAAA,EAAc,eAAA;ADH5B;AACA;AACE;AACF,sCAAC","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-FSS2MIEA.cjs","sourcesContent":[null,"\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronUp, ChevronDown } from \"lucide-react\"\nimport { cn } from \"../../utils/cn\"\n\ninterface ChevronButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n direction?: 'up' | 'down';\n size?: 'sm' | 'md' | 'lg';\n isExpanded?: boolean;\n backgroundColor?: string;\n borderColor?: string;\n}\n\nconst ChevronButton = React.forwardRef<HTMLButtonElement, ChevronButtonProps>(\n ({ className, direction = 'down', size = 'md', isExpanded, backgroundColor, borderColor, ...props }, ref) => {\n const Icon = (isExpanded ? ChevronUp : ChevronDown) || (direction === 'up' ? ChevronUp : ChevronDown);\n const sizeClasses = {\n sm: 'h-4 w-4',\n md: 'h-5 w-5', \n lg: 'h-6 w-6'\n };\n\n return (\n <button\n className={cn(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n \"h-10 px-4 py-2\",\n className\n )}\n style={{\n backgroundColor: backgroundColor,\n borderColor: borderColor\n }}\n ref={ref}\n {...props}\n >\n <Icon className={sizeClasses[size]} />\n </button>\n )\n }\n)\nChevronButton.displayName = \"ChevronButton\"\n\nexport { ChevronButton }"]}
@@ -4,22 +4,6 @@ import {
4
4
  init_cn
5
5
  } from "./chunk-XTCBRQN2.js";
6
6
 
7
- // src/utils/suggestion-url.ts
8
- function buildSuggestionUrl(path, opts = {}) {
9
- const qs = new URLSearchParams();
10
- const { entityType, entityId } = opts;
11
- if (entityType && entityId !== void 0 && entityId !== null && entityId !== "") {
12
- qs.set("entityType", entityType);
13
- qs.set("entityId", String(entityId));
14
- }
15
- if (opts.count !== void 0) qs.set("count", String(opts.count));
16
- for (const [key, value] of Object.entries(opts.extraParams ?? {})) {
17
- if (value !== void 0 && value !== "") qs.set(key, value);
18
- }
19
- const query = qs.toString();
20
- return `${opts.apiBaseUrl ?? ""}${path}${query ? `?${query}` : ""}`;
21
- }
22
-
23
7
  // src/components/ui/chevron-button.tsx
24
8
  init_cn();
25
9
  import * as React from "react";
@@ -55,7 +39,6 @@ var ChevronButton = React.forwardRef(
55
39
  ChevronButton.displayName = "ChevronButton";
56
40
 
57
41
  export {
58
- buildSuggestionUrl,
59
42
  ChevronButton
60
43
  };
61
- //# sourceMappingURL=chunk-VAUI3CND.js.map
44
+ //# sourceMappingURL=chunk-LJGBFD52.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/chevron-button.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronUp, ChevronDown } from \"lucide-react\"\nimport { cn } from \"../../utils/cn\"\n\ninterface ChevronButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n direction?: 'up' | 'down';\n size?: 'sm' | 'md' | 'lg';\n isExpanded?: boolean;\n backgroundColor?: string;\n borderColor?: string;\n}\n\nconst ChevronButton = React.forwardRef<HTMLButtonElement, ChevronButtonProps>(\n ({ className, direction = 'down', size = 'md', isExpanded, backgroundColor, borderColor, ...props }, ref) => {\n const Icon = (isExpanded ? ChevronUp : ChevronDown) || (direction === 'up' ? ChevronUp : ChevronDown);\n const sizeClasses = {\n sm: 'h-4 w-4',\n md: 'h-5 w-5', \n lg: 'h-6 w-6'\n };\n\n return (\n <button\n className={cn(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n \"h-10 px-4 py-2\",\n className\n )}\n style={{\n backgroundColor: backgroundColor,\n borderColor: borderColor\n }}\n ref={ref}\n {...props}\n >\n <Icon className={sizeClasses[size]} />\n </button>\n )\n }\n)\nChevronButton.displayName = \"ChevronButton\"\n\nexport { ChevronButton }"],"mappings":";;;;;;;AAIA;AAFA,YAAY,WAAW;AACvB,SAAS,WAAW,mBAAmB;AAkC/B;AAvBR,IAAM,gBAAsB;AAAA,EAC1B,CAAC,EAAE,WAAW,YAAY,QAAQ,OAAO,MAAM,YAAY,iBAAiB,aAAa,GAAG,MAAM,GAAG,QAAQ;AAC3G,UAAM,QAAQ,aAAa,YAAY,iBAAiB,cAAc,OAAO,YAAY;AACzF,UAAM,cAAc;AAAA,MAClB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QAEJ,8BAAC,QAAK,WAAW,YAAY,IAAI,GAAG;AAAA;AAAA,IACtC;AAAA,EAEJ;AACF;AACA,cAAc,cAAc;","names":[]}
@@ -1,24 +1,4 @@
1
1
  "use client";
2
- import {
3
- ToolIcon,
4
- dotColorByVariant,
5
- getSmallPlatformIcon,
6
- progressColorByVariant,
7
- toolLabels,
8
- useAutoLimitTags,
9
- useCopyToClipboard,
10
- useDebounce,
11
- useHorizontalScrollbar,
12
- useHumanitySignals,
13
- useImageEdgeColor,
14
- useLgUp,
15
- useLocalStorage,
16
- useMdUp,
17
- useNearViewport,
18
- useOgPlaceholder,
19
- useOnboardingState,
20
- useToast
21
- } from "./chunk-UECRKCKH.js";
22
2
  import {
23
3
  useChatRuntime,
24
4
  useRequiredChatRuntime
@@ -29,12 +9,6 @@ import {
29
9
  import {
30
10
  dynamic
31
11
  } from "./chunk-EL5YVPD5.js";
32
- import {
33
- init_next_navigation,
34
- usePathname,
35
- useRouter,
36
- useSearchParams
37
- } from "./chunk-PLJLE4A4.js";
38
12
  import {
39
13
  Button,
40
14
  Checkbox,
@@ -56,6 +30,32 @@ import {
56
30
  init_next_link,
57
31
  next_link_default
58
32
  } from "./chunk-OHPI2HRK.js";
33
+ import {
34
+ ToolIcon,
35
+ dotColorByVariant,
36
+ getSmallPlatformIcon,
37
+ progressColorByVariant,
38
+ toolLabels,
39
+ useAutoLimitTags,
40
+ useCopyToClipboard,
41
+ useDebounce,
42
+ useHorizontalScrollbar,
43
+ useHumanitySignals,
44
+ useImageEdgeColor,
45
+ useLgUp,
46
+ useLocalStorage,
47
+ useMdUp,
48
+ useNearViewport,
49
+ useOgPlaceholder,
50
+ useOnboardingState,
51
+ useToast
52
+ } from "./chunk-UECRKCKH.js";
53
+ import {
54
+ init_next_navigation,
55
+ usePathname,
56
+ useRouter,
57
+ useSearchParams
58
+ } from "./chunk-PLJLE4A4.js";
59
59
  import {
60
60
  BashIcon,
61
61
  ClickUpIcon,
@@ -4397,12 +4397,15 @@ var ChatMessageList = forwardRef13(
4397
4397
  onLoadMoreRef.current = onLoadMore;
4398
4398
  const isFetchingRef = useRef6(isFetchingNextPage);
4399
4399
  isFetchingRef.current = isFetchingNextPage;
4400
+ const dialogIdRef = useRef6(dialogId);
4401
+ dialogIdRef.current = dialogId;
4400
4402
  const prevRenderRef = useRef6({ dialogId: void 0, messageCount: 0, lastMessageId: void 0 });
4401
- const prependRef = useRef6({ firstMessageId: void 0, firstMessageContent: void 0, scrollHeight: 0 });
4403
+ const loadOlderAnchorRef = useRef6(null);
4402
4404
  useEffect6(() => {
4403
4405
  if (!autoScroll) return;
4404
4406
  const dialogChanged = dialogId !== prevRenderRef.current.dialogId;
4405
4407
  const prevCount = prevRenderRef.current.messageCount;
4408
+ const prevLastId = prevRenderRef.current.lastMessageId;
4406
4409
  const newCount = messages.length;
4407
4410
  const currentLastId = messages[messages.length - 1]?.id;
4408
4411
  prevRenderRef.current = { dialogId, messageCount: newCount, lastMessageId: currentLastId };
@@ -4415,7 +4418,8 @@ var ChatMessageList = forwardRef13(
4415
4418
  return;
4416
4419
  }
4417
4420
  if (newCount > prevCount) {
4418
- const newSlice = messages.slice(prevCount);
4421
+ const prevLastIdx = prevLastId ? messages.findIndex((m) => m.id === prevLastId) : -1;
4422
+ const newSlice = prevLastIdx >= 0 ? messages.slice(prevLastIdx + 1) : messages.slice(prevCount);
4419
4423
  const hasNewUser = newSlice.some((m) => m.role === "user");
4420
4424
  if (hasNewUser) {
4421
4425
  void scrollToBottom({ animation: "instant", ignoreEscapes: true });
@@ -4439,34 +4443,17 @@ var ChatMessageList = forwardRef13(
4439
4443
  }, [autoScroll, messages, dialogId, scrollToBottom, contentRef]);
4440
4444
  useLayoutEffect3(() => {
4441
4445
  const el = scrollRef.current;
4442
- if (!el) {
4443
- prependRef.current = { firstMessageId: void 0, firstMessageContent: void 0, scrollHeight: 0 };
4444
- return;
4445
- }
4446
- const currentFirstId = messages[0]?.id;
4447
- const currentFirstContent = messages[0]?.content;
4448
- const prevFirstId = prependRef.current.firstMessageId;
4449
- const prevHeight = prependRef.current.scrollHeight;
4450
- if (currentFirstId !== prevFirstId) {
4451
- if (prevFirstId && prevHeight > 0) {
4452
- const prevIdx = messages.findIndex((m) => m.id === prevFirstId);
4453
- if (prevIdx > 0) {
4454
- const addedHeight = el.scrollHeight - prevHeight;
4455
- if (addedHeight > 0) el.scrollTop += addedHeight;
4456
- }
4457
- }
4458
- prependRef.current = {
4459
- firstMessageId: currentFirstId,
4460
- firstMessageContent: currentFirstContent,
4461
- scrollHeight: el.scrollHeight
4462
- };
4446
+ const anchor = loadOlderAnchorRef.current;
4447
+ if (!el || !anchor) return;
4448
+ if (anchor.dialogId !== dialogId) {
4449
+ loadOlderAnchorRef.current = null;
4463
4450
  return;
4464
4451
  }
4465
- prependRef.current.scrollHeight = el.scrollHeight;
4466
- if (currentFirstContent !== prependRef.current.firstMessageContent) {
4467
- prependRef.current.firstMessageContent = currentFirstContent;
4468
- }
4469
- }, [messages, scrollRef]);
4452
+ const addedHeight = el.scrollHeight - anchor.scrollHeight;
4453
+ if (addedHeight <= 0) return;
4454
+ loadOlderAnchorRef.current = null;
4455
+ el.scrollTop = anchor.scrollTop + addedHeight;
4456
+ }, [messages, dialogId, scrollRef]);
4470
4457
  const messageElsRef = useRef6(/* @__PURE__ */ new Map());
4471
4458
  const refCallbacksRef = useRef6(/* @__PURE__ */ new Map());
4472
4459
  const getRegisterMessageEl = (id) => {
@@ -4538,6 +4525,14 @@ var ChatMessageList = forwardRef13(
4538
4525
  const entry = entries[0];
4539
4526
  if (!entry) return;
4540
4527
  if (entry.isIntersecting && !isFetchingRef.current) {
4528
+ const el = scrollRef.current;
4529
+ if (el) {
4530
+ loadOlderAnchorRef.current = {
4531
+ dialogId: dialogIdRef.current,
4532
+ scrollHeight: el.scrollHeight,
4533
+ scrollTop: el.scrollTop
4534
+ };
4535
+ }
4541
4536
  onLoadMoreRef.current?.();
4542
4537
  }
4543
4538
  },
@@ -4545,7 +4540,7 @@ var ChatMessageList = forwardRef13(
4545
4540
  );
4546
4541
  observer.observe(sentinelElement);
4547
4542
  return () => observer.disconnect();
4548
- }, [hasNextPage, scrollRef]);
4543
+ }, [hasNextPage, isFetchingNextPage, scrollRef]);
4549
4544
  useImperativeHandle2(ref, () => scrollRef.current, [scrollRef]);
4550
4545
  if (isLoading) {
4551
4546
  return /* @__PURE__ */ jsx26(
@@ -17132,9 +17127,6 @@ function scrollElementIntoView(target, options = {}) {
17132
17127
 
17133
17128
  // src/utils/list-url.ts
17134
17129
  var ALIASES = { blog_post_existing: "blog_post" };
17135
- function canonicalContentRefType(contentRefType) {
17136
- return ALIASES[contentRefType] ?? contentRefType;
17137
- }
17138
17130
  var BUILDERS = {
17139
17131
  roadmap_item: (ids, b) => `${b}/api/roadmap?task_ids=${ids.join(",")}`,
17140
17132
  delivery_item: (ids, b) => `${b}/api/delivery?task_ids=${ids.join(",")}`,
@@ -17159,60 +17151,6 @@ function buildListUrl(contentRefType, ids, base = "") {
17159
17151
  return fn ? fn(ids, base) : null;
17160
17152
  }
17161
17153
 
17162
- // src/utils/content-ref-groups.ts
17163
- var CONTENT_REF_GROUPS = {
17164
- investor_update: { label: "Investor Updates", order: 1, layout: "grid", gridSize: "default" },
17165
- product_release: { label: "Product Releases", order: 2, layout: "list", gridSize: "lg" },
17166
- podcast: { label: "Podcasts", order: 3, layout: "list", gridSize: "default" },
17167
- webinar: { label: "Webinars", order: 4, layout: "list", gridSize: "default" },
17168
- case_study: { label: "Case Studies", order: 5, layout: "grid", gridSize: "default" },
17169
- event: { label: "Events", order: 6, layout: "list", gridSize: "default" },
17170
- blog_post_existing: { label: "Blog Posts", order: 7, layout: "grid", gridSize: "default" },
17171
- customer_interview: { label: "Customer Interviews", order: 8, layout: "grid", gridSize: "default" },
17172
- onboarding_guide: { label: "Onboarding Guides", order: 9, layout: "list", gridSize: "default" }
17173
- };
17174
- function getContentRefLabel(type) {
17175
- return CONTENT_REF_GROUPS[type]?.label ?? null;
17176
- }
17177
- function getContentRefLabelOrTitleCase(type) {
17178
- return CONTENT_REF_GROUPS[type]?.label ?? type.replace(/_/g, " ").replace(/\b\w/g, (ch) => ch.toUpperCase());
17179
- }
17180
- function orderContentRefTypes(present) {
17181
- const presentSet = new Set(present);
17182
- const registeredInOrder = Object.entries(CONTENT_REF_GROUPS).sort(([, a], [, b]) => a.order - b.order).map(([type]) => type).filter((type) => presentSet.has(type));
17183
- const unregistered = [...presentSet].filter((type) => !CONTENT_REF_GROUPS[type]);
17184
- return [...registeredInOrder, ...unregistered];
17185
- }
17186
-
17187
- // src/utils/extract-items.ts
17188
- function extractItems(data) {
17189
- if (!data || typeof data !== "object") return [];
17190
- const obj = data;
17191
- if (Array.isArray(obj.items)) return obj.items;
17192
- if (Array.isArray(obj.posts)) return obj.posts;
17193
- if (Array.isArray(obj.campaigns)) return obj.campaigns;
17194
- if (Array.isArray(obj.completed) || Array.isArray(obj.inProgress)) {
17195
- const completed = Array.isArray(obj.completed) ? obj.completed : [];
17196
- const inProgress = Array.isArray(obj.inProgress) ? obj.inProgress : [];
17197
- return [...completed, ...inProgress];
17198
- }
17199
- if (Array.isArray(obj.data)) return obj.data;
17200
- if (Array.isArray(data)) return data;
17201
- return [];
17202
- }
17203
- function extractItemId(type, item) {
17204
- if (!item || typeof item !== "object") return null;
17205
- const obj = item;
17206
- if (type === "roadmap_item" || type === "delivery_item" || type === "internal_task") {
17207
- const ext = obj.external_id;
17208
- if (typeof ext === "string") return ext;
17209
- }
17210
- const id = obj.id;
17211
- if (typeof id === "string") return id;
17212
- if (typeof id === "number") return String(id);
17213
- return null;
17214
- }
17215
-
17216
17154
  // src/utils/content-href.ts
17217
17155
  var DEFAULT_CONTENT_SUFFIXES = {
17218
17156
  onboarding_guide: "onboarding-guides",
@@ -23899,6 +23837,7 @@ var CategorySection = ({
23899
23837
  /* @__PURE__ */ jsx195(
23900
23838
  Button,
23901
23839
  {
23840
+ type: "button",
23902
23841
  variant: "transparent",
23903
23842
  onClick: (e) => {
23904
23843
  e.stopPropagation();
@@ -36546,6 +36485,33 @@ init_next_navigation();
36546
36485
 
36547
36486
  // src/components/chat/hooks/use-chat-card-item.ts
36548
36487
  import { useQuery } from "@tanstack/react-query";
36488
+ function extractItems(data) {
36489
+ if (!data || typeof data !== "object") return [];
36490
+ const obj = data;
36491
+ if (Array.isArray(obj.items)) return obj.items;
36492
+ if (Array.isArray(obj.posts)) return obj.posts;
36493
+ if (Array.isArray(obj.campaigns)) return obj.campaigns;
36494
+ if (Array.isArray(obj.completed) || Array.isArray(obj.inProgress)) {
36495
+ const completed = Array.isArray(obj.completed) ? obj.completed : [];
36496
+ const inProgress = Array.isArray(obj.inProgress) ? obj.inProgress : [];
36497
+ return [...completed, ...inProgress];
36498
+ }
36499
+ if (Array.isArray(obj.data)) return obj.data;
36500
+ if (Array.isArray(data)) return data;
36501
+ return [];
36502
+ }
36503
+ function extractItemId(type, item) {
36504
+ if (!item || typeof item !== "object") return null;
36505
+ const obj = item;
36506
+ if (type === "roadmap_item" || type === "delivery_item" || type === "internal_task") {
36507
+ const ext = obj.external_id;
36508
+ if (typeof ext === "string") return ext;
36509
+ }
36510
+ const id = obj.id;
36511
+ if (typeof id === "string") return id;
36512
+ if (typeof id === "number") return String(id);
36513
+ return null;
36514
+ }
36549
36515
  function useChatCardItem(type, id) {
36550
36516
  const runtime = useRequiredChatRuntime();
36551
36517
  const url = runtime.endpoints.buildListUrl(type, [id]);
@@ -42095,6 +42061,110 @@ function extractIncompleteMessageState(lastMessage) {
42095
42061
  };
42096
42062
  }
42097
42063
 
42064
+ // src/components/chat/utils/history-merge.ts
42065
+ var SYNTHETIC_REALTIME_ID_PREFIXES = ["assistant-", "user-", "error-"];
42066
+ function isSyntheticRealtimeId(id) {
42067
+ return SYNTHETIC_REALTIME_ID_PREFIXES.some((prefix) => id.startsWith(prefix));
42068
+ }
42069
+ function flattenMessagePagesChronological(pages) {
42070
+ if (!pages) return [];
42071
+ return [...pages].reverse().flatMap((page) => [...page.messages].reverse());
42072
+ }
42073
+ function maxPersistedStreamSeq(pages) {
42074
+ let max = 0;
42075
+ if (!pages) return max;
42076
+ for (const page of pages) {
42077
+ for (const msg of page.messages) {
42078
+ const seq = msg.lastChunkStreamSeq;
42079
+ if (typeof seq === "number" && seq > max) max = seq;
42080
+ }
42081
+ }
42082
+ return max;
42083
+ }
42084
+ function mergeHistoryWithRealtime(input) {
42085
+ const {
42086
+ processedHistory,
42087
+ rawHistoryIds,
42088
+ existingMessages,
42089
+ streamingMessageId,
42090
+ historyFetchedAt,
42091
+ historyMaxStreamSeq = 0,
42092
+ realtimeSeenStreamSeq = 0
42093
+ } = input;
42094
+ if (processedHistory.length === 0) return existingMessages;
42095
+ const processedIds = new Set(processedHistory.map((m) => m.id));
42096
+ const seqCoverageKnown = realtimeSeenStreamSeq > 0 && historyMaxStreamSeq > 0;
42097
+ const historyCoversRealtime = seqCoverageKnown ? historyMaxStreamSeq >= realtimeSeenStreamSeq : null;
42098
+ const trailing = processedHistory[processedHistory.length - 1];
42099
+ const historyTrailingAssistant = trailing?.role === "assistant" ? trailing : null;
42100
+ const historyBatchId = historyTrailingAssistant && Array.isArray(historyTrailingAssistant.content) ? historyTrailingAssistant.content.find((s) => s.type === "approval_batch")?.data?.approvalRequestId ?? null : null;
42101
+ let processedToUse = processedHistory;
42102
+ const pinnedSyntheticIds = /* @__PURE__ */ new Set();
42103
+ const droppedSyntheticIds = /* @__PURE__ */ new Set();
42104
+ if (historyBatchId) {
42105
+ const batchTwins = existingMessages.filter(
42106
+ (m) => m.role === "assistant" && Array.isArray(m.content) && m.content.some(
42107
+ (s) => s.type === "approval_batch" && s.data?.approvalRequestId === historyBatchId
42108
+ )
42109
+ );
42110
+ const existingWithSameBatch = batchTwins.find((m) => m.id === streamingMessageId) ?? batchTwins[batchTwins.length - 1];
42111
+ if (existingWithSameBatch && Array.isArray(existingWithSameBatch.content)) {
42112
+ const histSize = Array.isArray(historyTrailingAssistant?.content) ? historyTrailingAssistant.content.length : 0;
42113
+ const realtimeSize = existingWithSameBatch.content.length;
42114
+ if (existingWithSameBatch.id === streamingMessageId || realtimeSize > histSize) {
42115
+ processedToUse = processedHistory.slice(0, -1);
42116
+ pinnedSyntheticIds.add(existingWithSameBatch.id);
42117
+ } else {
42118
+ droppedSyntheticIds.add(existingWithSameBatch.id);
42119
+ }
42120
+ }
42121
+ }
42122
+ const realtimeMessages = existingMessages.filter((m) => {
42123
+ if (pinnedSyntheticIds.has(m.id)) return true;
42124
+ if (droppedSyntheticIds.has(m.id)) return false;
42125
+ if (processedIds.has(m.id)) return false;
42126
+ if (rawHistoryIds?.has(m.id)) return false;
42127
+ if (m.role === "user" && m.id.startsWith("optimistic-") && typeof m.content === "string") {
42128
+ const canBeInSnapshot = (m.timestamp?.getTime() ?? 0) <= historyFetchedAt;
42129
+ return !(canBeInSnapshot && processedToUse.some((pm) => pm.role === "user" && pm.content === m.content));
42130
+ }
42131
+ if (isSyntheticRealtimeId(m.id) && m.id !== streamingMessageId) {
42132
+ const covered = historyCoversRealtime !== null ? historyCoversRealtime : (m.timestamp?.getTime() ?? 0) <= historyFetchedAt;
42133
+ if (covered) return false;
42134
+ }
42135
+ return true;
42136
+ });
42137
+ return [...processedToUse, ...realtimeMessages];
42138
+ }
42139
+ function computeHistoryPrepend(processedHistory, existingMessages) {
42140
+ const existingIds = new Set(existingMessages.map((m) => m.id));
42141
+ const newMessages = [];
42142
+ let boundaryMessageIndex = -1;
42143
+ for (let i = 0; i < processedHistory.length; i++) {
42144
+ if (existingIds.has(processedHistory[i].id)) {
42145
+ boundaryMessageIndex = i;
42146
+ break;
42147
+ }
42148
+ newMessages.push(processedHistory[i]);
42149
+ }
42150
+ let boundaryMessageId;
42151
+ let boundaryUpdates;
42152
+ if (boundaryMessageIndex >= 0) {
42153
+ const boundaryMessage = processedHistory[boundaryMessageIndex];
42154
+ const existingBoundary = existingMessages.find((m) => m.id === boundaryMessage.id);
42155
+ if (existingBoundary) {
42156
+ const existingContent = JSON.stringify(existingBoundary.content);
42157
+ const newContent = JSON.stringify(boundaryMessage.content);
42158
+ if (existingContent !== newContent) {
42159
+ boundaryMessageId = boundaryMessage.id;
42160
+ boundaryUpdates = { content: boundaryMessage.content };
42161
+ }
42162
+ }
42163
+ }
42164
+ if (newMessages.length === 0 && !boundaryUpdates) return null;
42165
+ return { newMessages, boundaryMessageId, boundaryUpdates };
42166
+ }
42167
+
42098
42168
  // src/components/chat/utils/chip-action-class.ts
42099
42169
  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";
42100
42170
 
@@ -43605,8 +43675,6 @@ export {
43605
43675
  applyProxyAuth,
43606
43676
  setEmbedAuthAdapter,
43607
43677
  embedAuthedFetch,
43608
- extractItems,
43609
- extractItemId,
43610
43678
  useChatCardItem,
43611
43679
  SOURCE_ICON_NAMES,
43612
43680
  getSourceIconName,
@@ -43675,6 +43743,11 @@ export {
43675
43743
  useNatsChatAdapter,
43676
43744
  useUnifiedChat,
43677
43745
  extractIncompleteMessageState,
43746
+ SYNTHETIC_REALTIME_ID_PREFIXES,
43747
+ flattenMessagePagesChronological,
43748
+ maxPersistedStreamSeq,
43749
+ mergeHistoryWithRealtime,
43750
+ computeHistoryPrepend,
43678
43751
  CHIP_ACTION_BUTTON_CLASS,
43679
43752
  chatChipClass,
43680
43753
  clickupTaskUrl,
@@ -43780,12 +43853,7 @@ export {
43780
43853
  TICKET_STATUS_OPTIONS,
43781
43854
  OPENFRAME_DEV_SECTIONS,
43782
43855
  scrollElementIntoView,
43783
- canonicalContentRefType,
43784
43856
  buildListUrl,
43785
- CONTENT_REF_GROUPS,
43786
- getContentRefLabel,
43787
- getContentRefLabelOrTitleCase,
43788
- orderContentRefTypes,
43789
43857
  DEFAULT_CONTENT_SUFFIXES,
43790
43858
  makeComposeContentUrl,
43791
43859
  buildDefaultHref,
@@ -44028,4 +44096,4 @@ export {
44028
44096
  LogsList,
44029
44097
  assets
44030
44098
  };
44031
- //# sourceMappingURL=chunk-FRRMXLU5.js.map
44099
+ //# sourceMappingURL=chunk-M7DPUWAL.js.map