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

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 (133) hide show
  1. package/dist/{chunk-STKMIMLP.cjs → chunk-3JRA55FZ.cjs} +12 -12
  2. package/dist/{chunk-STKMIMLP.cjs.map → chunk-3JRA55FZ.cjs.map} +1 -1
  3. package/dist/{chunk-DV3YZWGN.cjs → chunk-3TDLFCCS.cjs} +33 -20
  4. package/dist/chunk-3TDLFCCS.cjs.map +1 -0
  5. package/dist/{chunk-ORJREQ2W.js → chunk-4XLJWX2N.js} +4 -4
  6. package/dist/{chunk-P5C732SC.js → chunk-DB4HW42V.js} +6 -6
  7. package/dist/{chunk-EPXROXYC.cjs → chunk-ESADULCN.cjs} +651 -716
  8. package/dist/chunk-ESADULCN.cjs.map +1 -0
  9. package/dist/{chunk-EJ7J4QAD.cjs → chunk-GMFDA36U.cjs} +12 -12
  10. package/dist/{chunk-EJ7J4QAD.cjs.map → chunk-GMFDA36U.cjs.map} +1 -1
  11. package/dist/{chunk-PTSAF7T2.js → chunk-LXDA67PW.js} +2 -2
  12. package/dist/{chunk-APGMNHPY.js → chunk-MKVKVJQQ.js} +32 -19
  13. package/dist/chunk-MKVKVJQQ.js.map +1 -0
  14. package/dist/{chunk-M7DPUWAL.js → chunk-NZST65RV.js} +126 -191
  15. package/dist/chunk-NZST65RV.js.map +1 -0
  16. package/dist/{chunk-Z6GGYZDR.cjs → chunk-P2G5X6AW.cjs} +27 -27
  17. package/dist/{chunk-Z6GGYZDR.cjs.map → chunk-P2G5X6AW.cjs.map} +1 -1
  18. package/dist/chunk-PINAV6VJ.cjs +287 -0
  19. package/dist/chunk-PINAV6VJ.cjs.map +1 -0
  20. package/dist/{chunk-NKGNRFSS.js → chunk-QRGODKEG.js} +8 -8
  21. package/dist/{chunk-FSS2MIEA.cjs → chunk-SGJBUL2Y.cjs} +20 -3
  22. package/dist/chunk-SGJBUL2Y.cjs.map +1 -0
  23. package/dist/{chunk-LJGBFD52.js → chunk-VAUI3CND.js} +18 -1
  24. package/dist/chunk-VAUI3CND.js.map +1 -0
  25. package/dist/{chunk-OB45JHDY.cjs → chunk-VFKQMAUF.cjs} +3 -3
  26. package/dist/{chunk-OB45JHDY.cjs.map → chunk-VFKQMAUF.cjs.map} +1 -1
  27. package/dist/chunk-VI7GW7PE.js +287 -0
  28. package/dist/chunk-VI7GW7PE.js.map +1 -0
  29. package/dist/{chunk-RJC3L5DT.cjs → chunk-YJVDQZ5Y.cjs} +7 -7
  30. package/dist/{chunk-RJC3L5DT.cjs.map → chunk-YJVDQZ5Y.cjs.map} +1 -1
  31. package/dist/{chunk-WD2MZVJI.js → chunk-ZXECERJ4.js} +5 -5
  32. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  33. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts.map +1 -1
  34. package/dist/components/chat/hooks/use-chat-card-item.d.ts.map +1 -1
  35. package/dist/components/chat/index.cjs +6 -16
  36. package/dist/components/chat/index.cjs.map +1 -1
  37. package/dist/components/chat/index.js +5 -15
  38. package/dist/components/chat/types/entities/content-ref.d.ts +5 -20
  39. package/dist/components/chat/types/entities/content-ref.d.ts.map +1 -1
  40. package/dist/components/chat/utils/index.d.ts +0 -1
  41. package/dist/components/chat/utils/index.d.ts.map +1 -1
  42. package/dist/components/contact/index.cjs +7 -7
  43. package/dist/components/contact/index.js +6 -6
  44. package/dist/components/faq/faq-section.d.ts +7 -1
  45. package/dist/components/faq/faq-section.d.ts.map +1 -1
  46. package/dist/components/faq/index.cjs +3 -3
  47. package/dist/components/faq/index.js +2 -2
  48. package/dist/components/features/index.cjs +6 -6
  49. package/dist/components/features/index.js +5 -5
  50. package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
  51. package/dist/components/index.cjs +87 -93
  52. package/dist/components/index.cjs.map +1 -1
  53. package/dist/components/index.d.ts +1 -0
  54. package/dist/components/index.d.ts.map +1 -1
  55. package/dist/components/index.js +31 -37
  56. package/dist/components/index.js.map +1 -1
  57. package/dist/components/navigation/index.cjs +6 -6
  58. package/dist/components/navigation/index.js +5 -5
  59. package/dist/components/onboarding-guides/index.cjs +30 -30
  60. package/dist/components/onboarding-guides/index.cjs.map +1 -1
  61. package/dist/components/onboarding-guides/index.js +11 -11
  62. package/dist/components/related-content/index.cjs +26 -0
  63. package/dist/components/related-content/index.cjs.map +1 -0
  64. package/dist/components/related-content/index.d.ts +2 -0
  65. package/dist/components/related-content/index.d.ts.map +1 -0
  66. package/dist/components/related-content/index.js +26 -0
  67. package/dist/components/related-content/index.js.map +1 -0
  68. package/dist/components/related-content/related-content-section.d.ts +149 -0
  69. package/dist/components/related-content/related-content-section.d.ts.map +1 -0
  70. package/dist/components/tickets/index.cjs +73 -73
  71. package/dist/components/tickets/index.cjs.map +1 -1
  72. package/dist/components/tickets/index.js +15 -15
  73. package/dist/components/ui/index.cjs +9 -19
  74. package/dist/components/ui/index.cjs.map +1 -1
  75. package/dist/components/ui/index.js +13 -23
  76. package/dist/embed-shims/index.cjs +3 -3
  77. package/dist/embed-shims/index.cjs.map +1 -1
  78. package/dist/embed-shims/index.js +5 -5
  79. package/dist/index.cjs +17 -11
  80. package/dist/index.cjs.map +1 -1
  81. package/dist/index.js +55 -49
  82. package/dist/types/content-ref.d.ts +35 -0
  83. package/dist/types/content-ref.d.ts.map +1 -0
  84. package/dist/types/index.d.ts +1 -0
  85. package/dist/types/index.d.ts.map +1 -1
  86. package/dist/utils/content-ref-groups.d.ts +58 -0
  87. package/dist/utils/content-ref-groups.d.ts.map +1 -0
  88. package/dist/utils/extract-items.d.ts +18 -0
  89. package/dist/utils/extract-items.d.ts.map +1 -0
  90. package/dist/utils/index.cjs +81 -0
  91. package/dist/utils/index.cjs.map +1 -1
  92. package/dist/utils/index.d.ts +4 -1
  93. package/dist/utils/index.d.ts.map +1 -1
  94. package/dist/utils/index.js +74 -1
  95. package/dist/utils/index.js.map +1 -1
  96. package/dist/utils/list-url.d.ts +6 -0
  97. package/dist/utils/list-url.d.ts.map +1 -1
  98. package/dist/utils/suggestion-url.d.ts +26 -0
  99. package/dist/utils/suggestion-url.d.ts.map +1 -0
  100. package/package.json +7 -1
  101. package/src/components/chat/chat-message-list.tsx +49 -74
  102. package/src/components/chat/entity-cards/onboarding-guide-card.tsx +18 -3
  103. package/src/components/chat/hooks/use-chat-card-item.ts +3 -38
  104. package/src/components/chat/types/entities/content-ref.ts +5 -21
  105. package/src/components/chat/utils/index.ts +0 -12
  106. package/src/components/faq/faq-section.tsx +69 -24
  107. package/src/components/features/policy-configuration-panel.tsx +0 -1
  108. package/src/components/index.ts +1 -0
  109. package/src/components/related-content/index.ts +9 -0
  110. package/src/components/related-content/related-content-section.tsx +630 -0
  111. package/src/types/content-ref.ts +34 -0
  112. package/src/types/index.ts +1 -0
  113. package/src/utils/content-ref-groups.ts +89 -0
  114. package/src/utils/extract-items.ts +48 -0
  115. package/src/utils/index.ts +16 -1
  116. package/src/utils/list-url.ts +9 -0
  117. package/src/utils/suggestion-url.ts +39 -0
  118. package/dist/chunk-APGMNHPY.js.map +0 -1
  119. package/dist/chunk-DV3YZWGN.cjs.map +0 -1
  120. package/dist/chunk-EPXROXYC.cjs.map +0 -1
  121. package/dist/chunk-FSS2MIEA.cjs.map +0 -1
  122. package/dist/chunk-LJGBFD52.js.map +0 -1
  123. package/dist/chunk-M7DPUWAL.js.map +0 -1
  124. package/dist/components/chat/utils/history-merge.d.ts +0 -92
  125. package/dist/components/chat/utils/history-merge.d.ts.map +0 -1
  126. package/src/components/chat/__tests__/chat-message-list.test.tsx +0 -92
  127. package/src/components/chat/utils/__tests__/history-merge.test.ts +0 -339
  128. package/src/components/chat/utils/history-merge.ts +0 -255
  129. /package/dist/{chunk-ORJREQ2W.js.map → chunk-4XLJWX2N.js.map} +0 -0
  130. /package/dist/{chunk-P5C732SC.js.map → chunk-DB4HW42V.js.map} +0 -0
  131. /package/dist/{chunk-PTSAF7T2.js.map → chunk-LXDA67PW.js.map} +0 -0
  132. /package/dist/{chunk-NKGNRFSS.js.map → chunk-QRGODKEG.js.map} +0 -0
  133. /package/dist/{chunk-WD2MZVJI.js.map → chunk-ZXECERJ4.js.map} +0 -0
@@ -1,4 +1,24 @@
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";
2
22
  import {
3
23
  useChatRuntime,
4
24
  useRequiredChatRuntime
@@ -9,6 +29,12 @@ import {
9
29
  import {
10
30
  dynamic
11
31
  } from "./chunk-EL5YVPD5.js";
32
+ import {
33
+ init_next_navigation,
34
+ usePathname,
35
+ useRouter,
36
+ useSearchParams
37
+ } from "./chunk-PLJLE4A4.js";
12
38
  import {
13
39
  Button,
14
40
  Checkbox,
@@ -30,32 +56,6 @@ import {
30
56
  init_next_link,
31
57
  next_link_default
32
58
  } 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,15 +4397,12 @@ 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;
4402
4400
  const prevRenderRef = useRef6({ dialogId: void 0, messageCount: 0, lastMessageId: void 0 });
4403
- const loadOlderAnchorRef = useRef6(null);
4401
+ const prependRef = useRef6({ firstMessageId: void 0, firstMessageContent: void 0, scrollHeight: 0 });
4404
4402
  useEffect6(() => {
4405
4403
  if (!autoScroll) return;
4406
4404
  const dialogChanged = dialogId !== prevRenderRef.current.dialogId;
4407
4405
  const prevCount = prevRenderRef.current.messageCount;
4408
- const prevLastId = prevRenderRef.current.lastMessageId;
4409
4406
  const newCount = messages.length;
4410
4407
  const currentLastId = messages[messages.length - 1]?.id;
4411
4408
  prevRenderRef.current = { dialogId, messageCount: newCount, lastMessageId: currentLastId };
@@ -4418,8 +4415,7 @@ var ChatMessageList = forwardRef13(
4418
4415
  return;
4419
4416
  }
4420
4417
  if (newCount > prevCount) {
4421
- const prevLastIdx = prevLastId ? messages.findIndex((m) => m.id === prevLastId) : -1;
4422
- const newSlice = prevLastIdx >= 0 ? messages.slice(prevLastIdx + 1) : messages.slice(prevCount);
4418
+ const newSlice = messages.slice(prevCount);
4423
4419
  const hasNewUser = newSlice.some((m) => m.role === "user");
4424
4420
  if (hasNewUser) {
4425
4421
  void scrollToBottom({ animation: "instant", ignoreEscapes: true });
@@ -4443,17 +4439,34 @@ var ChatMessageList = forwardRef13(
4443
4439
  }, [autoScroll, messages, dialogId, scrollToBottom, contentRef]);
4444
4440
  useLayoutEffect3(() => {
4445
4441
  const el = scrollRef.current;
4446
- const anchor = loadOlderAnchorRef.current;
4447
- if (!el || !anchor) return;
4448
- if (anchor.dialogId !== dialogId) {
4449
- loadOlderAnchorRef.current = null;
4442
+ if (!el) {
4443
+ prependRef.current = { firstMessageId: void 0, firstMessageContent: void 0, scrollHeight: 0 };
4450
4444
  return;
4451
4445
  }
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]);
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
+ };
4463
+ return;
4464
+ }
4465
+ prependRef.current.scrollHeight = el.scrollHeight;
4466
+ if (currentFirstContent !== prependRef.current.firstMessageContent) {
4467
+ prependRef.current.firstMessageContent = currentFirstContent;
4468
+ }
4469
+ }, [messages, scrollRef]);
4457
4470
  const messageElsRef = useRef6(/* @__PURE__ */ new Map());
4458
4471
  const refCallbacksRef = useRef6(/* @__PURE__ */ new Map());
4459
4472
  const getRegisterMessageEl = (id) => {
@@ -4525,14 +4538,6 @@ var ChatMessageList = forwardRef13(
4525
4538
  const entry = entries[0];
4526
4539
  if (!entry) return;
4527
4540
  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
- }
4536
4541
  onLoadMoreRef.current?.();
4537
4542
  }
4538
4543
  },
@@ -4540,7 +4545,7 @@ var ChatMessageList = forwardRef13(
4540
4545
  );
4541
4546
  observer.observe(sentinelElement);
4542
4547
  return () => observer.disconnect();
4543
- }, [hasNextPage, isFetchingNextPage, scrollRef]);
4548
+ }, [hasNextPage, scrollRef]);
4544
4549
  useImperativeHandle2(ref, () => scrollRef.current, [scrollRef]);
4545
4550
  if (isLoading) {
4546
4551
  return /* @__PURE__ */ jsx26(
@@ -9582,6 +9587,9 @@ init_next_link();
9582
9587
  init_cn();
9583
9588
  import { Clock, ExternalLink, GraduationCap, Play as Play2 } from "lucide-react";
9584
9589
  import { jsx as jsx73, jsxs as jsxs58 } from "react/jsx-runtime";
9590
+ function stripMarkdownPreview(text) {
9591
+ return text.replace(/```[\s\S]*?```/g, " ").replace(/^#{1,6}\s+/gm, "").replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/[*_~`>]/g, "").replace(/^\s*[-+]\s+/gm, "").replace(/-{3,}/g, " ").replace(/\s+/g, " ").trim();
9592
+ }
9585
9593
  var HORIZONTAL_SIZE_TOKENS = {
9586
9594
  default: {
9587
9595
  padding: "p-4",
@@ -9726,7 +9734,7 @@ function OnboardingGuideCard({
9726
9734
  ] }) }),
9727
9735
  /* @__PURE__ */ jsxs58("div", { className: "flex-1 min-w-0 flex flex-col", children: [
9728
9736
  /* @__PURE__ */ jsx73("div", { className: "min-h-[60px] md:min-h-[72px] flex items-start mb-3", children: /* @__PURE__ */ jsx73("h3", { className: "font-['Azeret_Mono'] font-semibold text-xl md:text-2xl text-ods-text-primary leading-tight line-clamp-2", children: guide.title }) }),
9729
- /* @__PURE__ */ jsx73("div", { className: "min-h-[46px] md:min-h-[52px]", children: /* @__PURE__ */ jsx73("p", { className: "font-['DM_Sans'] text-sm md:text-base text-ods-text-secondary leading-relaxed line-clamp-2", children: (guide.video_summary || guide.content || "").trim() }) })
9737
+ /* @__PURE__ */ jsx73("div", { className: "min-h-[46px] md:min-h-[52px]", children: /* @__PURE__ */ jsx73("p", { className: "font-['DM_Sans'] text-sm md:text-base text-ods-text-secondary leading-relaxed line-clamp-2", children: stripMarkdownPreview(guide.video_summary || guide.content || "") }) })
9730
9738
  ] })
9731
9739
  ] }),
9732
9740
  /* @__PURE__ */ jsx73(
@@ -9752,7 +9760,7 @@ function OnboardingGuideCard({
9752
9760
  const coverImage = guide.featured_image || guide.main_video_thumbnail || guide.og_image_url || null;
9753
9761
  const compactCover = coverImage || placeholderUrl || null;
9754
9762
  const hasVideoCover = !guide.featured_image && !!guide.main_video_thumbnail;
9755
- const summary2 = (guide.video_summary || guide.content || "").trim();
9763
+ const summary2 = stripMarkdownPreview(guide.video_summary || guide.content || "");
9756
9764
  const author = guide.author?.full_name?.trim() || "";
9757
9765
  const subtitleParts = [
9758
9766
  `Step ${guide.step_order}`,
@@ -9783,7 +9791,7 @@ function OnboardingGuideCard({
9783
9791
  ] });
9784
9792
  }
9785
9793
  const t = HORIZONTAL_SIZE_TOKENS.default;
9786
- const summary = (guide.video_summary || guide.content || "").trim();
9794
+ const summary = stripMarkdownPreview(guide.video_summary || guide.content || "");
9787
9795
  return /* @__PURE__ */ jsxs58(
9788
9796
  next_link_default,
9789
9797
  {
@@ -17127,6 +17135,9 @@ function scrollElementIntoView(target, options = {}) {
17127
17135
 
17128
17136
  // src/utils/list-url.ts
17129
17137
  var ALIASES = { blog_post_existing: "blog_post" };
17138
+ function canonicalContentRefType(contentRefType) {
17139
+ return ALIASES[contentRefType] ?? contentRefType;
17140
+ }
17130
17141
  var BUILDERS = {
17131
17142
  roadmap_item: (ids, b) => `${b}/api/roadmap?task_ids=${ids.join(",")}`,
17132
17143
  delivery_item: (ids, b) => `${b}/api/delivery?task_ids=${ids.join(",")}`,
@@ -17151,6 +17162,60 @@ function buildListUrl(contentRefType, ids, base = "") {
17151
17162
  return fn ? fn(ids, base) : null;
17152
17163
  }
17153
17164
 
17165
+ // src/utils/content-ref-groups.ts
17166
+ var CONTENT_REF_GROUPS = {
17167
+ investor_update: { label: "Investor Updates", order: 1, layout: "grid", gridSize: "default" },
17168
+ product_release: { label: "Product Releases", order: 2, layout: "list", gridSize: "lg" },
17169
+ podcast: { label: "Podcasts", order: 3, layout: "list", gridSize: "default" },
17170
+ webinar: { label: "Webinars", order: 4, layout: "list", gridSize: "default" },
17171
+ case_study: { label: "Case Studies", order: 5, layout: "grid", gridSize: "default" },
17172
+ event: { label: "Events", order: 6, layout: "list", gridSize: "default" },
17173
+ blog_post_existing: { label: "Blog Posts", order: 7, layout: "grid", gridSize: "default" },
17174
+ customer_interview: { label: "Customer Interviews", order: 8, layout: "grid", gridSize: "default" },
17175
+ onboarding_guide: { label: "Onboarding Guides", order: 9, layout: "list", gridSize: "default" }
17176
+ };
17177
+ function getContentRefLabel(type) {
17178
+ return CONTENT_REF_GROUPS[type]?.label ?? null;
17179
+ }
17180
+ function getContentRefLabelOrTitleCase(type) {
17181
+ return CONTENT_REF_GROUPS[type]?.label ?? type.replace(/_/g, " ").replace(/\b\w/g, (ch) => ch.toUpperCase());
17182
+ }
17183
+ function orderContentRefTypes(present) {
17184
+ const presentSet = new Set(present);
17185
+ const registeredInOrder = Object.entries(CONTENT_REF_GROUPS).sort(([, a], [, b]) => a.order - b.order).map(([type]) => type).filter((type) => presentSet.has(type));
17186
+ const unregistered = [...presentSet].filter((type) => !CONTENT_REF_GROUPS[type]);
17187
+ return [...registeredInOrder, ...unregistered];
17188
+ }
17189
+
17190
+ // src/utils/extract-items.ts
17191
+ function extractItems(data) {
17192
+ if (!data || typeof data !== "object") return [];
17193
+ const obj = data;
17194
+ if (Array.isArray(obj.items)) return obj.items;
17195
+ if (Array.isArray(obj.posts)) return obj.posts;
17196
+ if (Array.isArray(obj.campaigns)) return obj.campaigns;
17197
+ if (Array.isArray(obj.completed) || Array.isArray(obj.inProgress)) {
17198
+ const completed = Array.isArray(obj.completed) ? obj.completed : [];
17199
+ const inProgress = Array.isArray(obj.inProgress) ? obj.inProgress : [];
17200
+ return [...completed, ...inProgress];
17201
+ }
17202
+ if (Array.isArray(obj.data)) return obj.data;
17203
+ if (Array.isArray(data)) return data;
17204
+ return [];
17205
+ }
17206
+ function extractItemId(type, item) {
17207
+ if (!item || typeof item !== "object") return null;
17208
+ const obj = item;
17209
+ if (type === "roadmap_item" || type === "delivery_item" || type === "internal_task") {
17210
+ const ext = obj.external_id;
17211
+ if (typeof ext === "string") return ext;
17212
+ }
17213
+ const id = obj.id;
17214
+ if (typeof id === "string") return id;
17215
+ if (typeof id === "number") return String(id);
17216
+ return null;
17217
+ }
17218
+
17154
17219
  // src/utils/content-href.ts
17155
17220
  var DEFAULT_CONTENT_SUFFIXES = {
17156
17221
  onboarding_guide: "onboarding-guides",
@@ -23837,7 +23902,6 @@ var CategorySection = ({
23837
23902
  /* @__PURE__ */ jsx195(
23838
23903
  Button,
23839
23904
  {
23840
- type: "button",
23841
23905
  variant: "transparent",
23842
23906
  onClick: (e) => {
23843
23907
  e.stopPropagation();
@@ -36485,33 +36549,6 @@ init_next_navigation();
36485
36549
 
36486
36550
  // src/components/chat/hooks/use-chat-card-item.ts
36487
36551
  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
- }
36515
36552
  function useChatCardItem(type, id) {
36516
36553
  const runtime = useRequiredChatRuntime();
36517
36554
  const url = runtime.endpoints.buildListUrl(type, [id]);
@@ -42061,110 +42098,6 @@ function extractIncompleteMessageState(lastMessage) {
42061
42098
  };
42062
42099
  }
42063
42100
 
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
-
42168
42101
  // src/components/chat/utils/chip-action-class.ts
42169
42102
  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";
42170
42103
 
@@ -43675,6 +43608,8 @@ export {
43675
43608
  applyProxyAuth,
43676
43609
  setEmbedAuthAdapter,
43677
43610
  embedAuthedFetch,
43611
+ extractItems,
43612
+ extractItemId,
43678
43613
  useChatCardItem,
43679
43614
  SOURCE_ICON_NAMES,
43680
43615
  getSourceIconName,
@@ -43743,11 +43678,6 @@ export {
43743
43678
  useNatsChatAdapter,
43744
43679
  useUnifiedChat,
43745
43680
  extractIncompleteMessageState,
43746
- SYNTHETIC_REALTIME_ID_PREFIXES,
43747
- flattenMessagePagesChronological,
43748
- maxPersistedStreamSeq,
43749
- mergeHistoryWithRealtime,
43750
- computeHistoryPrepend,
43751
43681
  CHIP_ACTION_BUTTON_CLASS,
43752
43682
  chatChipClass,
43753
43683
  clickupTaskUrl,
@@ -43853,7 +43783,12 @@ export {
43853
43783
  TICKET_STATUS_OPTIONS,
43854
43784
  OPENFRAME_DEV_SECTIONS,
43855
43785
  scrollElementIntoView,
43786
+ canonicalContentRefType,
43856
43787
  buildListUrl,
43788
+ CONTENT_REF_GROUPS,
43789
+ getContentRefLabel,
43790
+ getContentRefLabelOrTitleCase,
43791
+ orderContentRefTypes,
43857
43792
  DEFAULT_CONTENT_SUFFIXES,
43858
43793
  makeComposeContentUrl,
43859
43794
  buildDefaultHref,
@@ -44096,4 +44031,4 @@ export {
44096
44031
  LogsList,
44097
44032
  assets
44098
44033
  };
44099
- //# sourceMappingURL=chunk-M7DPUWAL.js.map
44034
+ //# sourceMappingURL=chunk-NZST65RV.js.map