@flamingo-stack/openframe-frontend-core 0.0.587-1973.5528.1 → 0.0.587-2000.5532.1

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 (165) hide show
  1. package/dist/chat-protocol/events.d.ts +2 -8
  2. package/dist/chat-protocol/events.d.ts.map +1 -1
  3. package/dist/chat-protocol/index.cjs +0 -188
  4. package/dist/chat-protocol/index.cjs.map +1 -1
  5. package/dist/chat-protocol/index.js +0 -188
  6. package/dist/chat-protocol/index.js.map +1 -1
  7. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -1
  8. package/dist/{chunk-5VCDP6UA.cjs → chunk-3FHWLQDG.cjs} +10 -10
  9. package/dist/{chunk-5VCDP6UA.cjs.map → chunk-3FHWLQDG.cjs.map} +1 -1
  10. package/dist/{chunk-RE3KVI2Q.js → chunk-3PDTGDOA.js} +5 -5
  11. package/dist/{chunk-5X7AJ67N.js → chunk-436G4DI4.js} +3 -3
  12. package/dist/{chunk-BLC4JOFC.cjs → chunk-4IIFSFJ3.cjs} +15 -15
  13. package/dist/{chunk-BLC4JOFC.cjs.map → chunk-4IIFSFJ3.cjs.map} +1 -1
  14. package/dist/{chunk-JR37UTA2.cjs → chunk-5O5JMGEN.cjs} +33 -33
  15. package/dist/{chunk-JR37UTA2.cjs.map → chunk-5O5JMGEN.cjs.map} +1 -1
  16. package/dist/{chunk-7A6J4JTW.js → chunk-6BFEJXMI.js} +3 -3
  17. package/dist/{chunk-S2UY2C4A.cjs → chunk-7WIKOL25.cjs} +10 -10
  18. package/dist/{chunk-S2UY2C4A.cjs.map → chunk-7WIKOL25.cjs.map} +1 -1
  19. package/dist/{chunk-DVMQV3M4.cjs → chunk-A5PXHMCJ.cjs} +69 -69
  20. package/dist/{chunk-DVMQV3M4.cjs.map → chunk-A5PXHMCJ.cjs.map} +1 -1
  21. package/dist/{chunk-RQ5PYSRJ.js → chunk-BLJEPNMJ.js} +4 -4
  22. package/dist/{chunk-4MVGFYRE.js → chunk-D7YISHXC.js} +190 -534
  23. package/dist/chunk-D7YISHXC.js.map +1 -0
  24. package/dist/{chunk-4S7GMJYA.cjs → chunk-DMQMRFGS.cjs} +21 -21
  25. package/dist/{chunk-4S7GMJYA.cjs.map → chunk-DMQMRFGS.cjs.map} +1 -1
  26. package/dist/{chunk-AIUIIGO3.cjs → chunk-DTQCZ6AR.cjs} +24 -24
  27. package/dist/{chunk-AIUIIGO3.cjs.map → chunk-DTQCZ6AR.cjs.map} +1 -1
  28. package/dist/{chunk-QKAUBYU5.cjs → chunk-E7NFHRLX.cjs} +3 -3
  29. package/dist/{chunk-QKAUBYU5.cjs.map → chunk-E7NFHRLX.cjs.map} +1 -1
  30. package/dist/{chunk-WFWWQO2I.js → chunk-F3YRPKUA.js} +2 -2
  31. package/dist/{chunk-EKKR5ZFB.cjs → chunk-G45RGWHF.cjs} +543 -887
  32. package/dist/chunk-G45RGWHF.cjs.map +1 -0
  33. package/dist/{chunk-ZRFSUCAH.js → chunk-HCWZP44O.js} +5 -3
  34. package/dist/{chunk-ZRFSUCAH.js.map → chunk-HCWZP44O.js.map} +1 -1
  35. package/dist/{chunk-NEI7XMCM.cjs → chunk-IGBNEPTD.cjs} +9 -9
  36. package/dist/{chunk-NEI7XMCM.cjs.map → chunk-IGBNEPTD.cjs.map} +1 -1
  37. package/dist/{chunk-3UJMZADA.cjs → chunk-KQ5JQVYL.cjs} +43 -43
  38. package/dist/{chunk-3UJMZADA.cjs.map → chunk-KQ5JQVYL.cjs.map} +1 -1
  39. package/dist/{chunk-FDWGO244.js → chunk-LODCKZ72.js} +2 -2
  40. package/dist/{chunk-ULOMJH7C.cjs → chunk-MF7TMFVB.cjs} +5 -5
  41. package/dist/{chunk-ULOMJH7C.cjs.map → chunk-MF7TMFVB.cjs.map} +1 -1
  42. package/dist/{chunk-DSXD77KX.cjs → chunk-MXCWOMNT.cjs} +3 -3
  43. package/dist/{chunk-DSXD77KX.cjs.map → chunk-MXCWOMNT.cjs.map} +1 -1
  44. package/dist/{chunk-E2QFZDCP.js → chunk-OKD7MX7Y.js} +5 -5
  45. package/dist/{chunk-OW3FUJ2I.js → chunk-P24OI2CD.js} +3 -3
  46. package/dist/{chunk-QSO24MEK.js → chunk-R2U2D7LU.js} +2 -2
  47. package/dist/{chunk-KQWI25NP.js → chunk-SI57FQZ2.js} +2 -2
  48. package/dist/{chunk-JQO47UHC.js → chunk-SVR75PFW.js} +5 -5
  49. package/dist/{chunk-UYHETUX3.cjs → chunk-UBSIENYF.cjs} +162 -160
  50. package/dist/chunk-UBSIENYF.cjs.map +1 -0
  51. package/dist/{chunk-OZRT3ZI3.js → chunk-V4WUSOGS.js} +3 -3
  52. package/dist/{chunk-UODM3HJC.js → chunk-VWNU2PFX.js} +3 -3
  53. package/dist/{chunk-SCVIBVFS.cjs → chunk-WQXWH7LF.cjs} +4 -4
  54. package/dist/{chunk-SCVIBVFS.cjs.map → chunk-WQXWH7LF.cjs.map} +1 -1
  55. package/dist/{chunk-7COFWOCJ.cjs → chunk-XNEPABUD.cjs} +22 -22
  56. package/dist/{chunk-7COFWOCJ.cjs.map → chunk-XNEPABUD.cjs.map} +1 -1
  57. package/dist/{chunk-QYDIVL4X.js → chunk-YB5DFQKD.js} +6 -6
  58. package/dist/components/case-studies/index.cjs +9 -9
  59. package/dist/components/case-studies/index.js +3 -3
  60. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  61. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  62. package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
  63. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +1 -4
  65. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  66. package/dist/components/chat/hooks/use-slash-commands.d.ts +3 -3
  67. package/dist/components/chat/hooks/use-slash-commands.d.ts.map +1 -1
  68. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +28 -2
  69. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  70. package/dist/components/chat/index.cjs +2 -2
  71. package/dist/components/chat/index.js +1 -1
  72. package/dist/components/chat/remark-strip-citations.d.ts.map +1 -1
  73. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -1
  74. package/dist/components/chat/tool-execution-display.d.ts.map +1 -1
  75. package/dist/components/chat/types/component.types.d.ts +0 -4
  76. package/dist/components/chat/types/component.types.d.ts.map +1 -1
  77. package/dist/components/chat/types/message.types.d.ts +1 -35
  78. package/dist/components/chat/types/message.types.d.ts.map +1 -1
  79. package/dist/components/chat/types/unified-chat-state.types.d.ts +3 -3
  80. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  81. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  82. package/dist/components/contact/index.cjs +4 -4
  83. package/dist/components/contact/index.js +3 -3
  84. package/dist/components/docs/index.cjs +7 -7
  85. package/dist/components/docs/index.js +6 -6
  86. package/dist/components/embeds/index.cjs +4 -4
  87. package/dist/components/embeds/index.js +3 -3
  88. package/dist/components/faq/index.cjs +4 -4
  89. package/dist/components/faq/index.js +3 -3
  90. package/dist/components/features/index.cjs +3 -3
  91. package/dist/components/features/index.js +2 -2
  92. package/dist/components/help-center-pages/index.cjs +23 -23
  93. package/dist/components/help-center-pages/index.js +14 -14
  94. package/dist/components/index.cjs +36 -36
  95. package/dist/components/index.js +13 -13
  96. package/dist/components/meeting-scheduler/index.cjs +21 -21
  97. package/dist/components/meeting-scheduler/index.js +2 -2
  98. package/dist/components/navigation/index.cjs +6 -6
  99. package/dist/components/navigation/index.js +5 -5
  100. package/dist/components/onboarding-guides/index.cjs +6 -6
  101. package/dist/components/onboarding-guides/index.js +5 -5
  102. package/dist/components/tickets/index.cjs +7 -7
  103. package/dist/components/tickets/index.js +6 -6
  104. package/dist/components/ui/data-table/use-data-table.d.ts.map +1 -1
  105. package/dist/components/ui/hover-dropdown.d.ts.map +1 -1
  106. package/dist/components/ui/index.cjs +3 -3
  107. package/dist/components/ui/index.js +2 -2
  108. package/dist/index.cjs +7 -7
  109. package/dist/index.js +6 -6
  110. package/dist/utils/index.cjs.map +1 -1
  111. package/dist/utils/index.js.map +1 -1
  112. package/package.json +1 -2
  113. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +0 -130
  114. package/src/chat-protocol/events.ts +1 -9
  115. package/src/chat-protocol/nats-decoder.ts +0 -7
  116. package/src/components/chat/__tests__/chat-message-list.test.tsx +0 -70
  117. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +0 -86
  118. package/src/components/chat/chat-message-enhanced.tsx +13 -28
  119. package/src/components/chat/chat-message-list.tsx +22 -27
  120. package/src/components/chat/embeddable-chat.tsx +36 -55
  121. package/src/components/chat/entity-cards/dispatch.tsx +17 -86
  122. package/src/components/chat/hooks/use-nats-chat-adapter.ts +0 -7
  123. package/src/components/chat/hooks/use-slash-commands.ts +5 -9
  124. package/src/components/chat/hooks/use-sse-chat-adapter.ts +29 -2
  125. package/src/components/chat/remark-strip-citations.ts +3 -5
  126. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +0 -56
  127. package/src/components/chat/stream/chat-stream-reducer.ts +0 -31
  128. package/src/components/chat/tool-execution-display.tsx +2 -5
  129. package/src/components/chat/types/component.types.ts +0 -4
  130. package/src/components/chat/types/message.types.ts +0 -39
  131. package/src/components/chat/types/unified-chat-state.types.ts +3 -4
  132. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +0 -57
  133. package/src/components/chat/utils/process-historical-messages.ts +1 -19
  134. package/src/components/ui/__tests__/data-table-compiler-identity.test.tsx +74 -0
  135. package/src/components/ui/data-table/use-data-table.ts +36 -1
  136. package/src/components/ui/hover-dropdown.tsx +3 -8
  137. package/dist/chat-protocol/source-metadata.d.ts +0 -5
  138. package/dist/chat-protocol/source-metadata.d.ts.map +0 -1
  139. package/dist/chunk-4MVGFYRE.js.map +0 -1
  140. package/dist/chunk-EKKR5ZFB.cjs.map +0 -1
  141. package/dist/chunk-UYHETUX3.cjs.map +0 -1
  142. package/dist/components/chat/utils/chat-source-metadata.d.ts +0 -5
  143. package/dist/components/chat/utils/chat-source-metadata.d.ts.map +0 -1
  144. package/src/chat-protocol/__tests__/source-metadata.test.ts +0 -74
  145. package/src/chat-protocol/source-metadata.ts +0 -202
  146. package/src/components/chat/__tests__/embeddable-chat-sources.test.tsx +0 -411
  147. package/src/components/chat/__tests__/remark-strip-citations.test.ts +0 -52
  148. package/src/components/chat/__tests__/tool-execution-display.test.tsx +0 -93
  149. package/src/components/chat/entity-cards/__tests__/dispatch-video-refs.test.tsx +0 -74
  150. package/src/components/chat/hooks/__tests__/use-slash-commands.test.ts +0 -64
  151. package/src/components/chat/utils/chat-source-metadata.ts +0 -19
  152. /package/dist/{chunk-RE3KVI2Q.js.map → chunk-3PDTGDOA.js.map} +0 -0
  153. /package/dist/{chunk-5X7AJ67N.js.map → chunk-436G4DI4.js.map} +0 -0
  154. /package/dist/{chunk-7A6J4JTW.js.map → chunk-6BFEJXMI.js.map} +0 -0
  155. /package/dist/{chunk-RQ5PYSRJ.js.map → chunk-BLJEPNMJ.js.map} +0 -0
  156. /package/dist/{chunk-WFWWQO2I.js.map → chunk-F3YRPKUA.js.map} +0 -0
  157. /package/dist/{chunk-FDWGO244.js.map → chunk-LODCKZ72.js.map} +0 -0
  158. /package/dist/{chunk-E2QFZDCP.js.map → chunk-OKD7MX7Y.js.map} +0 -0
  159. /package/dist/{chunk-OW3FUJ2I.js.map → chunk-P24OI2CD.js.map} +0 -0
  160. /package/dist/{chunk-QSO24MEK.js.map → chunk-R2U2D7LU.js.map} +0 -0
  161. /package/dist/{chunk-KQWI25NP.js.map → chunk-SI57FQZ2.js.map} +0 -0
  162. /package/dist/{chunk-JQO47UHC.js.map → chunk-SVR75PFW.js.map} +0 -0
  163. /package/dist/{chunk-OZRT3ZI3.js.map → chunk-V4WUSOGS.js.map} +0 -0
  164. /package/dist/{chunk-UODM3HJC.js.map → chunk-VWNU2PFX.js.map} +0 -0
  165. /package/dist/{chunk-QYDIVL4X.js.map → chunk-YB5DFQKD.js.map} +0 -0
@@ -1156,8 +1156,6 @@ import { forwardRef as forwardRef6 } from "react";
1156
1156
  var MESSAGE_TYPE = {
1157
1157
  TEXT: "TEXT",
1158
1158
  THINKING: "THINKING",
1159
- GUIDE: "GUIDE",
1160
- SOURCES: "SOURCES",
1161
1159
  ASK: "ASK",
1162
1160
  EXECUTING_TOOL: "EXECUTING_TOOL",
1163
1161
  EXECUTED_TOOL: "EXECUTED_TOOL",
@@ -6814,18 +6812,17 @@ var remarkMentionChips = () => {
6814
6812
  // src/components/chat/remark-strip-citations.ts
6815
6813
  import { visit as visit3 } from "unist-util-visit";
6816
6814
  var CITATION_REGEX = /(^|\s)\[\d{1,2}(?:\s*,\s*\d{1,2})*\](?=[\s.,;:!?)\]]|$)/g;
6817
- var CITATION_LIST_REGEX = /(^|\s)(?:\[\d{1,2}(?:\s*,\s*\d{1,2})*\]\s*,\s*)+(?:(?:and|or)\s+)?\[\d{1,2}(?:\s*,\s*\d{1,2})*\](?=[\s.,;:!?)\]]|$)/g;
6818
6815
  var remarkStripCitations = () => {
6819
6816
  return (tree) => {
6820
6817
  visit3(tree, "text", (node, index, parent) => {
6821
6818
  if (!parent || typeof index !== "number") return;
6822
6819
  if (!node.value || !node.value.includes("[")) return;
6823
- const withoutCitationLists = node.value.replace(CITATION_LIST_REGEX, "$1");
6824
- const withoutCitations = withoutCitationLists.replace(CITATION_REGEX, "$1");
6820
+ const withoutCitations = node.value.replace(CITATION_REGEX, "$1");
6825
6821
  if (withoutCitations === node.value) return;
6826
6822
  parent.children.splice(index, 1, {
6827
6823
  ...node,
6828
- value: withoutCitations.replace(/\s+([.,;:!?])/g, "$1").replace(/ {2,}/g, " ")
6824
+ // Collapse doubled spaces the removal can leave mid-sentence.
6825
+ value: withoutCitations.replace(/ {2,}/g, " ")
6829
6826
  });
6830
6827
  });
6831
6828
  };
@@ -6857,8 +6854,6 @@ var ToolExecutionDisplay = forwardRef15(
6857
6854
  }, [message.parameters, variant]);
6858
6855
  const hasResult = isExecuted && typeof message.result === "string" && message.result.length > 0;
6859
6856
  const hasBody = argEntries.length > 0 || hasResult || isExecuting;
6860
- const isConciseRemoteRead = !message.integratedToolType && !!message.toolTitle?.trim() && argEntries.length === 0 && !hasResult;
6861
- const isStaticRow = isClientView || isConciseRemoteRead;
6862
6857
  const renderStatusIcon = () => {
6863
6858
  if (isExecuting) return /* @__PURE__ */ jsx34(DotsLoaderIcon, { size: 16, className: "text-ods-text-secondary" });
6864
6859
  if (isExecuted && message.success === true) return /* @__PURE__ */ jsx34(CheckCircleIcon, { className: "h-4 w-4 text-ods-success" });
@@ -6878,7 +6873,7 @@ var ToolExecutionDisplay = forwardRef15(
6878
6873
  }
6879
6874
  ),
6880
6875
  /* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: renderStatusIcon() }),
6881
- !isStaticRow && /* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx34(ExpandChevron, { expanded }) })
6876
+ !isClientView && /* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx34(ExpandChevron, { expanded }) })
6882
6877
  ] });
6883
6878
  return /* @__PURE__ */ jsx34(
6884
6879
  "div",
@@ -6891,7 +6886,7 @@ var ToolExecutionDisplay = forwardRef15(
6891
6886
  className
6892
6887
  ),
6893
6888
  ...props,
6894
- children: isStaticRow ? (
6889
+ children: isClientView ? (
6895
6890
  // Client (Fae end-user): static, non-expandable row — no chevron, no
6896
6891
  // body. Just the explanation + status; command/args/result are hidden.
6897
6892
  /* @__PURE__ */ jsx34("div", { className: "flex w-full items-start gap-[var(--spacing-system-xs)] p-[var(--spacing-system-s)] text-left", children: headerContent })
@@ -6985,7 +6980,6 @@ var ChatMessageEnhanced = forwardRef16(
6985
6980
  renderContextItem,
6986
6981
  renderMention,
6987
6982
  renderEntityCard,
6988
- refs,
6989
6983
  onAskSelect,
6990
6984
  NavLinkAnchor,
6991
6985
  ...props
@@ -6994,10 +6988,6 @@ var ChatMessageEnhanced = forwardRef16(
6994
6988
  const isError = role === "error";
6995
6989
  const authorType = authorTypeProp ?? (isUser ? "user" : assistantType === "mingo" ? "mingo" : "fae");
6996
6990
  const hasMarkerSupport = !!renderEntityCard;
6997
- const refsByKey = useMemo8(
6998
- () => new Map((refs ?? []).map((reference) => [`${reference.type}:${reference.id}`, reference])),
6999
- [refs]
7000
- );
7001
6991
  const segments = useMemo8(() => normalizeContent(content), [content]);
7002
6992
  const askRuns = useMemo8(() => groupAskRuns(segments), [segments]);
7003
6993
  const hasMentionSupport = !!renderMention;
@@ -7046,15 +7036,14 @@ var ChatMessageEnhanced = forwardRef16(
7046
7036
  const key = `${cardType}:${cardId}`;
7047
7037
  usedKeys.add(key);
7048
7038
  let entry = cache.get(key);
7049
- const enrichedRef = refsByKey.get(key);
7050
- const refForRender = enrichedRef ?? {
7051
- type: cardType,
7052
- id: cardId,
7053
- title: cardId,
7054
- url: null
7055
- };
7056
- if (!entry || entry.render !== render || entry.reference !== refForRender) {
7057
- entry = { render, reference: refForRender, node: render(refForRender) };
7039
+ if (!entry || entry.render !== render) {
7040
+ const refForRender = {
7041
+ type: cardType,
7042
+ id: cardId,
7043
+ title: cardId,
7044
+ url: null
7045
+ };
7046
+ entry = { render, node: render(refForRender) };
7058
7047
  cache.set(key, entry);
7059
7048
  }
7060
7049
  const rendered = entry.node;
@@ -7088,7 +7077,7 @@ var ChatMessageEnhanced = forwardRef16(
7088
7077
  }
7089
7078
  });
7090
7079
  return { inlineByKey, partsBySegment, usedKeys };
7091
- }, [hasMarkerSupport, refsByKey, renderEntityCard, segments]);
7080
+ }, [hasMarkerSupport, renderEntityCard, segments]);
7092
7081
  useEffect6(() => {
7093
7082
  const cache = renderedCardNodeCache.current;
7094
7083
  const usedKeys = renderingPlan?.usedKeys;
@@ -7315,7 +7304,7 @@ var MemoizedChatMessageEnhanced = memo2(ChatMessageEnhanced, (prevProps, nextPro
7315
7304
  // message (it's set once on the optimistic send and never mutated).
7316
7305
  prevProps.contextItems === nextProps.contextItems && prevProps.resolveContextIcon === nextProps.resolveContextIcon && prevProps.renderContextItem === nextProps.renderContextItem && // Host keeps this stable (module const / useCallback), so reference
7317
7306
  // equality holds across streaming chunks.
7318
- prevProps.renderMention === nextProps.renderMention && prevProps.renderEntityCard === nextProps.renderEntityCard && prevProps.refs === nextProps.refs && // Same stability contract as the renderers above: hosts pass a `useCallback`
7307
+ prevProps.renderMention === nextProps.renderMention && prevProps.renderEntityCard === nextProps.renderEntityCard && // Same stability contract as the renderers above: hosts pass a `useCallback`
7319
7308
  // (EmbeddableChat passes its memoized `handleSend`), so this holds across
7320
7309
  // streaming chunks instead of re-rendering every ask card per chunk.
7321
7310
  prevProps.onAskSelect === nextProps.onAskSelect && prevProps.NavLinkAnchor === nextProps.NavLinkAnchor;
@@ -7324,7 +7313,6 @@ MemoizedChatMessageEnhanced.displayName = "MemoizedChatMessageEnhanced";
7324
7313
 
7325
7314
  // src/components/chat/chat-message-list.tsx
7326
7315
  import {
7327
- Fragment as Fragment11,
7328
7316
  useRef as useRef5,
7329
7317
  useState as useState14,
7330
7318
  useCallback as useCallback5,
@@ -7528,7 +7516,6 @@ var ChatMessageList = forwardRef17(
7528
7516
  renderContextItem,
7529
7517
  renderMention,
7530
7518
  onAskSelect,
7531
- renderAfterMessage,
7532
7519
  NavLinkAnchor,
7533
7520
  ...props
7534
7521
  }, ref) => {
@@ -7885,34 +7872,31 @@ var ChatMessageList = forwardRef17(
7885
7872
  if (message.hidden) return null;
7886
7873
  const isEmptyPendingTurn = index === messages.length - 1 && isTyping && message.role === "assistant" && !hasNonEmptyContent(message.content) && (!Array.isArray(message.content) || message.content.every((s) => s.type === "text"));
7887
7874
  if (isEmptyPendingTurn) return null;
7888
- return /* @__PURE__ */ jsxs28(Fragment11, { children: [
7889
- /* @__PURE__ */ jsx38(
7890
- MemoizedChatMessageEnhanced,
7891
- {
7892
- ref: getRegisterMessageEl(message.id),
7893
- role: message.role,
7894
- name: message.name,
7895
- content: message.content,
7896
- timestamp: message.timestamp,
7897
- isTyping: index === messages.length - 1 && isTyping && message.role === "assistant",
7898
- avatar: showAvatars ? message.avatar : null,
7899
- showAvatar: showAvatars,
7900
- assistantType: message.assistantType || assistantType,
7901
- approvalVariant,
7902
- authorType: message.authorType,
7903
- assistantIcon: message.role !== "user" ? assistantIcon : void 0,
7904
- contextItems: message.contextItems,
7905
- resolveContextIcon,
7906
- renderContextItem,
7907
- renderMention,
7908
- renderEntityCard,
7909
- refs: message.refs,
7910
- onAskSelect: index > lastUserMessageIndex ? onAskSelect : void 0,
7911
- NavLinkAnchor
7912
- }
7913
- ),
7914
- renderAfterMessage?.(message, index)
7915
- ] }, message.id);
7875
+ return /* @__PURE__ */ jsx38(
7876
+ MemoizedChatMessageEnhanced,
7877
+ {
7878
+ ref: getRegisterMessageEl(message.id),
7879
+ role: message.role,
7880
+ name: message.name,
7881
+ content: message.content,
7882
+ timestamp: message.timestamp,
7883
+ isTyping: index === messages.length - 1 && isTyping && message.role === "assistant",
7884
+ avatar: showAvatars ? message.avatar : null,
7885
+ showAvatar: showAvatars,
7886
+ assistantType: message.assistantType || assistantType,
7887
+ approvalVariant,
7888
+ authorType: message.authorType,
7889
+ assistantIcon: message.role !== "user" ? assistantIcon : void 0,
7890
+ contextItems: message.contextItems,
7891
+ resolveContextIcon,
7892
+ renderContextItem,
7893
+ renderMention,
7894
+ renderEntityCard,
7895
+ onAskSelect: index > lastUserMessageIndex ? onAskSelect : void 0,
7896
+ NavLinkAnchor
7897
+ },
7898
+ message.id
7899
+ );
7916
7900
  })
7917
7901
  ]
7918
7902
  }
@@ -8090,7 +8074,7 @@ function EntityIcon({
8090
8074
  }
8091
8075
 
8092
8076
  // src/components/chat/quick-action-chip.tsx
8093
- import { Fragment as Fragment12, jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
8077
+ import { Fragment as Fragment11, jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
8094
8078
  var AGENT_ACCENTS = { fae: "pink", mingo: "cyan" };
8095
8079
  function getAgentAccent(slug) {
8096
8080
  return slug === "fae" || slug === "mingo" ? AGENT_ACCENTS[slug] : void 0;
@@ -8118,7 +8102,7 @@ function renderQuickActionIcon(icon) {
8118
8102
  }
8119
8103
  function composeChipLabel(label, lozenge) {
8120
8104
  if (!lozenge) return label;
8121
- return /* @__PURE__ */ jsxs30(Fragment12, { children: [
8105
+ return /* @__PURE__ */ jsxs30(Fragment11, { children: [
8122
8106
  /* @__PURE__ */ jsx42(
8123
8107
  "span",
8124
8108
  {
@@ -8155,7 +8139,7 @@ function QuickActionChipSkeleton({
8155
8139
  size: size2,
8156
8140
  className,
8157
8141
  icon: icon ? /* @__PURE__ */ jsx42(ChipSkelBar, { className: size2 === "large" ? "block size-5" : "block size-4" }) : void 0,
8158
- label: /* @__PURE__ */ jsxs30(Fragment12, { children: [
8142
+ label: /* @__PURE__ */ jsxs30(Fragment11, { children: [
8159
8143
  lozenge && /* @__PURE__ */ jsx42(ChipSkelBar, { className: "mr-2 inline-block h-[16px] w-[26px] translate-y-[2px]" }),
8160
8144
  /* @__PURE__ */ jsx42(ChipSkelBar, { className: "inline-block h-[0.9em] translate-y-[0.08em]", style: { width: `${labelCh}ch` } })
8161
8145
  ] })
@@ -8245,7 +8229,7 @@ import {
8245
8229
  useState as useState16,
8246
8230
  useSyncExternalStore as useSyncExternalStore2
8247
8231
  } from "react";
8248
- import { Fragment as Fragment13, jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
8232
+ import { Fragment as Fragment12, jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
8249
8233
  function normalizeFades(fade) {
8250
8234
  if (fade === void 0) return [];
8251
8235
  return typeof fade === "string" ? [fade] : fade;
@@ -8333,7 +8317,7 @@ function MarqueeWallFades({
8333
8317
  fadeColor = "var(--color-bg)",
8334
8318
  fadeSize
8335
8319
  }) {
8336
- return /* @__PURE__ */ jsx43(Fragment13, { children: normalizeFades(fade).map((edge) => {
8320
+ return /* @__PURE__ */ jsx43(Fragment12, { children: normalizeFades(fade).map((edge) => {
8337
8321
  const size2 = (typeof fadeSize === "object" && fadeSize !== null ? fadeSize[edge] : fadeSize) ?? DEFAULT_FADE_SIZE[edge];
8338
8322
  const px = typeof size2 === "number" ? `${size2}px` : size2;
8339
8323
  const isY = edge === "top" || edge === "bottom";
@@ -9422,7 +9406,7 @@ function MingoChatHistory({
9422
9406
  }
9423
9407
 
9424
9408
  // src/components/chat/mingo-welcome.tsx
9425
- import { Fragment as Fragment14, jsx as jsx52, jsxs as jsxs39 } from "react/jsx-runtime";
9409
+ import { Fragment as Fragment13, jsx as jsx52, jsxs as jsxs39 } from "react/jsx-runtime";
9426
9410
  var DEFAULT_SUBTITLE = "Ready to help with your technical tasks. What can I do for you?";
9427
9411
  var DEFAULT_PROMO = {
9428
9412
  title: "New to OpenFrame?",
@@ -9489,7 +9473,7 @@ function MingoWelcome({
9489
9473
  /* @__PURE__ */ jsx52("p", { className: "text-body-sm text-ods-text-secondary", children: "Something went wrong reaching the server. Check your connection and try again." })
9490
9474
  ] }),
9491
9475
  onRetry && /* @__PURE__ */ jsx52(Button, { variant: "outline", size: "small", leftIcon: /* @__PURE__ */ jsx52(Refresh01RightIcon, {}), onClick: onRetry, children: "Try again" })
9492
- ] }) : isLoadingHistory ? /* @__PURE__ */ jsx52(MingoChatHistorySkeleton, {}) : /* @__PURE__ */ jsx52(Fragment14, { children: /* @__PURE__ */ jsxs39("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
9476
+ ] }) : isLoadingHistory ? /* @__PURE__ */ jsx52(MingoChatHistorySkeleton, {}) : /* @__PURE__ */ jsx52(Fragment13, { children: /* @__PURE__ */ jsxs39("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
9493
9477
  /* @__PURE__ */ jsx52(
9494
9478
  "div",
9495
9479
  {
@@ -10086,7 +10070,7 @@ var ModalFooter = forwardRef20(({ children, className }, ref) => /* @__PURE__ */
10086
10070
  ModalFooter.displayName = "ModalV2Footer";
10087
10071
 
10088
10072
  // src/components/chat/mingo-chat-modals.tsx
10089
- import { Fragment as Fragment15, jsx as jsx58, jsxs as jsxs45 } from "react/jsx-runtime";
10073
+ import { Fragment as Fragment14, jsx as jsx58, jsxs as jsxs45 } from "react/jsx-runtime";
10090
10074
  var footerBtn = "flex-1 min-w-0 rounded-md px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)] text-h3 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent disabled:opacity-50 disabled:cursor-not-allowed";
10091
10075
  var cancelBtn = cn(footerBtn, "border border-ods-border bg-transparent text-ods-text-primary hover:bg-ods-bg-hover");
10092
10076
  var saveBtn = cn(footerBtn, "bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover");
@@ -10157,7 +10141,7 @@ function ChatDialogModals({
10157
10141
  setRestoreTarget,
10158
10142
  onConfirmRestore
10159
10143
  }) {
10160
- return /* @__PURE__ */ jsxs45(Fragment15, { children: [
10144
+ return /* @__PURE__ */ jsxs45(Fragment14, { children: [
10161
10145
  /* @__PURE__ */ jsx58(
10162
10146
  RenameChatModal,
10163
10147
  {
@@ -10363,7 +10347,7 @@ function ChatPanelHeaderMobile({
10363
10347
  }
10364
10348
 
10365
10349
  // src/components/chat/chat-panel-header.tsx
10366
- import { Fragment as Fragment16, jsx as jsx62, jsxs as jsxs48 } from "react/jsx-runtime";
10350
+ import { Fragment as Fragment15, jsx as jsx62, jsxs as jsxs48 } from "react/jsx-runtime";
10367
10351
  function ChatPanelHeader({
10368
10352
  showBack = false,
10369
10353
  title,
@@ -10390,7 +10374,7 @@ function ChatPanelHeader({
10390
10374
  onRename && { id: "rename", label: "Rename chat", onClick: onRename },
10391
10375
  onArchive && { id: "archive", label: "Archive chat", onClick: onArchive }
10392
10376
  ].filter(Boolean);
10393
- return /* @__PURE__ */ jsxs48(Fragment16, { children: [
10377
+ return /* @__PURE__ */ jsxs48(Fragment15, { children: [
10394
10378
  !compact && /* @__PURE__ */ jsx62(
10395
10379
  ChatPanelHeaderMobile,
10396
10380
  {
@@ -10528,7 +10512,7 @@ function stripChatAttachmentMarkdown(text) {
10528
10512
  }
10529
10513
 
10530
10514
  // src/components/chat/chat-attachment-bar.tsx
10531
- import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs49 } from "react/jsx-runtime";
10515
+ import { Fragment as Fragment16, jsx as jsx63, jsxs as jsxs49 } from "react/jsx-runtime";
10532
10516
  var CHAT_ATTACHMENT_MIME_TYPES = [
10533
10517
  "image/jpeg",
10534
10518
  "image/png",
@@ -10558,7 +10542,7 @@ function ChatAttachmentAddButton({
10558
10542
  if (!canAddMore) return;
10559
10543
  fileInputRef.current?.click();
10560
10544
  };
10561
- return /* @__PURE__ */ jsxs49(Fragment17, { children: [
10545
+ return /* @__PURE__ */ jsxs49(Fragment16, { children: [
10562
10546
  /* @__PURE__ */ jsx63(
10563
10547
  "input",
10564
10548
  {
@@ -11105,11 +11089,11 @@ function ChatComposer({
11105
11089
  }
11106
11090
 
11107
11091
  // src/components/chat/chat-archive-page.tsx
11108
- import { Fragment as Fragment18, jsx as jsx68, jsxs as jsxs53 } from "react/jsx-runtime";
11092
+ import { Fragment as Fragment17, jsx as jsx68, jsxs as jsxs53 } from "react/jsx-runtime";
11109
11093
  function ChatArchivePage(props) {
11110
11094
  const { dialogs, onSelectDialog, isLoading = false, isFetching = false, hasMore = false, onLoadMore } = props;
11111
11095
  const suppressEmptyStateWhileFetching = isFetching;
11112
- return /* @__PURE__ */ jsxs53(Fragment18, { children: [
11096
+ return /* @__PURE__ */ jsxs53(Fragment17, { children: [
11113
11097
  !props.embedded && /* @__PURE__ */ jsx68(
11114
11098
  ChatPanelHeaderMobile,
11115
11099
  {
@@ -11215,7 +11199,7 @@ var ChatSidebarSkeleton = forwardRef23(
11215
11199
  ChatSidebarSkeleton.displayName = "ChatSidebarSkeleton";
11216
11200
 
11217
11201
  // src/components/chat/chat-sidebar.tsx
11218
- import { Fragment as Fragment19, jsx as jsx70, jsxs as jsxs55 } from "react/jsx-runtime";
11202
+ import { Fragment as Fragment18, jsx as jsx70, jsxs as jsxs55 } from "react/jsx-runtime";
11219
11203
  var DialogListItem = forwardRef24(
11220
11204
  ({ className, dialog, isActive, onDialogSelect, onClick, ...props }, ref) => {
11221
11205
  const handleClick = (e) => {
@@ -11352,7 +11336,7 @@ var ChatSidebar = forwardRef24(
11352
11336
  },
11353
11337
  dialog.id
11354
11338
  )),
11355
- hasNextPage && /* @__PURE__ */ jsx70("div", { ref: loadMoreRef, children: isFetchingNextPage && /* @__PURE__ */ jsxs55(Fragment19, { children: [
11339
+ hasNextPage && /* @__PURE__ */ jsx70("div", { ref: loadMoreRef, children: isFetchingNextPage && /* @__PURE__ */ jsxs55(Fragment18, { children: [
11356
11340
  /* @__PURE__ */ jsx70(DialogListItemSkeleton, {}),
11357
11341
  /* @__PURE__ */ jsx70(DialogListItemSkeleton, {}),
11358
11342
  /* @__PURE__ */ jsx70(DialogListItemSkeleton, {})
@@ -11597,7 +11581,7 @@ function captionsEntityTypeForDocType(docType) {
11597
11581
  }
11598
11582
 
11599
11583
  // src/components/layout/page-heading.tsx
11600
- import { Fragment as Fragment20, jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
11584
+ import { Fragment as Fragment19, jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
11601
11585
  var PAGE_HEADING_CLASS = "text-h1 text-ods-text-primary";
11602
11586
  var SECTION_HEADING_CLASS = "text-h2 text-ods-text-primary";
11603
11587
  var DESCRIPTION_CLASS = "mt-6 max-w-[640px] font-body text-[16px] md:text-[18px] leading-[24px] md:leading-[28px] text-ods-text-secondary";
@@ -11611,7 +11595,7 @@ function PageHeading({
11611
11595
  const headingClass = className ? `${PAGE_HEADING_CLASS} ${className}` : PAGE_HEADING_CLASS;
11612
11596
  const descClass = descriptionClassName ? `${DESCRIPTION_CLASS} ${descriptionClassName}` : DESCRIPTION_CLASS;
11613
11597
  const hasDescription = description != null && description !== "" && typeof description !== "boolean";
11614
- return /* @__PURE__ */ jsxs56(Fragment20, { children: [
11598
+ return /* @__PURE__ */ jsxs56(Fragment19, { children: [
11615
11599
  /* @__PURE__ */ jsx73(Tag2, { className: headingClass, children }),
11616
11600
  hasDescription && /* @__PURE__ */ jsx73("p", { className: descClass, children: description })
11617
11601
  ] });
@@ -12792,7 +12776,7 @@ function CardHitLayer({
12792
12776
 
12793
12777
  // src/components/features/cards-strip.tsx
12794
12778
  import React5, { useCallback as useCallback12, useEffect as useEffect20, useMemo as useMemo21, useRef as useRef16, useState as useState26 } from "react";
12795
- import { Fragment as Fragment21, jsx as jsx79, jsxs as jsxs59 } from "react/jsx-runtime";
12779
+ import { Fragment as Fragment20, jsx as jsx79, jsxs as jsxs59 } from "react/jsx-runtime";
12796
12780
  var TRACK_GAP_PX = 16;
12797
12781
  var CHEVRON_SUPPRESS_MS = 4e3;
12798
12782
  var USER_SCROLL_SUPPRESS_MS = 3e3;
@@ -13169,7 +13153,7 @@ function CardsStrip(props) {
13169
13153
  ) })
13170
13154
  }
13171
13155
  ),
13172
- showChevrons && overflows && /* @__PURE__ */ jsxs59(Fragment21, { children: [
13156
+ showChevrons && overflows && /* @__PURE__ */ jsxs59(Fragment20, { children: [
13173
13157
  /* @__PURE__ */ jsx79(
13174
13158
  Button,
13175
13159
  {
@@ -13203,7 +13187,7 @@ function CardsStrip(props) {
13203
13187
 
13204
13188
  // src/components/features/video-hover-preview.tsx
13205
13189
  import { useEffect as useEffect21, useRef as useRef17, useState as useState27 } from "react";
13206
- import { Fragment as Fragment22, jsx as jsx80, jsxs as jsxs60 } from "react/jsx-runtime";
13190
+ import { Fragment as Fragment21, jsx as jsx80, jsxs as jsxs60 } from "react/jsx-runtime";
13207
13191
  function VideoHoverPreviewSurface({
13208
13192
  url,
13209
13193
  posterUrl = null,
@@ -13242,7 +13226,7 @@ function VideoHoverPreviewSurface({
13242
13226
  const showMedia = continuation || (gateControlled ? playerMounted : isNear);
13243
13227
  const { src: posterSrc, onError: onPosterError } = useCoverImageFallback(posterUrl);
13244
13228
  const facadeSkipped = preload === "none" && !posterSrc;
13245
- return /* @__PURE__ */ jsx80("div", { ref: rootElRef, className: cn("absolute inset-0", className), inert: isClone || void 0, children: showMedia ? /* @__PURE__ */ jsxs60(Fragment22, { children: [
13229
+ return /* @__PURE__ */ jsx80("div", { ref: rootElRef, className: cn("absolute inset-0", className), inert: isClone || void 0, children: showMedia ? /* @__PURE__ */ jsxs60(Fragment21, { children: [
13246
13230
  posterSrc ? /* @__PURE__ */ jsx80(
13247
13231
  next_image_default,
13248
13232
  {
@@ -13291,7 +13275,7 @@ function VideoHoverPreviewSurface({
13291
13275
  }
13292
13276
 
13293
13277
  // src/components/features/video-ratio-tabs.tsx
13294
- import { Fragment as Fragment23, jsx as jsx81, jsxs as jsxs61 } from "react/jsx-runtime";
13278
+ import { Fragment as Fragment22, jsx as jsx81, jsxs as jsxs61 } from "react/jsx-runtime";
13295
13279
  var TAB_TRIGGER_CLASS = "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2 text-h6 text-ods-text-secondary data-[state=active]:text-ods-text-primary";
13296
13280
  var RATIO_GRID_CLASS = {
13297
13281
  portrait: "grid grid-cols-2 md:grid-cols-3 gap-4",
@@ -13312,7 +13296,7 @@ function RatioTabs({ groups, defaultTab, className = "" }) {
13312
13296
  const activeTabs = RATIO_TAB_CONFIG.filter((t) => groups[t.key].count > 0);
13313
13297
  if (activeTabs.length <= 1) {
13314
13298
  const active = activeTabs[0];
13315
- return active ? /* @__PURE__ */ jsx81(Fragment23, { children: groups[active.key].render() }) : null;
13299
+ return active ? /* @__PURE__ */ jsx81(Fragment22, { children: groups[active.key].render() }) : null;
13316
13300
  }
13317
13301
  const firstTab = defaultTab && groups[defaultTab].count > 0 ? defaultTab : activeTabs[0].key;
13318
13302
  return /* @__PURE__ */ jsxs61(Tabs, { defaultValue: firstTab, className: `w-full ${className}`, children: [
@@ -13355,7 +13339,7 @@ function groupByAspectRatio(items, getAspectRatio) {
13355
13339
  }
13356
13340
 
13357
13341
  // src/components/features/video-bites-strip.tsx
13358
- import { Fragment as Fragment24, jsx as jsx82, jsxs as jsxs62 } from "react/jsx-runtime";
13342
+ import { Fragment as Fragment23, jsx as jsx82, jsxs as jsxs62 } from "react/jsx-runtime";
13359
13343
  function VideoBitesStrip({
13360
13344
  bites,
13361
13345
  title = DEFAULT_VIDEO_BITES_TITLE,
@@ -13468,7 +13452,7 @@ function VideoBiteCard({
13468
13452
  if (isTouch && !isActive) activate();
13469
13453
  };
13470
13454
  const titleClass = "text-h6 text-ods-text-primary";
13471
- const overlayContent = /* @__PURE__ */ jsxs62(Fragment24, { children: [
13455
+ const overlayContent = /* @__PURE__ */ jsxs62(Fragment23, { children: [
13472
13456
  titleEditable ? (
13473
13457
  // Textarea, not input: the public title wraps to two lines
13474
13458
  // (line-clamp-2) and the editor must render identically. rows=1 +
@@ -13540,7 +13524,7 @@ function VideoBiteCard({
13540
13524
  // the bottom strip, so the card centre (where the play glyph sits) was
13541
13525
  // not clickable and showed no pointer cursor even though the glyph
13542
13526
  // accented on hover. One interactive element, no a11y duplication.
13543
- /* @__PURE__ */ jsxs62(Fragment24, { children: [
13527
+ /* @__PURE__ */ jsxs62(Fragment23, { children: [
13544
13528
  /* @__PURE__ */ jsx82(
13545
13529
  CardHitLayer,
13546
13530
  {
@@ -13586,7 +13570,7 @@ function VideoBiteCard({
13586
13570
  }
13587
13571
 
13588
13572
  // src/components/features/entity-video-section.tsx
13589
- import { Fragment as Fragment25, jsx as jsx83, jsxs as jsxs63 } from "react/jsx-runtime";
13573
+ import { Fragment as Fragment24, jsx as jsx83, jsxs as jsxs63 } from "react/jsx-runtime";
13590
13574
  function EntityVideoSection({
13591
13575
  mainVideoUrl,
13592
13576
  youtubeUrl,
@@ -13622,7 +13606,7 @@ function EntityVideoSection({
13622
13606
  }
13623
13607
  const fullVideoUrl = youtubeUrl || mainVideoUrl || null;
13624
13608
  const fullVideoKind = youtubeUrl ? "youtube" : "auto";
13625
- return /* @__PURE__ */ jsxs63(Fragment25, { children: [
13609
+ return /* @__PURE__ */ jsxs63(Fragment24, { children: [
13626
13610
  hasVideo && (fullVideoUrl && hasHighlight ? /* @__PURE__ */ jsxs63(Tabs, { defaultValue: "full-video", className: "w-full", children: [
13627
13611
  /* @__PURE__ */ jsxs63(TabsList, { className: "inline-flex h-auto justify-start gap-0 rounded-none bg-transparent p-0", children: [
13628
13612
  /* @__PURE__ */ jsx83(
@@ -13735,7 +13719,7 @@ function ChatVideoEntityCard({ chatRef }) {
13735
13719
  // src/components/chat/entity-cards/github-activity-card.tsx
13736
13720
  import { GitPullRequest, Eye, ExternalLink } from "lucide-react";
13737
13721
  import React6 from "react";
13738
- import { Fragment as Fragment26, jsx as jsx85, jsxs as jsxs64 } from "react/jsx-runtime";
13722
+ import { Fragment as Fragment25, jsx as jsx85, jsxs as jsxs64 } from "react/jsx-runtime";
13739
13723
  function parseRepoFromUrl(url) {
13740
13724
  if (!url) return null;
13741
13725
  try {
@@ -13870,7 +13854,7 @@ function GitHubActivityCard({ item, variant = "compact", className, anchorProps
13870
13854
  /* @__PURE__ */ jsx85("span", { className: "whitespace-nowrap", children: dateText }, "date")
13871
13855
  );
13872
13856
  const href = safeHref(item.url);
13873
- const body = /* @__PURE__ */ jsxs64(Fragment26, { children: [
13857
+ const body = /* @__PURE__ */ jsxs64(Fragment25, { children: [
13874
13858
  /* @__PURE__ */ jsx85("span", { className: COMPACT_CARD_ICON_SLOT, children: kindIcon(kind, "h-5 w-5") }),
13875
13859
  /* @__PURE__ */ jsxs64("span", { className: COMPACT_CARD_TEXT_COL, children: [
13876
13860
  /* @__PURE__ */ jsxs64("span", { className: `${COMPACT_CARD_TITLE_ROW} flex-nowrap gap-1.5`, children: [
@@ -13919,7 +13903,7 @@ function GitHubActivityCardSkeleton({
13919
13903
  // src/components/chat/entity-cards/slack-message-card.tsx
13920
13904
  import { ExternalLink as ExternalLink2, Hash } from "lucide-react";
13921
13905
  import React7 from "react";
13922
- import { Fragment as Fragment27, jsx as jsx86, jsxs as jsxs65 } from "react/jsx-runtime";
13906
+ import { Fragment as Fragment26, jsx as jsx86, jsxs as jsxs65 } from "react/jsx-runtime";
13923
13907
  function parseChannelFromUrl(url) {
13924
13908
  if (!url) return null;
13925
13909
  try {
@@ -13961,7 +13945,7 @@ function SlackMessageCard({ item, variant = "compact", className, anchorProps })
13961
13945
  /* @__PURE__ */ jsx86("span", { className: "whitespace-nowrap", children: dateText }, "date")
13962
13946
  );
13963
13947
  const href = safeHref(item.url);
13964
- const body = /* @__PURE__ */ jsxs65(Fragment27, { children: [
13948
+ const body = /* @__PURE__ */ jsxs65(Fragment26, { children: [
13965
13949
  /* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_ICON_SLOT, children: /* @__PURE__ */ jsx86(SlackIcon, { className: "h-5 w-5" }) }),
13966
13950
  /* @__PURE__ */ jsxs65("span", { className: COMPACT_CARD_TEXT_COL, children: [
13967
13951
  /* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_TITLE, children: item.title }) }),
@@ -14005,7 +13989,7 @@ function SlackMessageCardSkeleton({
14005
13989
  // src/components/chat/entity-cards/hubspot-ticket-card.tsx
14006
13990
  import { ExternalLink as ExternalLink3 } from "lucide-react";
14007
13991
  import React8 from "react";
14008
- import { Fragment as Fragment28, jsx as jsx87, jsxs as jsxs66 } from "react/jsx-runtime";
13992
+ import { Fragment as Fragment27, jsx as jsx87, jsxs as jsxs66 } from "react/jsx-runtime";
14009
13993
  function formatToken(token) {
14010
13994
  if (!token) return null;
14011
13995
  const lower = token.toLowerCase().replace(/_/g, " ");
@@ -14047,7 +14031,7 @@ function HubspotTicketCard({ item, variant = "compact", className, anchorProps }
14047
14031
  /* @__PURE__ */ jsx87("span", { className: "whitespace-nowrap", children: dateText }, "date")
14048
14032
  );
14049
14033
  const href = safeHref(item.url);
14050
- const body = /* @__PURE__ */ jsxs66(Fragment28, { children: [
14034
+ const body = /* @__PURE__ */ jsxs66(Fragment27, { children: [
14051
14035
  /* @__PURE__ */ jsxs66("span", { className: COMPACT_CARD_TEXT_COL, children: [
14052
14036
  /* @__PURE__ */ jsxs66("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
14053
14037
  /* @__PURE__ */ jsx87("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
@@ -14121,9 +14105,9 @@ function HubspotTicketCardSkeleton({
14121
14105
 
14122
14106
  // src/components/chat/entity-cards/data-room-doc-card.tsx
14123
14107
  import { ExternalLink as ExternalLink4 } from "lucide-react";
14124
- import { Fragment as Fragment29, jsx as jsx88, jsxs as jsxs67 } from "react/jsx-runtime";
14108
+ import { Fragment as Fragment28, jsx as jsx88, jsxs as jsxs67 } from "react/jsx-runtime";
14125
14109
  function DataRoomDocCard({ item, className, badgeText, anchorProps }) {
14126
- const body = /* @__PURE__ */ jsxs67(Fragment29, { children: [
14110
+ const body = /* @__PURE__ */ jsxs67(Fragment28, { children: [
14127
14111
  /* @__PURE__ */ jsxs67("span", { className: COMPACT_CARD_TEXT_COL, children: [
14128
14112
  /* @__PURE__ */ jsxs67("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
14129
14113
  /* @__PURE__ */ jsx88("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
@@ -14161,10 +14145,10 @@ function DataRoomDocCardSkeleton({ className }) {
14161
14145
 
14162
14146
  // src/components/chat/entity-cards/campaign-card-admin.tsx
14163
14147
  import { Megaphone as Megaphone3 } from "lucide-react";
14164
- import { Fragment as Fragment30, jsx as jsx89, jsxs as jsxs68 } from "react/jsx-runtime";
14148
+ import { Fragment as Fragment29, jsx as jsx89, jsxs as jsxs68 } from "react/jsx-runtime";
14165
14149
  function CampaignCardAdmin({ campaign, className, anchorProps }) {
14166
14150
  const goalsCount = campaign.goals?.length || 0;
14167
- const innerChildren = /* @__PURE__ */ jsxs68(Fragment30, { children: [
14151
+ const innerChildren = /* @__PURE__ */ jsxs68(Fragment29, { children: [
14168
14152
  /* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_ICON_SLOT, children: /* @__PURE__ */ jsx89(Megaphone3, { className: "h-5 w-5" }) }),
14169
14153
  /* @__PURE__ */ jsxs68("span", { className: COMPACT_CARD_TEXT_COL, children: [
14170
14154
  /* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_TITLE, children: campaign.name }) }),
@@ -14194,11 +14178,11 @@ function CampaignCardAdminSkeleton({ className }) {
14194
14178
 
14195
14179
  // src/components/chat/entity-cards/generic-entity-card.tsx
14196
14180
  import { ExternalLink as ExternalLink5 } from "lucide-react";
14197
- import { Fragment as Fragment31, jsx as jsx90, jsxs as jsxs69 } from "react/jsx-runtime";
14181
+ import { Fragment as Fragment30, jsx as jsx90, jsxs as jsxs69 } from "react/jsx-runtime";
14198
14182
  function GenericEntityCard({ item, className, anchorProps }) {
14199
14183
  const href = safeHref(item.url);
14200
14184
  const dateText = formatDateUTC(item.dateUpdated, { fallback: "", timezone: "local" });
14201
- const body = /* @__PURE__ */ jsxs69(Fragment31, { children: [
14185
+ const body = /* @__PURE__ */ jsxs69(Fragment30, { children: [
14202
14186
  /* @__PURE__ */ jsxs69("span", { className: COMPACT_CARD_TEXT_COL, children: [
14203
14187
  /* @__PURE__ */ jsxs69("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
14204
14188
  /* @__PURE__ */ jsx90("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
@@ -14251,190 +14235,6 @@ function GenericEntityCardSkeleton({ className }) {
14251
14235
  // src/components/chat/entity-cards/dispatch.tsx
14252
14236
  import React9 from "react";
14253
14237
 
14254
- // src/chat-protocol/source-metadata.ts
14255
- var CARD_REFERENCE = /^\[card:\/\/([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)\]$/;
14256
- var SOURCE_METADATA_MATCHED = "sourceMetadataMatched";
14257
- function isSourceMetadataCardRef(ref) {
14258
- return ref.metadata?.[SOURCE_METADATA_MATCHED] === true;
14259
- }
14260
- function requiredString(value) {
14261
- if (typeof value !== "string") return null;
14262
- const normalized = value.trim();
14263
- return normalized ? normalized : null;
14264
- }
14265
- function optionalString(value) {
14266
- return requiredString(value) ?? void 0;
14267
- }
14268
- function httpsUrl(value) {
14269
- const candidate = optionalString(value);
14270
- if (!candidate) return void 0;
14271
- try {
14272
- return new URL(candidate).protocol === "https:" ? candidate : void 0;
14273
- } catch {
14274
- return void 0;
14275
- }
14276
- }
14277
- function youtubeId(value) {
14278
- const candidate = optionalString(value);
14279
- if (!candidate) return void 0;
14280
- if (/^[A-Za-z0-9_-]{11}$/.test(candidate)) return candidate;
14281
- const url = httpsUrl(candidate);
14282
- if (!url) return void 0;
14283
- const parsed = new URL(url);
14284
- const hostname = parsed.hostname.toLowerCase();
14285
- const youtubeHost = hostname === "youtu.be" || hostname === "youtube.com" || hostname.endsWith(".youtube.com");
14286
- if (!youtubeHost) return void 0;
14287
- const pathId = hostname === "youtu.be" ? parsed.pathname.split("/").filter(Boolean)[0] : parsed.pathname.match(/^\/(?:embed|v|shorts)\/([A-Za-z0-9_-]{11})(?:\/|$)/)?.[1];
14288
- const id = pathId ?? parsed.searchParams.get("v") ?? void 0;
14289
- return id && /^[A-Za-z0-9_-]{11}$/.test(id) ? id : void 0;
14290
- }
14291
- function nullableString(value) {
14292
- return value === null ? null : optionalString(value);
14293
- }
14294
- function normalizeSourceItems(value) {
14295
- if (!Array.isArray(value)) return void 0;
14296
- const items = value.flatMap((candidate) => {
14297
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
14298
- const item = candidate;
14299
- const id = requiredString(item.id);
14300
- const documentType = requiredString(item.documentType);
14301
- const name = requiredString(item.name);
14302
- if (!id || !documentType || !name) return [];
14303
- const externalUrl = httpsUrl(item.externalUrl);
14304
- const targetPlatform = nullableString(item.targetPlatform);
14305
- const path = nullableString(item.path);
14306
- return [
14307
- {
14308
- id,
14309
- documentType,
14310
- name,
14311
- ...externalUrl ? { externalUrl } : {},
14312
- ...targetPlatform !== void 0 ? { targetPlatform } : {},
14313
- ...path !== void 0 ? { path } : {}
14314
- }
14315
- ];
14316
- });
14317
- return items.length > 0 ? items : void 0;
14318
- }
14319
- function normalizeSources(value) {
14320
- if (!Array.isArray(value)) return [];
14321
- const seen = /* @__PURE__ */ new Set();
14322
- const sources = [];
14323
- for (const candidate of value) {
14324
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
14325
- const source = candidate;
14326
- const index = source.index;
14327
- const name = requiredString(source.name);
14328
- const path = requiredString(source.path);
14329
- const documentType = requiredString(source.documentType);
14330
- const validIndex = typeof index === "number" && Number.isFinite(index) && Number.isInteger(index) && index > 0 && !seen.has(index);
14331
- if (!validIndex || !name || !path || !documentType) continue;
14332
- seen.add(index);
14333
- const externalUrl = httpsUrl(source.externalUrl);
14334
- const targetPlatform = nullableString(source.targetPlatform);
14335
- const id = optionalString(source.id);
14336
- const sourceRepo = optionalString(source.sourceRepo);
14337
- const label = optionalString(source.label);
14338
- const items = normalizeSourceItems(source.items);
14339
- sources.push({
14340
- index,
14341
- name,
14342
- path,
14343
- documentType,
14344
- ...externalUrl ? { externalUrl } : {},
14345
- ...targetPlatform !== void 0 ? { targetPlatform } : {},
14346
- ...id ? { id } : {},
14347
- ...sourceRepo ? { sourceRepo } : {},
14348
- ...label ? { label } : {},
14349
- ...items ? { items } : {}
14350
- });
14351
- }
14352
- return sources;
14353
- }
14354
- function normalizeVideoMetadata(value) {
14355
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
14356
- const input = value;
14357
- const metadata = {};
14358
- for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
14359
- const url = httpsUrl(input[key]);
14360
- if (url) metadata[key] = url;
14361
- }
14362
- const id = youtubeId(input.youtubeUrl);
14363
- if (id) metadata.youtubeUrl = id;
14364
- return metadata;
14365
- }
14366
- function normalizeVideos(value) {
14367
- if (!Array.isArray(value)) return [];
14368
- return value.flatMap((candidate) => {
14369
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
14370
- const video = candidate;
14371
- const match = typeof video.ref === "string" ? CARD_REFERENCE.exec(video.ref) : null;
14372
- if (!match || match[1] !== "video") return [];
14373
- const id = match[2];
14374
- const title = optionalString(video.title) ?? id;
14375
- const url = httpsUrl(video.url) ?? null;
14376
- const sourceRepo = optionalString(video.sourceRepo);
14377
- const metadata = normalizeVideoMetadata(video.metadata);
14378
- if (url) {
14379
- const idFromUrl = youtubeId(url);
14380
- if (idFromUrl) {
14381
- metadata.youtubeUrl = idFromUrl;
14382
- delete metadata.videoUrl;
14383
- } else {
14384
- metadata.videoUrl = url;
14385
- delete metadata.youtubeUrl;
14386
- }
14387
- }
14388
- return [
14389
- {
14390
- type: "video",
14391
- id,
14392
- title,
14393
- url,
14394
- ...sourceRepo ? { sourceRepo } : {},
14395
- ...Object.keys(metadata).length > 0 ? { metadata } : {}
14396
- }
14397
- ];
14398
- });
14399
- }
14400
- function normalizeCards(value, sources) {
14401
- if (!Array.isArray(value)) return [];
14402
- return value.flatMap((candidate) => {
14403
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
14404
- const card = candidate;
14405
- const match = typeof card.ref === "string" ? CARD_REFERENCE.exec(card.ref) : null;
14406
- if (!match || match[1] === "video") return [];
14407
- const type = requiredString(card.entityType);
14408
- const id = requiredString(card.entityId);
14409
- if (!type || !id || type !== match[1] || id !== match[2]) return [];
14410
- const source = sources.find((item) => item.id === id && item.documentType === type);
14411
- const ref = {
14412
- type,
14413
- id,
14414
- title: source?.name ?? id,
14415
- url: source?.externalUrl ?? null,
14416
- ...source?.sourceRepo ? { sourceRepo: source.sourceRepo } : {},
14417
- ...source?.targetPlatform !== void 0 ? { targetPlatform: source.targetPlatform } : {},
14418
- ...source?.path ? { metadata: { path: source.path, [SOURCE_METADATA_MATCHED]: true } } : {}
14419
- };
14420
- return [ref];
14421
- });
14422
- }
14423
- function sourceMetadataEvent(payload) {
14424
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
14425
- const metadata = payload;
14426
- const sources = normalizeSources(metadata.sources);
14427
- const refs = [...normalizeVideos(metadata.videos), ...normalizeCards(metadata.cards, sources)];
14428
- const refsByIdentity = /* @__PURE__ */ new Map();
14429
- refs.forEach((ref) => {
14430
- const identity = `${ref.type}:${ref.id}`;
14431
- if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
14432
- });
14433
- const uniqueRefs = Array.from(refsByIdentity.values());
14434
- if (sources.length === 0 && uniqueRefs.length === 0) return null;
14435
- return { type: "sources", sources, ...uniqueRefs.length > 0 ? { refs: uniqueRefs } : {} };
14436
- }
14437
-
14438
14238
  // src/utils/faq-anchor.ts
14439
14239
  function faqSectionSlug(section) {
14440
14240
  return "faq-" + section.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -14495,7 +14295,7 @@ function useChatCardItem(type, id) {
14495
14295
  }
14496
14296
 
14497
14297
  // src/components/chat/mingo-info-card.tsx
14498
- import { Fragment as Fragment32, jsx as jsx91, jsxs as jsxs70 } from "react/jsx-runtime";
14298
+ import { Fragment as Fragment31, jsx as jsx91, jsxs as jsxs70 } from "react/jsx-runtime";
14499
14299
  function CardMedia({ imageSrc, imageAlt, icon }) {
14500
14300
  if (imageSrc) {
14501
14301
  return /* @__PURE__ */ jsxs70("span", { className: "relative block size-10 shrink-0", children: [
@@ -14558,7 +14358,7 @@ function MingoInfoCard({
14558
14358
  const hasMenu = !!menuGroups && menuGroups.length > 0;
14559
14359
  const isAnchor = !!anchorProps;
14560
14360
  const isInteractive = isAnchor || !!onClick;
14561
- const content = /* @__PURE__ */ jsxs70(Fragment32, { children: [
14361
+ const content = /* @__PURE__ */ jsxs70(Fragment31, { children: [
14562
14362
  hasMedia && /* @__PURE__ */ jsx91(CardMedia, { imageSrc, imageAlt, icon }),
14563
14363
  /* @__PURE__ */ jsxs70("span", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [
14564
14364
  /* @__PURE__ */ jsx91("span", { className: "truncate text-ods-text-primary text-h4", children: title }),
@@ -14915,7 +14715,7 @@ function DeletedDataCard({ title, entityLabel, recoveryNote, className }) {
14915
14715
  }
14916
14716
 
14917
14717
  // src/components/chat/entity-cards/dispatch.tsx
14918
- import { Fragment as Fragment33, jsx as jsx93, jsxs as jsxs72 } from "react/jsx-runtime";
14718
+ import { Fragment as Fragment32, jsx as jsx93, jsxs as jsxs72 } from "react/jsx-runtime";
14919
14719
  function githubKindIcon(kind) {
14920
14720
  switch (kind) {
14921
14721
  case "pull_request":
@@ -15014,14 +14814,6 @@ function hubspotStatusToVariant(status) {
15014
14814
  if (s === "OPEN") return "warning";
15015
14815
  return "grey";
15016
14816
  }
15017
- function validatedHttpsUrl(value) {
15018
- if (typeof value !== "string") return null;
15019
- try {
15020
- return new URL(value).protocol === "https:" ? value : null;
15021
- } catch {
15022
- return null;
15023
- }
15024
- }
15025
14817
  function decodeVideoMarkerId(id) {
15026
14818
  const mux = id.match(/^mux-([A-Za-z0-9_-]+)$/);
15027
14819
  if (mux) {
@@ -15034,8 +14826,8 @@ function decodeVideoMarkerId(id) {
15034
14826
  try {
15035
14827
  const b64 = mp4[1].replace(/-/g, "+").replace(/_/g, "/");
15036
14828
  const url = atob(b64);
15037
- const safeUrl = validatedHttpsUrl(url);
15038
- return safeUrl ? { videoUrl: safeUrl } : null;
14829
+ if (!/^https:\/\//.test(url)) return null;
14830
+ return { videoUrl: url };
15039
14831
  } catch {
15040
14832
  return null;
15041
14833
  }
@@ -15043,26 +14835,6 @@ function decodeVideoMarkerId(id) {
15043
14835
  if (/^[A-Za-z0-9_-]{11}$/.test(id)) return { youtubeUrl: id };
15044
14836
  return null;
15045
14837
  }
15046
- function validatedVideoMetadata(chatRef) {
15047
- const input = chatRef.metadata ?? {};
15048
- const metadata = {};
15049
- for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
15050
- const url = validatedHttpsUrl(input[key]);
15051
- if (url) metadata[key] = url;
15052
- }
15053
- const youtubeUrl = input.youtubeUrl;
15054
- if (typeof youtubeUrl === "string" && /^[A-Za-z0-9_-]{11}$/.test(youtubeUrl)) {
15055
- metadata.youtubeUrl = youtubeUrl;
15056
- }
15057
- const safeUrl = validatedHttpsUrl(chatRef.url);
15058
- if (safeUrl) {
15059
- const youtubeId2 = extractYouTubeId(safeUrl);
15060
- delete metadata.videoUrl;
15061
- delete metadata.youtubeUrl;
15062
- metadata[youtubeId2 ? "youtubeUrl" : "videoUrl"] = youtubeId2 ?? safeUrl;
15063
- }
15064
- return Object.keys(metadata).length > 0 ? metadata : null;
15065
- }
15066
14838
  function itemVideoMetadata(item) {
15067
14839
  const pick = (...vals) => {
15068
14840
  for (const v of vals) if (typeof v === "string" && v.length > 0) return v;
@@ -15546,7 +15318,7 @@ function RoadmapChatCard({
15546
15318
  }
15547
15319
  );
15548
15320
  }
15549
- function refHydratedEntry(docType, label, renderRef, renderFromSourceMetadata = false) {
15321
+ function refHydratedEntry(docType, label, renderRef) {
15550
15322
  return {
15551
15323
  label,
15552
15324
  bareInline: true,
@@ -15554,19 +15326,7 @@ function refHydratedEntry(docType, label, renderRef, renderFromSourceMetadata =
15554
15326
  noComposedHref: true,
15555
15327
  fallbackHref: (item) => item?.url ?? null,
15556
15328
  skeleton: () => /* @__PURE__ */ jsx93(MingoInfoCardSkeleton, {}),
15557
- render: (item, chatRef, opts) => renderRef(fetchedItemDisplayRef(item, chatRef), opts),
15558
- renderFromSourceMetadata
15559
- };
15560
- }
15561
- function sourceMetadataCardItem(chatRef) {
15562
- return {
15563
- type: chatRef.type,
15564
- id: chatRef.id,
15565
- title: chatRef.title,
15566
- url: chatRef.url,
15567
- targetPlatform: chatRef.targetPlatform,
15568
- sourceRepo: chatRef.sourceRepo,
15569
- metadata: chatRef.metadata
15329
+ render: (item, chatRef, opts) => renderRef(fetchedItemDisplayRef(item, chatRef), opts)
15570
15330
  };
15571
15331
  }
15572
15332
  var FINANCIAL_CARD_CONFIGS = {
@@ -15718,18 +15478,8 @@ var CHAT_CARD_REGISTRY = {
15718
15478
  // config's searchFilter is deliberately fail-closed there. Same
15719
15479
  // ChatRef item shape (`buildHubspotTicketSelfRef` SSOT), same preset.
15720
15480
  hubspot_ticket_self: refHydratedEntry("hubspot_ticket_self", "HubSpot ticket (self)", (displayRef, opts) => /* @__PURE__ */ jsx93(HubspotTicketChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss })),
15721
- data_room_doc: refHydratedEntry(
15722
- "data_room_doc",
15723
- "Data-room doc",
15724
- (displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss }),
15725
- true
15726
- ),
15727
- markdown: refHydratedEntry(
15728
- "markdown",
15729
- "Doc page (markdown)",
15730
- (displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss }),
15731
- true
15732
- ),
15481
+ data_room_doc: refHydratedEntry("data_room_doc", "Data-room doc", (displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss })),
15482
+ markdown: refHydratedEntry("markdown", "Doc page (markdown)", (displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss })),
15733
15483
  // Body-synthesized video ids (`shortVideoId` content hashes / YouTube
15734
15484
  // ids) have no backing table row to fetch — ref-only by nature.
15735
15485
  video: {
@@ -15967,7 +15717,7 @@ function ChatCardLoader({
15967
15717
  children
15968
15718
  }
15969
15719
  );
15970
- const finish = (node) => entry.bareInline ? /* @__PURE__ */ jsx93(Fragment33, { children: navWrap(node) }) : /* @__PURE__ */ jsx93(
15720
+ const finish = (node) => entry.bareInline ? /* @__PURE__ */ jsx93(Fragment32, { children: navWrap(node) }) : /* @__PURE__ */ jsx93(
15971
15721
  ChatCardWithDiscuss,
15972
15722
  {
15973
15723
  chatRef: finalChatRef,
@@ -15980,12 +15730,8 @@ function ChatCardLoader({
15980
15730
  if (!fetchEntry) {
15981
15731
  return finish(entry.render(void 0, finalChatRef, renderOpts));
15982
15732
  }
15983
- if (isLoading) return /* @__PURE__ */ jsx93(Fragment33, { children: fetchEntry.skeleton?.() ?? null });
15733
+ if (isLoading) return /* @__PURE__ */ jsx93(Fragment32, { children: fetchEntry.skeleton?.() ?? null });
15984
15734
  if (!item) {
15985
- const hasSourceMetadata = fetchEntry.renderFromSourceMetadata && isSourceMetadataCardRef(chatRef) && typeof finalChatRef.metadata?.path === "string";
15986
- if (hasSourceMetadata) {
15987
- return finish(fetchEntry.render(sourceMetadataCardItem(finalChatRef), finalChatRef, renderOpts));
15988
- }
15989
15735
  if (isError) {
15990
15736
  return /* @__PURE__ */ jsx93(CardLoadFailure, { label: entry.label, id: finalChatRef.id, detail: "Failed to load" });
15991
15737
  }
@@ -16026,15 +15772,13 @@ function renderChatInlineEntityCard(chatRef, options = {}) {
16026
15772
  }
16027
15773
  );
16028
15774
  if (chatRef.type === "video") {
16029
- const enrichedMetadata = validatedVideoMetadata(chatRef);
16030
15775
  const decoded = decodeVideoMarkerId(chatRef.id);
16031
- const playableMetadata = enrichedMetadata ?? decoded;
16032
- if (playableMetadata) {
15776
+ if (decoded) {
16033
15777
  const displayRef = {
16034
15778
  ...chatRef,
16035
15779
  title: chatRef.title && chatRef.title !== chatRef.id ? chatRef.title : "Video",
16036
- url: chatRef.url ?? (typeof playableMetadata.videoUrl === "string" ? playableMetadata.videoUrl : null) ?? (typeof playableMetadata.youtubeUrl === "string" ? `https://www.youtube.com/watch?v=${playableMetadata.youtubeUrl}` : null),
16037
- metadata: playableMetadata
15780
+ url: chatRef.url ?? decoded.videoUrl ?? (decoded.youtubeUrl ? `https://www.youtube.com/watch?v=${decoded.youtubeUrl}` : null),
15781
+ metadata: { ...chatRef.metadata ?? {}, ...decoded }
16038
15782
  };
16039
15783
  return /* @__PURE__ */ jsx93(BlockCard, { inline: /* @__PURE__ */ jsx93(ChatInlineVideoPill, { chatRef: displayRef }), children: /* @__PURE__ */ jsx93(ChatVideoEntityCard, { chatRef: displayRef }) });
16040
15784
  }
@@ -17033,17 +16777,14 @@ function buildNatsWsUrl(apiBaseUrl, options) {
17033
16777
  // src/components/chat/hooks/use-slash-commands.ts
17034
16778
  import { useQuery as useQuery2 } from "@tanstack/react-query";
17035
16779
  import { useEffect as useEffect26, useState as useState32 } from "react";
17036
- var COMMANDS_MAX_RESULTS = 10;
17037
16780
  async function fetchSlashCommands(prefix, signal, commandsUrl) {
17038
16781
  try {
17039
16782
  const url = new URL(commandsUrl, window.location.origin);
16783
+ if (prefix) url.searchParams.set("q", prefix);
17040
16784
  const res = await embedAuthedFetch(url.toString(), { signal, headers: {} });
17041
16785
  if (!res.ok) return [];
17042
16786
  const data = await res.json();
17043
- const commands = data.commands ?? [];
17044
- const normalizedPrefix = prefix.trim().toLowerCase();
17045
- if (!normalizedPrefix) return commands;
17046
- return commands.filter(({ id }) => id.startsWith(normalizedPrefix)).slice(0, COMMANDS_MAX_RESULTS);
16787
+ return data.commands ?? [];
17047
16788
  } catch (err) {
17048
16789
  if (err?.name === "AbortError") throw err;
17049
16790
  console.warn("[chat] slash-commands fetch failed, showing none:", err);
@@ -18136,23 +17877,6 @@ function approvalDisplaysInline(approvalType, displayApprovalTypes) {
18136
17877
  return !displayApprovalTypes || displayApprovalTypes.includes(approvalType);
18137
17878
  }
18138
17879
 
18139
- // src/components/chat/utils/chat-source-metadata.ts
18140
- function mergeChatSources(current, incoming) {
18141
- const sourcesByIndex = new Map((current ?? []).map((source) => [source.index, source]));
18142
- incoming.forEach((source) => {
18143
- if (!sourcesByIndex.has(source.index)) sourcesByIndex.set(source.index, source);
18144
- });
18145
- return Array.from(sourcesByIndex.values());
18146
- }
18147
- function mergeChatRefs(current, incoming) {
18148
- const refsByIdentity = new Map((current ?? []).map((ref) => [`${ref.type}:${ref.id}`, ref]));
18149
- incoming.forEach((ref) => {
18150
- const identity = `${ref.type}:${ref.id}`;
18151
- if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
18152
- });
18153
- return Array.from(refsByIdentity.values());
18154
- }
18155
-
18156
17880
  // src/components/chat/stream/message-mutations.ts
18157
17881
  function nextId(role) {
18158
17882
  return `${role}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
@@ -19012,8 +18736,6 @@ function createChatStreamReducer(options = {}) {
19012
18736
  const sourcesMap = /* @__PURE__ */ new Map();
19013
18737
  let sendCount = 0;
19014
18738
  let sseCurrentText = "";
19015
- let pendingSources;
19016
- let pendingRefs;
19017
18739
  let stateCache = null;
19018
18740
  function invalidate() {
19019
18741
  stateCache = null;
@@ -19075,17 +18797,6 @@ function createChatStreamReducer(options = {}) {
19075
18797
  }
19076
18798
  setMessagesInternal(stampTrailingAssistantSeq(updateTrailingAssistant(messages, segments), seq));
19077
18799
  }
19078
- function attachPendingSourceMetadata() {
19079
- if (!pendingSources && !pendingRefs) return;
19080
- const last = messages[messages.length - 1];
19081
- if (!last || last.role !== "assistant") return;
19082
- const next = {
19083
- ...last,
19084
- ...pendingSources ? { sources: pendingSources } : {},
19085
- ...pendingRefs ? { refs: pendingRefs } : {}
19086
- };
19087
- setMessagesInternal([...messages.slice(0, -1), next]);
19088
- }
19089
18800
  function applyStreamStartToState() {
19090
18801
  setPhaseInternal("streaming");
19091
18802
  const adoptTail = adoptTrailingAssistant;
@@ -19204,8 +18915,6 @@ function createChatStreamReducer(options = {}) {
19204
18915
  }
19205
18916
  switch (event.type) {
19206
18917
  case "turn-start": {
19207
- pendingSources = void 0;
19208
- pendingRefs = void 0;
19209
18918
  isInStream = true;
19210
18919
  hasEverStreamed = true;
19211
18920
  turnStartedAt = Date.now();
@@ -19220,14 +18929,6 @@ function createChatStreamReducer(options = {}) {
19220
18929
  emit("onStreamEnd");
19221
18930
  setPhaseInternal("idle");
19222
18931
  accumulator.resetSegments();
19223
- pendingSources = void 0;
19224
- pendingRefs = void 0;
19225
- break;
19226
- }
19227
- case "sources": {
19228
- pendingSources = mergeChatSources(pendingSources, event.sources);
19229
- if (event.refs) pendingRefs = mergeChatRefs(pendingRefs, event.refs);
19230
- attachPendingSourceMetadata();
19231
18932
  break;
19232
18933
  }
19233
18934
  case "metadata": {
@@ -19256,12 +18957,10 @@ function createChatStreamReducer(options = {}) {
19256
18957
  if (isInStream || !hasEverStreamed) {
19257
18958
  emitSegments(segments);
19258
18959
  applySegmentsToState(segments, withSeqMeta(void 0));
19259
- attachPendingSourceMetadata();
19260
18960
  } else {
19261
18961
  const delta = [{ type: kind, text: event.text }];
19262
18962
  emitSegments(delta, { append: true });
19263
18963
  applySegmentsToState(delta, withSeqMeta({ append: true }));
19264
- attachPendingSourceMetadata();
19265
18964
  }
19266
18965
  break;
19267
18966
  }
@@ -20949,11 +20648,6 @@ function decodeNatsChunk(chunk) {
20949
20648
  return { type: "thinking-delta", text: data.text, ...seq };
20950
20649
  }
20951
20650
  return null;
20952
- case MESSAGE_TYPE.GUIDE:
20953
- case MESSAGE_TYPE.SOURCES: {
20954
- const event = sourceMetadataEvent(data.payload);
20955
- return event ? { ...event, ...seq } : null;
20956
- }
20957
20651
  // An ask card is only an ask card with something to pick: a question and at
20958
20652
  // least one option. Anything less is dropped rather than rendered as an
20959
20653
  // empty card the user can't answer — the backend already falls back to a
@@ -21305,9 +20999,6 @@ function decodeHistoricalMessageData(data) {
21305
20999
  return { type: "thinking-delta", text: data.text };
21306
21000
  }
21307
21001
  return null;
21308
- case MESSAGE_TYPE.GUIDE:
21309
- case MESSAGE_TYPE.SOURCES:
21310
- return decodeNatsChunk({ type: data.type, payload: data.payload });
21311
21002
  // Same completeness gate as the live decoder (`decodeNatsChunk`): a
21312
21003
  // persisted row without a question or without options is not a card the
21313
21004
  // user can answer, so it replays as nothing rather than as empty chrome.
@@ -21663,8 +21354,6 @@ function processHistoricalMessages(messages, options = {}) {
21663
21354
  let currentAssistantTimestamp = null;
21664
21355
  let lastAssistantId = null;
21665
21356
  let currentAssistantStreamSeq;
21666
- let currentAssistantSources;
21667
- let currentAssistantRefs;
21668
21357
  const flushAssistantMessage = () => {
21669
21358
  const idToUse = lastAssistantId || currentAssistantId;
21670
21359
  if (idToUse && accumulator.hasContent()) {
@@ -21677,8 +21366,6 @@ function processHistoricalMessages(messages, options = {}) {
21677
21366
  authorType: assistantType,
21678
21367
  timestamp: currentAssistantTimestamp || /* @__PURE__ */ new Date(),
21679
21368
  avatar: assistantAvatar,
21680
- ...currentAssistantSources ? { sources: currentAssistantSources } : {},
21681
- ...currentAssistantRefs ? { refs: currentAssistantRefs } : {},
21682
21369
  ...currentAssistantStreamSeq !== void 0 ? { streamSeq: currentAssistantStreamSeq } : {}
21683
21370
  });
21684
21371
  accumulator.resetSegments();
@@ -21687,8 +21374,6 @@ function processHistoricalMessages(messages, options = {}) {
21687
21374
  currentAssistantTimestamp = null;
21688
21375
  lastAssistantId = null;
21689
21376
  currentAssistantStreamSeq = void 0;
21690
- currentAssistantSources = void 0;
21691
- currentAssistantRefs = void 0;
21692
21377
  };
21693
21378
  messages.forEach((msg, index) => {
21694
21379
  if (chatTypeFilter && msg.chatType !== chatTypeFilter) return;
@@ -21732,11 +21417,6 @@ function processHistoricalMessages(messages, options = {}) {
21732
21417
  messageDataArray.forEach((data) => {
21733
21418
  const event = decodeHistoricalMessageData(data);
21734
21419
  if (!event) return;
21735
- if (event.type === "sources") {
21736
- currentAssistantSources = mergeChatSources(currentAssistantSources, event.sources);
21737
- if (event.refs) currentAssistantRefs = mergeChatRefs(currentAssistantRefs, event.refs);
21738
- return;
21739
- }
21740
21420
  applyHistoryEvent(
21741
21421
  event,
21742
21422
  accumulator,
@@ -21829,17 +21509,13 @@ function mapProcessedToUnified(processed) {
21829
21509
  id: m.id,
21830
21510
  role: m.role,
21831
21511
  content: "",
21832
- segments: m.content,
21833
- ...m.sources ? { sources: m.sources } : {},
21834
- ...m.refs ? { refs: m.refs } : {}
21512
+ segments: m.content
21835
21513
  });
21836
21514
  } else {
21837
21515
  out.push({
21838
21516
  id: m.id,
21839
21517
  role: m.role,
21840
- content: m.content,
21841
- ...m.sources ? { sources: m.sources } : {},
21842
- ...m.refs ? { refs: m.refs } : {}
21518
+ content: m.content
21843
21519
  });
21844
21520
  }
21845
21521
  }
@@ -23123,7 +22799,7 @@ DrawerFooter.displayName = "DrawerFooter";
23123
22799
 
23124
22800
  // src/components/ui/hover-dropdown.tsx
23125
22801
  import { useState as useState43, useRef as useRef32, useCallback as useCallback24 } from "react";
23126
- import { Fragment as Fragment34, jsx as jsx96, jsxs as jsxs74 } from "react/jsx-runtime";
22802
+ import { Fragment as Fragment33, jsx as jsx96, jsxs as jsxs74 } from "react/jsx-runtime";
23127
22803
  function DefaultAnchor({ href, className, children }) {
23128
22804
  return /* @__PURE__ */ jsx96("a", { href, className, children });
23129
22805
  }
@@ -23137,7 +22813,6 @@ function HoverDropdown({
23137
22813
  }) {
23138
22814
  const [open, setOpen] = useState43(false);
23139
22815
  const timeoutRef = useRef32(void 0);
23140
- const clickPinnedRef = useRef32(false);
23141
22816
  const containerRef = useRef32(null);
23142
22817
  const panelRef = useRef32(null);
23143
22818
  useIsomorphicLayoutEffect(() => {
@@ -23172,17 +22847,14 @@ function HoverDropdown({
23172
22847
  setOpen(true);
23173
22848
  }, []);
23174
22849
  const hide = useCallback24(() => {
23175
- if (clickPinnedRef.current) return;
23176
22850
  timeoutRef.current = setTimeout(() => setOpen(false), hideDelay);
23177
22851
  }, [hideDelay]);
23178
22852
  const toggle = useCallback24((e) => {
23179
22853
  e.stopPropagation();
23180
22854
  clearTimeout(timeoutRef.current);
23181
- const pinned = !clickPinnedRef.current;
23182
- clickPinnedRef.current = pinned;
23183
- setOpen(pinned);
22855
+ setOpen((prev) => !prev);
23184
22856
  }, []);
23185
- if (items.length === 0) return /* @__PURE__ */ jsx96(Fragment34, { children });
22857
+ if (items.length === 0) return /* @__PURE__ */ jsx96(Fragment33, { children });
23186
22858
  const renderAnchorFn = renderAnchor ?? DefaultAnchor;
23187
22859
  return /* @__PURE__ */ jsxs74("div", { ref: containerRef, className: "relative inline-flex", onMouseEnter: show, onMouseLeave: hide, onClick: toggle, children: [
23188
22860
  children,
@@ -23192,7 +22864,7 @@ function HoverDropdown({
23192
22864
  className: `fixed z-[9999] max-h-[420px] min-w-[220px] max-w-[340px] overflow-y-auto rounded-lg border border-ods-border bg-ods-card p-1 shadow-xl ${className || ""}`,
23193
22865
  ref: panelRef,
23194
22866
  children: items.map((item, i) => {
23195
- const content = /* @__PURE__ */ jsxs74(Fragment34, { children: [
22867
+ const content = /* @__PURE__ */ jsxs74(Fragment33, { children: [
23196
22868
  item.icon && /* @__PURE__ */ jsx96("span", { className: "flex-shrink-0 [&_svg]:size-3.5", children: item.icon }),
23197
22869
  /* @__PURE__ */ jsx96("span", { className: "min-w-0 flex-1 truncate", children: item.label })
23198
22870
  ] });
@@ -23412,7 +23084,7 @@ function useChatDialogManager({
23412
23084
  }
23413
23085
 
23414
23086
  // src/components/chat/embeddable-chat.tsx
23415
- import { Fragment as Fragment35, jsx as jsx97, jsxs as jsxs75 } from "react/jsx-runtime";
23087
+ import { Fragment as Fragment34, jsx as jsx97, jsxs as jsxs75 } from "react/jsx-runtime";
23416
23088
  var DRAWER_DEFAULT_WIDTH_RATIO = 0.5;
23417
23089
  var DRAWER_WIDTH_KEY = "mingo-chat-width-v3";
23418
23090
  var DRAWER_DEFAULT_WIDTH_PX = 750;
@@ -23586,7 +23258,7 @@ function SourceChip({
23586
23258
  );
23587
23259
  }
23588
23260
  const displayName = src.name || formatRelativePath(src.path);
23589
- const chipBody = (label) => /* @__PURE__ */ jsxs75(Fragment35, { children: [
23261
+ const chipBody = (label) => /* @__PURE__ */ jsxs75(Fragment34, { children: [
23590
23262
  icon,
23591
23263
  /* @__PURE__ */ jsxs75("span", { className: "max-w-[160px] truncate", children: [
23592
23264
  "[",
@@ -23657,34 +23329,21 @@ function SourceChips({
23657
23329
  }) {
23658
23330
  const [expanded, setExpanded] = useState45(false);
23659
23331
  if (cited.length === 0) {
23660
- const visible = expanded ? uncited : uncited.slice(0, FALLBACK_TOP_RETRIEVED);
23661
- const hiddenCount2 = Math.max(0, uncited.length - FALLBACK_TOP_RETRIEVED);
23662
- if (visible.length === 0) return null;
23332
+ const fallback = uncited.slice(0, FALLBACK_TOP_RETRIEVED);
23333
+ if (fallback.length === 0) return null;
23663
23334
  return /* @__PURE__ */ jsxs75("div", { className: "mt-2 flex flex-col gap-1.5 border-t border-ods-border pt-2", children: [
23664
23335
  /* @__PURE__ */ jsx97("span", { className: "uppercase text-ods-text-muted text-h6", children: "Top retrieved sources" }),
23665
- /* @__PURE__ */ jsxs75("div", { className: `flex flex-wrap gap-1.5 ${expanded ? "max-h-[200px] overflow-y-auto overscroll-contain" : ""}`, children: [
23666
- visible.map((src) => /* @__PURE__ */ jsx97(
23667
- SourceChip,
23668
- {
23669
- src,
23670
- baseRoute,
23671
- chipBasePlatform,
23672
- onClose,
23673
- onDiscuss
23674
- },
23675
- src.index
23676
- )),
23677
- hiddenCount2 > 0 && /* @__PURE__ */ jsx97(
23678
- "button",
23679
- {
23680
- onClick: () => setExpanded(!expanded),
23681
- className: "inline-flex cursor-pointer items-center gap-1 rounded border border-ods-accent bg-ods-card px-2 py-0.5 text-ods-accent transition-colors text-h6 hover:bg-ods-accent/10",
23682
- "aria-expanded": expanded,
23683
- "aria-label": expanded ? "Show fewer sources" : `Show ${hiddenCount2} additional retrieved sources`,
23684
- children: expanded ? "Show less" : `+${hiddenCount2} more retrieved ${hiddenCount2 === 1 ? "source" : "sources"}`
23685
- }
23686
- )
23687
- ] })
23336
+ /* @__PURE__ */ jsx97("div", { className: "flex flex-wrap gap-1.5", children: fallback.map((src) => /* @__PURE__ */ jsx97(
23337
+ SourceChip,
23338
+ {
23339
+ src,
23340
+ baseRoute,
23341
+ chipBasePlatform,
23342
+ onClose,
23343
+ onDiscuss
23344
+ },
23345
+ src.index
23346
+ )) })
23688
23347
  ] });
23689
23348
  }
23690
23349
  const hiddenCount = uncited.length;
@@ -24111,10 +23770,6 @@ function EmbeddableChatInner({
24111
23770
  // explicitly — see `Message.hidden` and `chat-message-list`'s skip.
24112
23771
  ...m.hidden ? { hidden: true } : {},
24113
23772
  ...m.scrollAnchor ? { scrollAnchor: m.scrollAnchor } : {},
24114
- // Preserve same-turn rich metadata. Source chips and entity-card
24115
- // renderers consume it after this raw-to-Message projection.
24116
- ...m.sources && m.sources.length > 0 ? { sources: m.sources } : {},
24117
- ...m.refs && m.refs.length > 0 ? { refs: m.refs } : {},
24118
23773
  // Forward attached context items so the user bubble renders its chips.
24119
23774
  ...m.contextItems && m.contextItems.length > 0 ? { contextItems: m.contextItems } : {}
24120
23775
  };
@@ -24266,32 +23921,21 @@ function EmbeddableChatInner({
24266
23921
  });
24267
23922
  return out;
24268
23923
  }, [commandsById, enabledSet]);
24269
- const renderSourcesAfterMessage = useCallback26(
24270
- (message, index) => {
24271
- if (message.role !== "assistant" || !message.sources?.length) return null;
24272
- if (chatLoading && index === messages.length - 1) return null;
24273
- const content = typeof message.content === "string" ? message.content : message.content.filter((segment) => segment.type === "text").map((segment) => segment.text).join("\n");
24274
- const citationOrder = [...content.matchAll(/\[(\d+)\]/g)].map((m) => parseInt(m[1], 10));
24275
- const seenOrder = /* @__PURE__ */ new Map();
24276
- citationOrder.forEach((idx) => {
24277
- if (!seenOrder.has(idx)) seenOrder.set(idx, seenOrder.size);
24278
- });
24279
- const cited = message.sources.filter((s) => seenOrder.has(s.index)).sort((a, b) => (seenOrder.get(a.index) ?? 0) - (seenOrder.get(b.index) ?? 0));
24280
- const uncited = message.sources.filter((s) => !seenOrder.has(s.index));
24281
- return /* @__PURE__ */ jsx97("div", { className: "flex-shrink-0 pb-2", children: /* @__PURE__ */ jsx97(
24282
- SourceChips,
24283
- {
24284
- cited,
24285
- uncited,
24286
- baseRoute: resolvedBaseRoute,
24287
- chipBasePlatform,
24288
- onClose: handleNavigationClose,
24289
- onDiscuss: discussRef
24290
- }
24291
- ) });
24292
- },
24293
- [chatLoading, messages.length, resolvedBaseRoute, chipBasePlatform, handleNavigationClose, discussRef]
24294
- );
23924
+ const lastAssistantMsg = [...rawMessages].reverse().find((m) => m.role === "assistant");
23925
+ const lastSources = useMemo29(() => {
23926
+ if (chatLoading) return void 0;
23927
+ const sources = lastAssistantMsg?.sources;
23928
+ if (!sources || sources.length === 0) return void 0;
23929
+ const content = lastAssistantMsg?.content || "";
23930
+ const citationOrder = [...content.matchAll(/\[(\d+)\]/g)].map((m) => parseInt(m[1], 10));
23931
+ const seenOrder = /* @__PURE__ */ new Map();
23932
+ citationOrder.forEach((idx) => {
23933
+ if (!seenOrder.has(idx)) seenOrder.set(idx, seenOrder.size);
23934
+ });
23935
+ const cited = sources.filter((s) => seenOrder.has(s.index)).sort((a, b) => (seenOrder.get(a.index) ?? 0) - (seenOrder.get(b.index) ?? 0));
23936
+ const uncited = sources.filter((s) => !seenOrder.has(s.index));
23937
+ return { cited, uncited };
23938
+ }, [lastAssistantMsg, chatLoading]);
24295
23939
  const [portalHost, setPortalHost] = useState45(null);
24296
23940
  const [panelBoundary, setPanelBoundary] = useState45(null);
24297
23941
  const [panelWidth, setPanelWidth] = useState45(0);
@@ -24447,7 +24091,7 @@ function EmbeddableChatInner({
24447
24091
  // renders in the rail below); the chat block is untouched.
24448
24092
  // Back is a full-height leading cell, matching the other
24449
24093
  // header cells (not a small inline chevron).
24450
- /* @__PURE__ */ jsxs75(Fragment35, { children: [
24094
+ /* @__PURE__ */ jsxs75(Fragment34, { children: [
24451
24095
  /* @__PURE__ */ jsx97(ChatHeaderIconButton, { divider: "right", onClick: closeArchive, "aria-label": "Back to chats", children: /* @__PURE__ */ jsx97(Chevron02LeftIcon, { size: 24 }) }),
24452
24096
  /* @__PURE__ */ jsx97("div", { className: "flex min-w-0 flex-1 items-center px-[var(--spacing-system-mf)]", children: /* @__PURE__ */ jsx97("span", { className: "min-w-0 flex-1 truncate text-ods-text-primary text-h3", children: "Chat Archive" }) })
24453
24097
  ] })
@@ -24456,7 +24100,7 @@ function EmbeddableChatInner({
24456
24100
  // search + archive controls. When search is open the
24457
24101
  // inline field takes over the title area in place
24458
24102
  // (Figma 116:51217) and the magnifier toggle is hidden.
24459
- /* @__PURE__ */ jsxs75(Fragment35, { children: [
24103
+ /* @__PURE__ */ jsxs75(Fragment34, { children: [
24460
24104
  railSearchOpen && mingoCaps.onSearchChange ? /* @__PURE__ */ jsx97(
24461
24105
  ChatHeaderSearchField,
24462
24106
  {
@@ -24464,7 +24108,7 @@ function EmbeddableChatInner({
24464
24108
  onSearchChange: mingoCaps.onSearchChange,
24465
24109
  onCollapse: () => setRailSearchOpen(false)
24466
24110
  }
24467
- ) : /* @__PURE__ */ jsxs75(Fragment35, { children: [
24111
+ ) : /* @__PURE__ */ jsxs75(Fragment34, { children: [
24468
24112
  /* @__PURE__ */ jsx97("div", { className: "flex min-w-0 flex-1 items-center px-[var(--spacing-system-mf)]", children: /* @__PURE__ */ jsx97("span", { className: "min-w-0 flex-1 truncate text-ods-text-primary text-h3", children: "Current Chats" }) }),
24469
24113
  mingoCaps.onSearchChange && /* @__PURE__ */ jsx97(
24470
24114
  ChatHeaderIconButton,
@@ -24603,49 +24247,61 @@ function EmbeddableChatInner({
24603
24247
  onRetry: reloadDialogs
24604
24248
  }
24605
24249
  )
24606
- ) : /* @__PURE__ */ jsxs75(Fragment35, { children: [
24250
+ ) : /* @__PURE__ */ jsxs75(Fragment34, { children: [
24607
24251
  /* @__PURE__ */ jsx97("div", { ref: galleryPanelRef, className: "flex min-h-0 flex-1 flex-col p-[var(--spacing-system-m)]", children: /* @__PURE__ */ jsx97(
24608
24252
  "div",
24609
24253
  {
24610
24254
  className: "flex min-h-0 flex-1 flex-col duration-200 animate-in fade-in-0",
24611
- children: hasConversation ? /* @__PURE__ */ jsx97("div", { className: "flex min-h-0 flex-1 flex-col", children: messagesInitialLoading ? (
24612
- // Match the real list's `fullWidth` layout so swapping
24613
- // skeleton → bubbles doesn't shift the column. The panel
24614
- // wrapper above already pads (`p-[var(--spacing-system-m)]`),
24615
- // so the skeleton sits flush (no inner px/pb).
24616
- //
24617
- // In `previewMode` the chat lives in a fixed-height host box
24618
- // (e.g. the Mingo hero demo). The default bottom-anchored
24619
- // skeleton overflows a short panel and grows its OWN
24620
- // scrollbar — ugly. `fill` top-anchors + clips overflow so
24621
- // it reads as "the whole panel is loading" and never scrolls.
24622
- /* @__PURE__ */ jsx97(ChatMessageListSkeleton, { fullWidth: true, fill: previewMode, className: "flex-1" })
24623
- ) : /* @__PURE__ */ jsx97(
24624
- ChatMessageList,
24625
- {
24626
- messages,
24627
- isTyping: chatLoading,
24628
- pendingApprovals,
24629
- autoScroll: !previewMode,
24630
- pinBottom: previewMode,
24631
- overscrollContain: !previewMode,
24632
- assistantType: "mingo",
24633
- assistantIcon: mingoAssistantIcon,
24634
- renderEntityCard,
24635
- resolveContextIcon,
24636
- renderContextItem,
24637
- renderMention,
24638
- renderAfterMessage: renderSourcesAfterMessage,
24639
- onAskSelect: chatLoading || previewMode ? void 0 : handleAskSelect,
24640
- NavLinkAnchor: NavLinkAnchorViaRuntime,
24641
- className: previewMode ? "pointer-events-auto flex-1" : "flex-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
24642
- contentClassName: "max-w-none pb-0",
24643
- fullWidth: true,
24644
- hasNextPage: hasMoreMessages,
24645
- isFetchingNextPage: isMessagesLoading,
24646
- onLoadMore: loadMoreMessages
24647
- }
24648
- ) }) : activeMode === "mingo" ? (
24255
+ children: hasConversation ? /* @__PURE__ */ jsxs75("div", { className: "flex min-h-0 flex-1 flex-col", children: [
24256
+ messagesInitialLoading ? (
24257
+ // Match the real list's `fullWidth` layout so swapping
24258
+ // skeleton → bubbles doesn't shift the column. The panel
24259
+ // wrapper above already pads (`p-[var(--spacing-system-m)]`),
24260
+ // so the skeleton sits flush (no inner px/pb).
24261
+ //
24262
+ // In `previewMode` the chat lives in a fixed-height host box
24263
+ // (e.g. the Mingo hero demo). The default bottom-anchored
24264
+ // skeleton overflows a short panel and grows its OWN
24265
+ // scrollbar — ugly. `fill` top-anchors + clips overflow so
24266
+ // it reads as "the whole panel is loading" and never scrolls.
24267
+ /* @__PURE__ */ jsx97(ChatMessageListSkeleton, { fullWidth: true, fill: previewMode, className: "flex-1" })
24268
+ ) : /* @__PURE__ */ jsx97(
24269
+ ChatMessageList,
24270
+ {
24271
+ messages,
24272
+ isTyping: chatLoading,
24273
+ pendingApprovals,
24274
+ autoScroll: !previewMode,
24275
+ pinBottom: previewMode,
24276
+ overscrollContain: !previewMode,
24277
+ assistantType: "mingo",
24278
+ assistantIcon: mingoAssistantIcon,
24279
+ renderEntityCard,
24280
+ resolveContextIcon,
24281
+ renderContextItem,
24282
+ renderMention,
24283
+ onAskSelect: chatLoading || previewMode ? void 0 : handleAskSelect,
24284
+ NavLinkAnchor: NavLinkAnchorViaRuntime,
24285
+ className: previewMode ? "pointer-events-auto flex-1" : "flex-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
24286
+ contentClassName: "max-w-none pb-0",
24287
+ fullWidth: true,
24288
+ hasNextPage: hasMoreMessages,
24289
+ isFetchingNextPage: isMessagesLoading,
24290
+ onLoadMore: loadMoreMessages
24291
+ }
24292
+ ),
24293
+ lastSources && (lastSources.cited.length > 0 || lastSources.uncited.length > 0) && !chatLoading && /* @__PURE__ */ jsx97("div", { className: "flex-shrink-0 pb-2", children: /* @__PURE__ */ jsx97(
24294
+ SourceChips,
24295
+ {
24296
+ cited: lastSources.cited,
24297
+ uncited: lastSources.uncited,
24298
+ baseRoute: resolvedBaseRoute,
24299
+ chipBasePlatform,
24300
+ onClose: handleNavigationClose,
24301
+ onDiscuss: discussRef
24302
+ }
24303
+ ) })
24304
+ ] }) : activeMode === "mingo" ? (
24649
24305
  /* Figma node 7532:222444 — default (Mingo-mode) empty state:
24650
24306
  centred greeting + capability grid + Guide-chat promo +
24651
24307
  quick-action chips. Guide mode keeps the slash-command
@@ -24818,7 +24474,7 @@ function EmbeddableChatInner({
24818
24474
  ]
24819
24475
  }
24820
24476
  ) }) });
24821
- return /* @__PURE__ */ jsxs75(Fragment35, { children: [
24477
+ return /* @__PURE__ */ jsxs75(Fragment34, { children: [
24822
24478
  showInternalTrigger && !shellLess && /* @__PURE__ */ jsx97(
24823
24479
  "div",
24824
24480
  {
@@ -25207,4 +24863,4 @@ export {
25207
24863
  buildStreamFrames,
25208
24864
  EmbeddableChat
25209
24865
  };
25210
- //# sourceMappingURL=chunk-4MVGFYRE.js.map
24866
+ //# sourceMappingURL=chunk-D7YISHXC.js.map