@flamingo-stack/openframe-frontend-core 0.0.487 → 0.0.488-snapshot.20260728130942

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 (124) hide show
  1. package/dist/{chunk-4TFUB2CR.cjs → chunk-2IHN7NNB.cjs} +29 -29
  2. package/dist/{chunk-4TFUB2CR.cjs.map → chunk-2IHN7NNB.cjs.map} +1 -1
  3. package/dist/{chunk-UU4DW7JX.cjs → chunk-2RNJYJWO.cjs} +42 -42
  4. package/dist/{chunk-UU4DW7JX.cjs.map → chunk-2RNJYJWO.cjs.map} +1 -1
  5. package/dist/{chunk-W6GDTB4R.cjs → chunk-3OIB763B.cjs} +15 -15
  6. package/dist/{chunk-W6GDTB4R.cjs.map → chunk-3OIB763B.cjs.map} +1 -1
  7. package/dist/{chunk-NETEA5E4.js → chunk-5VSEMWWE.js} +6 -6
  8. package/dist/{chunk-K6MITU6M.cjs → chunk-5YMY4BAW.cjs} +77 -77
  9. package/dist/{chunk-K6MITU6M.cjs.map → chunk-5YMY4BAW.cjs.map} +1 -1
  10. package/dist/{chunk-KFQXO7QB.js → chunk-6GT557KN.js} +1 -1
  11. package/dist/chunk-6GT557KN.js.map +1 -0
  12. package/dist/{chunk-QBDHNUQX.js → chunk-B4YR342L.js} +6 -6
  13. package/dist/{chunk-SMD67GJP.js → chunk-BGWDDB7Y.js} +4 -4
  14. package/dist/{chunk-A7IPON2V.cjs → chunk-BIKOJ4FH.cjs} +5 -5
  15. package/dist/{chunk-A7IPON2V.cjs.map → chunk-BIKOJ4FH.cjs.map} +1 -1
  16. package/dist/{chunk-G4XU7BYU.js → chunk-EU6QNO4S.js} +2 -2
  17. package/dist/{chunk-ITEPRN6L.js → chunk-FKPXFTZT.js} +3 -3
  18. package/dist/{chunk-EO7MUGY4.cjs → chunk-H3YRJ3LZ.cjs} +14 -14
  19. package/dist/{chunk-EO7MUGY4.cjs.map → chunk-H3YRJ3LZ.cjs.map} +1 -1
  20. package/dist/{chunk-TJSJPOPL.cjs → chunk-IN4IO7BL.cjs} +395 -337
  21. package/dist/chunk-IN4IO7BL.cjs.map +1 -0
  22. package/dist/{chunk-HWK5CH5N.cjs → chunk-J7H32E3R.cjs} +18 -18
  23. package/dist/{chunk-HWK5CH5N.cjs.map → chunk-J7H32E3R.cjs.map} +1 -1
  24. package/dist/{chunk-BTMYUK4P.js → chunk-K7MNWYYI.js} +3 -3
  25. package/dist/{chunk-PECGZWQR.cjs → chunk-KP5KRRD6.cjs} +3 -3
  26. package/dist/{chunk-PECGZWQR.cjs.map → chunk-KP5KRRD6.cjs.map} +1 -1
  27. package/dist/{chunk-2B6773QM.cjs → chunk-LILQJ3UZ.cjs} +1 -1
  28. package/dist/chunk-LILQJ3UZ.cjs.map +1 -0
  29. package/dist/{chunk-RAYDQGJV.cjs → chunk-LLEDO4P7.cjs} +75 -75
  30. package/dist/{chunk-RAYDQGJV.cjs.map → chunk-LLEDO4P7.cjs.map} +1 -1
  31. package/dist/{chunk-AUGM74CO.js → chunk-N4MTNTSX.js} +7 -7
  32. package/dist/{chunk-KLYHZRAD.js → chunk-PB3BTZDU.js} +2 -2
  33. package/dist/{chunk-QW6SPNPT.cjs → chunk-RO7Q56ZK.cjs} +40 -40
  34. package/dist/{chunk-QW6SPNPT.cjs.map → chunk-RO7Q56ZK.cjs.map} +1 -1
  35. package/dist/{chunk-CWQACI4Z.js → chunk-RW2LPL72.js} +2 -2
  36. package/dist/{chunk-SDNMOAT4.js → chunk-TWGYBXYV.js} +4 -4
  37. package/dist/{chunk-WLRBZXFB.js → chunk-VL4LUO32.js} +3 -3
  38. package/dist/{chunk-QL7S3CH4.cjs → chunk-VLOE7MI2.cjs} +35 -35
  39. package/dist/{chunk-QL7S3CH4.cjs.map → chunk-VLOE7MI2.cjs.map} +1 -1
  40. package/dist/{chunk-UBK5HIMH.js → chunk-W6ZUOWSB.js} +7 -7
  41. package/dist/{chunk-GXOUXAXU.js → chunk-X2YF5TJS.js} +2 -2
  42. package/dist/{chunk-BC74IKAX.js → chunk-YMJZOANX.js} +277 -219
  43. package/dist/chunk-YMJZOANX.js.map +1 -0
  44. package/dist/{chunk-6SBAF5VG.cjs → chunk-Z7Y63IFU.cjs} +7 -7
  45. package/dist/{chunk-6SBAF5VG.cjs.map → chunk-Z7Y63IFU.cjs.map} +1 -1
  46. package/dist/{chunk-KTD2MGYF.cjs → chunk-ZIAS5NNL.cjs} +7 -7
  47. package/dist/{chunk-KTD2MGYF.cjs.map → chunk-ZIAS5NNL.cjs.map} +1 -1
  48. package/dist/components/case-studies/index.cjs +10 -10
  49. package/dist/components/case-studies/index.js +4 -4
  50. package/dist/components/chat/hooks/use-chat-history-hydration.d.ts +47 -0
  51. package/dist/components/chat/hooks/use-chat-history-hydration.d.ts.map +1 -0
  52. package/dist/components/chat/hooks/use-chat.d.ts +1 -0
  53. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  54. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +4 -0
  55. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  56. package/dist/components/chat/index.cjs +4 -4
  57. package/dist/components/chat/index.js +3 -3
  58. package/dist/components/chat/types/unified-chat-state.types.d.ts +5 -0
  59. package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
  60. package/dist/components/chat/utils/chat-conversation-storage.d.ts +34 -0
  61. package/dist/components/chat/utils/chat-conversation-storage.d.ts.map +1 -0
  62. package/dist/components/contact/index.cjs +5 -5
  63. package/dist/components/contact/index.js +4 -4
  64. package/dist/components/docs/index.cjs +7 -7
  65. package/dist/components/docs/index.js +6 -6
  66. package/dist/components/embeds/index.cjs +5 -5
  67. package/dist/components/embeds/index.js +4 -4
  68. package/dist/components/faq/index.cjs +6 -6
  69. package/dist/components/faq/index.js +5 -5
  70. package/dist/components/features/index.cjs +4 -4
  71. package/dist/components/features/index.js +3 -3
  72. package/dist/components/help-center-pages/index.cjs +23 -23
  73. package/dist/components/help-center-pages/index.js +14 -14
  74. package/dist/components/index.cjs +140 -140
  75. package/dist/components/index.js +12 -12
  76. package/dist/components/navigation/index.cjs +4 -4
  77. package/dist/components/navigation/index.js +3 -3
  78. package/dist/components/onboarding-guides/index.cjs +8 -8
  79. package/dist/components/onboarding-guides/index.js +7 -7
  80. package/dist/components/related-content/index.cjs +6 -6
  81. package/dist/components/related-content/index.js +5 -5
  82. package/dist/components/tickets/index.cjs +7 -7
  83. package/dist/components/tickets/index.js +6 -6
  84. package/dist/components/ui/index.cjs +4 -4
  85. package/dist/components/ui/index.js +3 -3
  86. package/dist/components/ui/query-report-table/query-report-table.d.ts.map +1 -1
  87. package/dist/components/ui/query-report-table/types.d.ts +2 -2
  88. package/dist/components/ui/query-report-table/types.d.ts.map +1 -1
  89. package/dist/contexts/chat-runtime-context.d.ts +8 -0
  90. package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
  91. package/dist/contexts/index.cjs +2 -2
  92. package/dist/contexts/index.js +1 -1
  93. package/dist/hooks/index.cjs +3 -3
  94. package/dist/hooks/index.js +2 -2
  95. package/dist/index.cjs +4 -4
  96. package/dist/index.js +3 -3
  97. package/package.json +1 -1
  98. package/src/components/chat/hooks/use-chat-history-hydration.ts +142 -0
  99. package/src/components/chat/hooks/use-chat.ts +12 -0
  100. package/src/components/chat/hooks/use-sse-chat-adapter.ts +109 -162
  101. package/src/components/chat/types/unified-chat-state.types.ts +6 -0
  102. package/src/components/chat/utils/chat-conversation-storage.ts +83 -0
  103. package/src/components/features/notifications/notification-drawer.tsx +1 -1
  104. package/src/components/ui/query-report-table/query-report-table-skeleton.tsx +1 -1
  105. package/src/components/ui/query-report-table/query-report-table.tsx +7 -8
  106. package/src/components/ui/query-report-table/types.ts +2 -2
  107. package/src/contexts/chat-runtime-context.tsx +8 -0
  108. package/dist/chunk-2B6773QM.cjs.map +0 -1
  109. package/dist/chunk-BC74IKAX.js.map +0 -1
  110. package/dist/chunk-KFQXO7QB.js.map +0 -1
  111. package/dist/chunk-TJSJPOPL.cjs.map +0 -1
  112. /package/dist/{chunk-NETEA5E4.js.map → chunk-5VSEMWWE.js.map} +0 -0
  113. /package/dist/{chunk-QBDHNUQX.js.map → chunk-B4YR342L.js.map} +0 -0
  114. /package/dist/{chunk-SMD67GJP.js.map → chunk-BGWDDB7Y.js.map} +0 -0
  115. /package/dist/{chunk-G4XU7BYU.js.map → chunk-EU6QNO4S.js.map} +0 -0
  116. /package/dist/{chunk-ITEPRN6L.js.map → chunk-FKPXFTZT.js.map} +0 -0
  117. /package/dist/{chunk-BTMYUK4P.js.map → chunk-K7MNWYYI.js.map} +0 -0
  118. /package/dist/{chunk-AUGM74CO.js.map → chunk-N4MTNTSX.js.map} +0 -0
  119. /package/dist/{chunk-KLYHZRAD.js.map → chunk-PB3BTZDU.js.map} +0 -0
  120. /package/dist/{chunk-CWQACI4Z.js.map → chunk-RW2LPL72.js.map} +0 -0
  121. /package/dist/{chunk-SDNMOAT4.js.map → chunk-TWGYBXYV.js.map} +0 -0
  122. /package/dist/{chunk-WLRBZXFB.js.map → chunk-VL4LUO32.js.map} +0 -0
  123. /package/dist/{chunk-UBK5HIMH.js.map → chunk-W6ZUOWSB.js.map} +0 -0
  124. /package/dist/{chunk-GXOUXAXU.js.map → chunk-X2YF5TJS.js.map} +0 -0
@@ -34,7 +34,7 @@ import {
34
34
  useResetOnPageHidden,
35
35
  useSuppressCloneFocus,
36
36
  useToast
37
- } from "./chunk-KLYHZRAD.js";
37
+ } from "./chunk-PB3BTZDU.js";
38
38
  import {
39
39
  AlertCircleIcon,
40
40
  AnthropicLogoGreyIcon,
@@ -160,7 +160,7 @@ import {
160
160
  import {
161
161
  useChatRuntime,
162
162
  useRequiredChatRuntime
163
- } from "./chunk-KFQXO7QB.js";
163
+ } from "./chunk-6GT557KN.js";
164
164
  import {
165
165
  dynamic
166
166
  } from "./chunk-EL5YVPD5.js";
@@ -35334,7 +35334,7 @@ function NotificationDrawer({
35334
35334
  type: "button",
35335
35335
  disabled: unreadCount === 0,
35336
35336
  onClick: markAllRead,
35337
- className: "self-center text-h6 text-ods-text-secondary underline transition-colors hover:text-ods-text-primary disabled:opacity-40",
35337
+ className: "self-center text-h6 text-ods-text-secondary underline transition-colors hover:text-ods-text-primary disabled:opacity-40 max-md:focus:outline-none max-md:focus-visible:outline-none",
35338
35338
  children: "Mark All Complete"
35339
35339
  }
35340
35340
  ),
@@ -41506,7 +41506,7 @@ function QueryReportTableSkeleton({
41506
41506
  className
41507
41507
  }) {
41508
41508
  const isCompact = variant === "compact";
41509
- return /* @__PURE__ */ jsxs260("div", { className: cn("flex flex-col", isCompact ? "gap-0" : "gap-2", className), children: [
41509
+ return /* @__PURE__ */ jsxs260("div", { className: cn("flex flex-col", isCompact ? "gap-0" : "gap-[var(--spacing-system-xs)]", className), children: [
41510
41510
  /* @__PURE__ */ jsx327("div", { className: cn(
41511
41511
  "flex items-center gap-4 px-4",
41512
41512
  isCompact ? "py-2 border-b border-ods-border" : ""
@@ -41633,18 +41633,17 @@ function QueryReportTable({
41633
41633
  onThumbPointerMove,
41634
41634
  onThumbPointerUp
41635
41635
  } = useHorizontalScrollbar();
41636
- return /* @__PURE__ */ jsxs261("div", { className: cn("flex flex-col w-full", isCompact ? "gap-0" : "gap-6", className), children: [
41637
- !isCompact && (title || headerActions || showExport && data.length > 0) && /* @__PURE__ */ jsxs261("div", { className: "flex items-end justify-between pt-6", children: [
41636
+ return /* @__PURE__ */ jsxs261("div", { className: cn("flex flex-col w-full", isCompact ? "gap-0" : "gap-[var(--spacing-system-l)]", className), children: [
41637
+ !isCompact && (title || headerActions || showExport && data.length > 0) && /* @__PURE__ */ jsxs261("div", { className: "flex items-end justify-between pt-[var(--spacing-system-l)]", children: [
41638
41638
  /* @__PURE__ */ jsx328("h2", { className: "text-h2 text-ods-text-primary", children: title }),
41639
- /* @__PURE__ */ jsxs261("div", { className: "flex items-center gap-3", children: [
41639
+ /* @__PURE__ */ jsxs261("div", { className: "flex items-center gap-[var(--spacing-system-s)]", children: [
41640
41640
  headerActions,
41641
41641
  showExport && data.length > 0 && /* @__PURE__ */ jsx328(
41642
41642
  Button,
41643
41643
  {
41644
- className: "bg-ods-card",
41644
+ className: "bg-ods-card max-md:hidden",
41645
41645
  variant: "outline",
41646
- size: "small-legacy",
41647
- leftIcon: /* @__PURE__ */ jsx328(Download02Icon, { size: 18 }),
41646
+ leftIcon: /* @__PURE__ */ jsx328(Download02Icon, { size: 18, className: "text-ods-text-secondary" }),
41648
41647
  onClick: handleExport,
41649
41648
  children: "Export CSV"
41650
41649
  }
@@ -41661,7 +41660,7 @@ function QueryReportTable({
41661
41660
  }
41662
41661
  ),
41663
41662
  !loading && data.length === 0 && /* @__PURE__ */ jsx328(TableEmptyState, { message: emptyMessage }),
41664
- !loading && data.length > 0 && /* @__PURE__ */ jsxs261("div", { className: "flex flex-col gap-1", children: [
41663
+ !loading && data.length > 0 && /* @__PURE__ */ jsxs261("div", { className: "flex flex-col", children: [
41665
41664
  !isCompact && thumbRatio > 0 && /* @__PURE__ */ jsx328(
41666
41665
  "div",
41667
41666
  {
@@ -41702,7 +41701,7 @@ function QueryReportTable({
41702
41701
  variant
41703
41702
  }
41704
41703
  ),
41705
- /* @__PURE__ */ jsx328("div", { className: cn("flex flex-col", isCompact ? "gap-0" : "gap-2 p-4"), children: data.map((row, index) => /* @__PURE__ */ jsx328(
41704
+ /* @__PURE__ */ jsx328("div", { className: cn("flex flex-col", isCompact ? "gap-0" : "gap-[var(--spacing-system-xs)]"), children: data.map((row, index) => /* @__PURE__ */ jsx328(
41706
41705
  QueryReportTableRow,
41707
41706
  {
41708
41707
  row,
@@ -51610,6 +51609,9 @@ function useChat({
51610
51609
  setIsTyping(false);
51611
51610
  reset();
51612
51611
  }, [reset]);
51612
+ const hydrateMessages = useCallback53((history) => {
51613
+ setMessages((prev) => prev.length === 0 ? history : [...history, ...prev]);
51614
+ }, []);
51613
51615
  const stopMessage = useCallback53(() => {
51614
51616
  abort();
51615
51617
  setIsTyping(false);
@@ -51623,12 +51625,125 @@ function useChat({
51623
51625
  stopMessage,
51624
51626
  handleQuickAction,
51625
51627
  clearMessages,
51628
+ hydrateMessages,
51626
51629
  hasMessages: messages.length > 0
51627
51630
  };
51628
51631
  }
51629
51632
 
51630
51633
  // src/components/chat/hooks/use-sse-chat-adapter.ts
51631
- import { useState as useState122, useEffect as useEffect91, useCallback as useCallback54, useMemo as useMemo48, useRef as useRef77 } from "react";
51634
+ import { useState as useState123, useEffect as useEffect92, useCallback as useCallback54, useMemo as useMemo48, useRef as useRef78 } from "react";
51635
+
51636
+ // src/components/chat/utils/chat-conversation-storage.ts
51637
+ var STORAGE_KEY2 = "conversation";
51638
+ var namespaceFor = (source) => {
51639
+ const base = `mingo-chat-${source}`;
51640
+ const auth = getEmbedProxyAuth();
51641
+ return auth?.email ? `${base}-u-${encodeURIComponent(auth.email.toLowerCase())}` : base;
51642
+ };
51643
+ function createChatConversationStorage(source) {
51644
+ return createLocalStorageAdapter({
51645
+ key: STORAGE_KEY2,
51646
+ namespace: () => namespaceFor(source),
51647
+ validate: (parsed) => !!parsed && typeof parsed.conversationId === "string" && parsed.conversationId.length > 0,
51648
+ logTag: "[chat-conversation-storage]"
51649
+ });
51650
+ }
51651
+ function pruneStaleChatConversationStorage(source) {
51652
+ if (typeof window === "undefined") return;
51653
+ try {
51654
+ const base = `mingo-chat-${source}`;
51655
+ const currentKey = `${namespaceFor(source)}.${STORAGE_KEY2}`;
51656
+ const ownedKey = (k) => k === base || // retired raw key (pre-adapter shape)
51657
+ k === `${base}.${STORAGE_KEY2}` || // current no-identity shape
51658
+ k.startsWith(`${base}-u-`) || // per-identity shapes (current + retired)
51659
+ k.startsWith(`${base}-v`);
51660
+ const toRemove = [];
51661
+ for (let i = 0; i < window.localStorage.length; i++) {
51662
+ const k = window.localStorage.key(i);
51663
+ if (!k) continue;
51664
+ if (ownedKey(k) && k !== currentKey) toRemove.push(k);
51665
+ }
51666
+ for (const k of toRemove) {
51667
+ window.localStorage.removeItem(k);
51668
+ }
51669
+ } catch {
51670
+ }
51671
+ }
51672
+
51673
+ // src/components/chat/hooks/use-chat-history-hydration.ts
51674
+ import { useEffect as useEffect91, useRef as useRef77, useState as useState122 } from "react";
51675
+ function useChatHistoryHydration({
51676
+ active,
51677
+ source,
51678
+ historyUrl,
51679
+ conversationIdRef,
51680
+ refsMapRef,
51681
+ sendCountRef,
51682
+ hydrateMessages,
51683
+ bumpMetaTick
51684
+ }) {
51685
+ const [isHydratingHistory, setIsHydratingHistory] = useState122(false);
51686
+ const hydratedKeyRef = useRef77(null);
51687
+ useEffect91(() => {
51688
+ if (!active) return;
51689
+ const conversationId = conversationIdRef.current;
51690
+ if (!conversationId) return;
51691
+ const key = `${source}:${conversationId}`;
51692
+ if (hydratedKeyRef.current === key) return;
51693
+ hydratedKeyRef.current = key;
51694
+ let cancelled = false;
51695
+ setIsHydratingHistory(true);
51696
+ (async () => {
51697
+ try {
51698
+ const res = await embedAuthedFetch(
51699
+ `${historyUrl}?conversationId=${encodeURIComponent(conversationId)}`,
51700
+ { method: "GET" }
51701
+ );
51702
+ if (!res.ok) return;
51703
+ const payload = await res.json().catch(() => null);
51704
+ const body = payload?.data ?? payload;
51705
+ const rows = Array.isArray(body?.messages) ? body.messages : [];
51706
+ if (cancelled || rows.length === 0) return;
51707
+ const hydrated = [];
51708
+ let userTurns = 0;
51709
+ for (const row of rows) {
51710
+ const role = row.role === "assistant" ? "assistant" : row.role === "user" ? "user" : null;
51711
+ if (!role) continue;
51712
+ const content = typeof row.content === "string" ? row.content : "";
51713
+ const hidden = role === "user" && (content === "" || content.startsWith(AUTO_CONTINUATION_DIRECTIVE_PREFIX));
51714
+ if (role === "user") {
51715
+ userTurns += 1;
51716
+ } else if (row.chat_refs && typeof row.chat_refs === "object") {
51717
+ refsMapRef.current.set(
51718
+ Math.max(0, userTurns - 1),
51719
+ row.chat_refs
51720
+ );
51721
+ }
51722
+ hydrated.push({
51723
+ id: `hydrated-${String(row.seq ?? hydrated.length)}`,
51724
+ role,
51725
+ content,
51726
+ ...typeof row.created_at === "string" ? { timestamp: new Date(row.created_at) } : {},
51727
+ ...hidden ? { hidden: true } : {}
51728
+ });
51729
+ }
51730
+ if (cancelled || hydrated.length === 0) return;
51731
+ sendCountRef.current = userTurns;
51732
+ hydrateMessages(hydrated);
51733
+ bumpMetaTick();
51734
+ } catch {
51735
+ } finally {
51736
+ if (!cancelled) setIsHydratingHistory(false);
51737
+ }
51738
+ })();
51739
+ return () => {
51740
+ cancelled = true;
51741
+ };
51742
+ }, [active, source, historyUrl, hydrateMessages, bumpMetaTick]);
51743
+ return { isHydratingHistory, hydratedKeyRef };
51744
+ }
51745
+
51746
+ // src/components/chat/hooks/use-sse-chat-adapter.ts
51632
51747
  function createEmptyTurnMeta() {
51633
51748
  return {
51634
51749
  provider: null,
@@ -51640,34 +51755,28 @@ function createEmptyTurnMeta() {
51640
51755
  breakdown: null,
51641
51756
  scrollAnchor: null,
51642
51757
  routedComplexity: null,
51643
- routedThinkingBudget: null
51758
+ routedThinkingBudget: null,
51759
+ conversationId: null
51644
51760
  };
51645
51761
  }
51646
51762
  function escapeThinkingTags(text) {
51647
51763
  return text.replace(/</g, "&lt;");
51648
51764
  }
51649
- function createDocStreamFn(source, endpoints, messagesRef, sourcesMapRef, refsMapRef, metaMapRef, setStreamingPhase, bumpMetaTick, sendCountRef) {
51765
+ function createDocStreamFn(source, endpoints, sourcesMapRef, refsMapRef, metaMapRef, setStreamingPhase, bumpMetaTick, sendCountRef, conversationIdRef, conversationStorage) {
51650
51766
  return async function* (message2, signal, extra) {
51651
- const currentMessages = messagesRef.current || [];
51652
- const apiMessages = [
51653
- ...currentMessages.filter((m) => (m.role === "user" || m.role === "assistant") && !m.hidden).map((m) => ({
51654
- role: m.role,
51655
- content: typeof m.content === "string" ? m.content : flattenAssistantContent(m.content)
51656
- })),
51657
- { role: "user", content: message2 }
51658
- ];
51659
51767
  const targetPath = extra?.approvalAction ? endpoints.approvalToolUrl : endpoints.chatStreamUrl;
51768
+ const conversationId = conversationIdRef.current;
51660
51769
  const requestBody = extra?.approvalAction ? {
51661
51770
  proposal_id: extra.approvalAction.proposalId,
51662
51771
  action: extra.approvalAction.action,
51663
- messages: currentMessages.filter((m) => (m.role === "user" || m.role === "assistant") && !m.hidden).map((m) => ({
51664
- role: m.role,
51665
- content: typeof m.content === "string" ? m.content : flattenAssistantContent(m.content)
51666
- }))
51772
+ // Always present here — an approval can only happen inside an
51773
+ // established conversation (the proposal turn captured the id).
51774
+ conversationId
51667
51775
  } : {
51668
- messages: apiMessages,
51776
+ messages: [{ role: "user", content: message2 }],
51669
51777
  ...extra?.commandOverride ? { commandOverride: extra.commandOverride } : {},
51670
- ...extra?.pendingAttachments && extra.pendingAttachments.length > 0 ? { pendingAttachments: extra.pendingAttachments } : {}
51778
+ ...extra?.pendingAttachments && extra.pendingAttachments.length > 0 ? { pendingAttachments: extra.pendingAttachments } : {},
51779
+ ...conversationId ? { conversationId } : {}
51671
51780
  };
51672
51781
  const response = await embedAuthedFetch(targetPath, {
51673
51782
  method: "POST",
@@ -51830,6 +51939,14 @@ function createDocStreamFn(source, endpoints, messagesRef, sourcesMapRef, refsMa
51830
51939
  });
51831
51940
  bumpMetaTick();
51832
51941
  }
51942
+ if (typeof meta.conversationId === "string" && meta.conversationId) {
51943
+ if (conversationIdRef.current !== meta.conversationId) {
51944
+ conversationIdRef.current = meta.conversationId;
51945
+ conversationStorage.save({ conversationId: meta.conversationId });
51946
+ }
51947
+ mergeTurnMeta(metaMapRef, sendIdx, { conversationId: meta.conversationId });
51948
+ bumpMetaTick();
51949
+ }
51833
51950
  const parsedAnchor = parseScrollAnchor(meta.scrollAnchor);
51834
51951
  if (parsedAnchor !== null) {
51835
51952
  mergeTurnMeta(metaMapRef, sendIdx, { scrollAnchor: parsedAnchor });
@@ -51888,83 +52005,26 @@ function mergeTurnMeta(ref, sendIdx, partial) {
51888
52005
  );
51889
52006
  ref.current.set(sendIdx, { ...prev, ...filtered });
51890
52007
  }
51891
- var CHAT_STORAGE_VERSION = 1;
51892
52008
  var DEFAULT_CHAT_SOURCE = "embed";
51893
- var chatStorageKey = (source) => {
51894
- const base = `mingo-chat-${source}-v${CHAT_STORAGE_VERSION}`;
51895
- const auth = getEmbedProxyAuth();
51896
- if (auth?.email) {
51897
- return `${base}-u-${encodeURIComponent(auth.email.toLowerCase())}`;
51898
- }
51899
- return base;
51900
- };
51901
- function pruneStaleChatStorage(source) {
51902
- if (typeof window === "undefined") return;
51903
- try {
51904
- const currentKey = chatStorageKey(source);
51905
- const prefix = `mingo-chat-${source}-v${CHAT_STORAGE_VERSION}-u-`;
51906
- const legacy = `mingo-chat-${source}-v${CHAT_STORAGE_VERSION}`;
51907
- const toRemove = [];
51908
- for (let i = 0; i < window.localStorage.length; i++) {
51909
- const k = window.localStorage.key(i);
51910
- if (!k) continue;
51911
- if (!k.startsWith(prefix)) continue;
51912
- if (k === currentKey) continue;
51913
- if (k === legacy) continue;
51914
- toRemove.push(k);
51915
- }
51916
- for (const k of toRemove) {
51917
- window.localStorage.removeItem(k);
51918
- }
51919
- } catch {
51920
- }
51921
- }
51922
- function loadPersistedChat(source) {
51923
- if (typeof window === "undefined") return null;
51924
- try {
51925
- const raw = window.localStorage.getItem(chatStorageKey(source));
51926
- if (!raw) return null;
51927
- const parsed = JSON.parse(raw);
51928
- if (!parsed || !Array.isArray(parsed.messages)) return null;
51929
- for (const m of parsed.messages) {
51930
- if (typeof m.timestamp === "string") m.timestamp = new Date(m.timestamp);
51931
- if (m.role === "user" && !m.hidden && typeof m.content === "string" && m.content.startsWith(AUTO_CONTINUATION_DIRECTIVE_PREFIX)) {
51932
- m.hidden = true;
51933
- }
51934
- }
51935
- return parsed;
51936
- } catch {
51937
- return null;
51938
- }
51939
- }
51940
- function savePersistedChat(source, state) {
51941
- if (typeof window === "undefined") return;
51942
- try {
51943
- window.localStorage.setItem(chatStorageKey(source), JSON.stringify(state));
51944
- } catch {
51945
- }
51946
- }
51947
52009
  function useSseChatAdapter(options, runtimeOptions = {}) {
51948
52010
  const { active = true } = runtimeOptions;
51949
52011
  const runtime = useRequiredChatRuntime();
51950
52012
  const source = runtime.source || DEFAULT_CHAT_SOURCE;
51951
52013
  const tableIdForDocumentType = options?.tableIdForDocumentType ?? defaultTableIdForDocumentType;
51952
- const persistedRef = useRef77(null);
51953
- if (persistedRef.current === null) {
51954
- pruneStaleChatStorage(source);
51955
- persistedRef.current = loadPersistedChat(source) || { messages: [], sources: [], sendCount: 0 };
51956
- }
51957
- const sourcesMapRef = useRef77(
51958
- new Map(persistedRef.current.sources)
51959
- );
51960
- const refsMapRef = useRef77(
51961
- new Map(persistedRef.current.refs ?? [])
51962
- );
51963
- const metaMapRef = useRef77(/* @__PURE__ */ new Map());
51964
- const messagesRef = useRef77(persistedRef.current.messages);
51965
- const sendCountRef = useRef77(persistedRef.current.sendCount);
51966
- const [streamingPhase, setStreamingPhase] = useState122("idle");
51967
- const [metaTick, setMetaTick] = useState122(0);
52014
+ const conversationStorage = useMemo48(() => createChatConversationStorage(source), [source]);
52015
+ const conversationIdRef = useRef78(null);
52016
+ const restoredConversationRef = useRef78(false);
52017
+ if (!restoredConversationRef.current) {
52018
+ restoredConversationRef.current = true;
52019
+ pruneStaleChatConversationStorage(source);
52020
+ conversationIdRef.current = conversationStorage.load()?.conversationId ?? null;
52021
+ }
52022
+ const sourcesMapRef = useRef78(/* @__PURE__ */ new Map());
52023
+ const refsMapRef = useRef78(/* @__PURE__ */ new Map());
52024
+ const metaMapRef = useRef78(/* @__PURE__ */ new Map());
52025
+ const sendCountRef = useRef78(0);
52026
+ const [streamingPhase, setStreamingPhase] = useState123("idle");
52027
+ const [metaTick, setMetaTick] = useState123(0);
51968
52028
  const bumpMetaTick = useCallback54(() => setMetaTick((t) => t + 1), []);
51969
52029
  const streamFn = useMemo48(
51970
52030
  () => createDocStreamFn(
@@ -51973,19 +52033,21 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
51973
52033
  chatStreamUrl: runtime.endpoints.chatStreamUrl,
51974
52034
  approvalToolUrl: runtime.endpoints.approvalToolUrl
51975
52035
  },
51976
- messagesRef,
51977
52036
  sourcesMapRef,
51978
52037
  refsMapRef,
51979
52038
  metaMapRef,
51980
52039
  setStreamingPhase,
51981
52040
  bumpMetaTick,
51982
- sendCountRef
52041
+ sendCountRef,
52042
+ conversationIdRef,
52043
+ conversationStorage
51983
52044
  ),
51984
52045
  [
51985
52046
  source,
51986
52047
  runtime.endpoints.chatStreamUrl,
51987
52048
  runtime.endpoints.approvalToolUrl,
51988
- bumpMetaTick
52049
+ bumpMetaTick,
52050
+ conversationStorage
51989
52051
  ]
51990
52052
  );
51991
52053
  const commandsUrl = runtime.endpoints.commandsUrl;
@@ -52012,17 +52074,6 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
52012
52074
  }
52013
52075
  return map;
52014
52076
  }, [slashCommands]);
52015
- const persist = useCallback54(
52016
- (nextMessages) => {
52017
- savePersistedChat(source, {
52018
- messages: nextMessages,
52019
- sources: Array.from(sourcesMapRef.current.entries()),
52020
- refs: Array.from(refsMapRef.current.entries()),
52021
- sendCount: sendCountRef.current
52022
- });
52023
- },
52024
- [source]
52025
- );
52026
52077
  const {
52027
52078
  messages,
52028
52079
  isTyping,
@@ -52030,15 +52081,24 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
52030
52081
  sendMessage: chatSendMessage,
52031
52082
  stopMessage: chatStopMessage,
52032
52083
  clearMessages: chatClearMessages,
52084
+ hydrateMessages,
52033
52085
  hasMessages
52034
52086
  } = useChat({
52035
52087
  useMock: false,
52036
52088
  assistantName: "Mingo AI",
52037
- streamFn,
52038
- initialMessages: persistedRef.current.messages,
52039
- onMessagesChange: persist
52089
+ streamFn
52090
+ });
52091
+ const historyUrl = runtime.endpoints.chatHistoryUrl ?? `${runtime.endpoints.chatStreamUrl.replace(/\/+$/, "")}/history`;
52092
+ const { isHydratingHistory, hydratedKeyRef } = useChatHistoryHydration({
52093
+ active,
52094
+ source,
52095
+ historyUrl,
52096
+ conversationIdRef,
52097
+ refsMapRef,
52098
+ sendCountRef,
52099
+ hydrateMessages,
52100
+ bumpMetaTick
52040
52101
  });
52041
- messagesRef.current = messages;
52042
52102
  let sendIdx = -1;
52043
52103
  const docMessages = messages.map((m) => {
52044
52104
  const segments = Array.isArray(m.content) ? m.content : void 0;
@@ -52142,17 +52202,14 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
52142
52202
  refsMapRef.current.clear();
52143
52203
  metaMapRef.current.clear();
52144
52204
  sendCountRef.current = 0;
52205
+ conversationIdRef.current = null;
52206
+ conversationStorage.clear();
52207
+ hydratedKeyRef.current = null;
52145
52208
  setStreamingPhase("idle");
52146
52209
  bumpMetaTick();
52147
52210
  chatClearMessages();
52148
- if (typeof window !== "undefined") {
52149
- try {
52150
- window.localStorage.removeItem(chatStorageKey(source));
52151
- } catch {
52152
- }
52153
- }
52154
- }, [chatClearMessages, source, bumpMetaTick]);
52155
- useEffect91(() => {
52211
+ }, [chatClearMessages, conversationStorage, hydratedKeyRef, bumpMetaTick]);
52212
+ useEffect92(() => {
52156
52213
  if (!isTyping && !isStreaming && streamingPhase !== "idle") {
52157
52214
  setStreamingPhase("idle");
52158
52215
  }
@@ -52172,6 +52229,8 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
52172
52229
  stopMessage,
52173
52230
  clearMessages,
52174
52231
  streamingPhase,
52232
+ /** True while the mount-time rebuild from the server transcript runs. */
52233
+ isHydratingHistory,
52175
52234
  /** Provider key for the lib's `<ModelDisplay>` icon. */
52176
52235
  currentProvider: latestMeta?.provider ?? null,
52177
52236
  currentModelLabel: latestMeta?.modelLabel ?? null,
@@ -52186,12 +52245,11 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
52186
52245
  * token counts). null until the trailing usage frame lands. */
52187
52246
  currentUsageBreakdown: latestMeta?.breakdown ?? null,
52188
52247
  // ─── Dialog management — stubs for v1 ────────────────────────────────
52189
- // Guide mode currently keeps its history in `localStorage` opaquely
52190
- // under the hood (`runtime.source` namespaced key). Surfacing that
52191
- // history as a structured dialog list is a follow-up; for now the
52192
- // shape is satisfied with empty defaults so the unified contract
52193
- // type-checks and EmbeddableChat hides sidebar affordances when
52194
- // `dialogs.length === 0`.
52248
+ // Guide mode keeps ONE server-side conversation per stored id
52249
+ // (`chat_conversations`, hydrated on mount). Surfacing multiple threads
52250
+ // as a structured dialog list is a follow-up; for now the shape is
52251
+ // satisfied with empty defaults so the unified contract type-checks and
52252
+ // EmbeddableChat hides sidebar affordances when `dialogs.length === 0`.
52195
52253
  dialogs: SSE_EMPTY_DIALOGS,
52196
52254
  activeDialogId: null,
52197
52255
  selectDialog: noopSelectDialog,
@@ -52234,10 +52292,10 @@ var noopRejectRequest = async (_id, _reason) => {
52234
52292
  // src/components/chat/hooks/use-nats-chat-adapter.ts
52235
52293
  import {
52236
52294
  useCallback as useCallback55,
52237
- useEffect as useEffect92,
52295
+ useEffect as useEffect93,
52238
52296
  useMemo as useMemo49,
52239
- useRef as useRef78,
52240
- useState as useState123
52297
+ useRef as useRef79,
52298
+ useState as useState124
52241
52299
  } from "react";
52242
52300
 
52243
52301
  // src/components/chat/utils/process-historical-messages.ts
@@ -52937,32 +52995,32 @@ function useNatsChatAdapter(config, options = {}) {
52937
52995
  modelLabel = null
52938
52996
  } = config;
52939
52997
  const isManagedMode = fetchDialogs !== void 0;
52940
- const [internalDialogId, setInternalDialogId] = useState123(null);
52998
+ const [internalDialogId, setInternalDialogId] = useState124(null);
52941
52999
  const dialogId = isManagedMode ? internalDialogId : controlledDialogId !== void 0 ? controlledDialogId : null;
52942
- const currentDialogIdRef = useRef78(dialogId);
53000
+ const currentDialogIdRef = useRef79(dialogId);
52943
53001
  currentDialogIdRef.current = dialogId;
52944
- const [messages, setMessages] = useState123([]);
52945
- const [streamingPhase, setStreamingPhase] = useState123("idle");
52946
- const streamingPhaseRef = useRef78(streamingPhase);
53002
+ const [messages, setMessages] = useState124([]);
53003
+ const [streamingPhase, setStreamingPhase] = useState124("idle");
53004
+ const streamingPhaseRef = useRef79(streamingPhase);
52947
53005
  streamingPhaseRef.current = streamingPhase;
52948
- const suppressAgentBusyRef = useRef78(0);
52949
- const adoptTrailingAssistantRef = useRef78(false);
52950
- const hasConnectedOnceRef = useRef78(false);
52951
- const seenParticipantSeqsRef = useRef78(/* @__PURE__ */ new Set());
52952
- const pendingEchoTextsRef = useRef78([]);
52953
- const [approvalStatuses, setApprovalStatuses] = useState123({});
52954
- const [dialogs, setDialogs] = useState123([]);
52955
- const [dialogsNextCursor, setDialogsNextCursor] = useState123(null);
52956
- const [isDialogsLoading, setIsDialogsLoading] = useState123(false);
52957
- const [dialogsError, setDialogsError] = useState123(false);
52958
- const [isCreatingDialog, setIsCreatingDialog] = useState123(false);
52959
- const [messagesNextCursor, setMessagesNextCursor] = useState123(null);
52960
- const [isMessagesLoading, setIsMessagesLoading] = useState123(false);
52961
- const [dialogTokenUsage, setDialogTokenUsage] = useState123(
53006
+ const suppressAgentBusyRef = useRef79(0);
53007
+ const adoptTrailingAssistantRef = useRef79(false);
53008
+ const hasConnectedOnceRef = useRef79(false);
53009
+ const seenParticipantSeqsRef = useRef79(/* @__PURE__ */ new Set());
53010
+ const pendingEchoTextsRef = useRef79([]);
53011
+ const [approvalStatuses, setApprovalStatuses] = useState124({});
53012
+ const [dialogs, setDialogs] = useState124([]);
53013
+ const [dialogsNextCursor, setDialogsNextCursor] = useState124(null);
53014
+ const [isDialogsLoading, setIsDialogsLoading] = useState124(false);
53015
+ const [dialogsError, setDialogsError] = useState124(false);
53016
+ const [isCreatingDialog, setIsCreatingDialog] = useState124(false);
53017
+ const [messagesNextCursor, setMessagesNextCursor] = useState124(null);
53018
+ const [isMessagesLoading, setIsMessagesLoading] = useState124(false);
53019
+ const [dialogTokenUsage, setDialogTokenUsage] = useState124(
52962
53020
  null
52963
53021
  );
52964
- const [liveModel, setLiveModel] = useState123(null);
52965
- const [connectionState, setConnectionState] = useState123("connecting");
53022
+ const [liveModel, setLiveModel] = useState124(null);
53023
+ const [connectionState, setConnectionState] = useState124("connecting");
52966
53024
  const handleApprove = useCallback55(
52967
53025
  async (requestId) => {
52968
53026
  if (!approveRequestCallback) return;
@@ -53002,9 +53060,9 @@ function useNatsChatAdapter(config, options = {}) {
53002
53060
  },
53003
53061
  [rejectRequestCallback]
53004
53062
  );
53005
- const handleApproveRef = useRef78(handleApprove);
53063
+ const handleApproveRef = useRef79(handleApprove);
53006
53064
  handleApproveRef.current = handleApprove;
53007
- const handleRejectRef = useRef78(handleReject);
53065
+ const handleRejectRef = useRef79(handleReject);
53008
53066
  handleRejectRef.current = handleReject;
53009
53067
  const accumApprove = useCallback55((requestId) => {
53010
53068
  if (!requestId) return;
@@ -53014,7 +53072,7 @@ function useNatsChatAdapter(config, options = {}) {
53014
53072
  if (!requestId) return;
53015
53073
  return handleRejectRef.current(requestId);
53016
53074
  }, []);
53017
- const callbacksRef = useRef78({
53075
+ const callbacksRef = useRef79({
53018
53076
  onSegmentsUpdate: (segments, meta) => {
53019
53077
  if (meta?.append && meta.isCompacting) {
53020
53078
  setMessages((prev) => upsertTrailingCompaction(prev, segments));
@@ -53232,7 +53290,7 @@ function useNatsChatAdapter(config, options = {}) {
53232
53290
  onChunkReceived: (chunk) => processChunk(chunk),
53233
53291
  fetchChunks
53234
53292
  });
53235
- const historyLoadSeqRef = useRef78(0);
53293
+ const historyLoadSeqRef = useRef79(0);
53236
53294
  const loadDialogHistory = useCallback55(
53237
53295
  async (id, cursor) => {
53238
53296
  if (!fetchDialogMessages) return;
@@ -53291,8 +53349,8 @@ function useNatsChatAdapter(config, options = {}) {
53291
53349
  isBufferingActive
53292
53350
  ]
53293
53351
  );
53294
- const prevDialogIdRef = useRef78(void 0);
53295
- useEffect92(() => {
53352
+ const prevDialogIdRef = useRef79(void 0);
53353
+ useEffect93(() => {
53296
53354
  if (prevDialogIdRef.current === dialogId) return;
53297
53355
  prevDialogIdRef.current = dialogId;
53298
53356
  historyLoadSeqRef.current += 1;
@@ -53309,7 +53367,7 @@ function useNatsChatAdapter(config, options = {}) {
53309
53367
  if (!active || !dialogId) return;
53310
53368
  void loadDialogHistory(dialogId);
53311
53369
  }, [active, dialogId, loadDialogHistory, resetAccumulator]);
53312
- useEffect92(() => {
53370
+ useEffect93(() => {
53313
53371
  if (!active || !dialogId) return;
53314
53372
  suppressAgentBusyRef.current += 1;
53315
53373
  resetChunkTracking();
@@ -53361,14 +53419,14 @@ function useNatsChatAdapter(config, options = {}) {
53361
53419
  })();
53362
53420
  }
53363
53421
  });
53364
- useEffect92(() => {
53422
+ useEffect93(() => {
53365
53423
  if (!active || !dialogId) {
53366
53424
  setConnectionState("connected");
53367
53425
  return;
53368
53426
  }
53369
53427
  setConnectionState("connecting");
53370
53428
  }, [active, dialogId]);
53371
- const initialDialogsLoadedRef = useRef78(false);
53429
+ const initialDialogsLoadedRef = useRef79(false);
53372
53430
  const loadDialogsPage = useCallback55(
53373
53431
  async (cursor) => {
53374
53432
  if (!fetchDialogs) return;
@@ -53400,7 +53458,7 @@ function useNatsChatAdapter(config, options = {}) {
53400
53458
  const reloadDialogs = useCallback55(() => {
53401
53459
  void loadDialogsPage();
53402
53460
  }, [loadDialogsPage]);
53403
- useEffect92(() => {
53461
+ useEffect93(() => {
53404
53462
  if (!fetchDialogs) return;
53405
53463
  if (!active) return;
53406
53464
  if (initialDialogsLoadedRef.current) return;
@@ -53643,7 +53701,7 @@ function useNatsChatAdapter(config, options = {}) {
53643
53701
  }
53644
53702
 
53645
53703
  // src/components/chat/hooks/use-unified-chat.ts
53646
- import { useCallback as useCallback56, useMemo as useMemo50, useRef as useRef79 } from "react";
53704
+ import { useCallback as useCallback56, useMemo as useMemo50, useRef as useRef80 } from "react";
53647
53705
  var EMPTY_SSE_OPTIONS = {};
53648
53706
  function createDisabledNatsConfig() {
53649
53707
  return {
@@ -53658,7 +53716,7 @@ function createDisabledNatsConfig() {
53658
53716
  }
53659
53717
  function useUnifiedChat(options) {
53660
53718
  const { modes, activeMode, mingoStateOverride } = options;
53661
- const disabledNatsRef = useRef79(null);
53719
+ const disabledNatsRef = useRef80(null);
53662
53720
  if (disabledNatsRef.current === null) {
53663
53721
  disabledNatsRef.current = createDisabledNatsConfig();
53664
53722
  }
@@ -53672,7 +53730,7 @@ function useUnifiedChat(options) {
53672
53730
  { active: natsActive }
53673
53731
  );
53674
53732
  const activeState = activeMode === "guide" ? sseState : mingoStateOverride ?? natsState;
53675
- const activeStateRef = useRef79(activeState);
53733
+ const activeStateRef = useRef80(activeState);
53676
53734
  activeStateRef.current = activeState;
53677
53735
  const stopMessage = useCallback56(() => activeStateRef.current.stopMessage(), []);
53678
53736
  const clearMessages = useCallback56(
@@ -54036,7 +54094,7 @@ function buildStreamFrames(messages) {
54036
54094
 
54037
54095
  // src/components/chat/embeddable-chat.tsx
54038
54096
  init_cn();
54039
- import { useCallback as useCallback58, useEffect as useEffect93, useMemo as useMemo52, useRef as useRef81, useState as useState125 } from "react";
54097
+ import { useCallback as useCallback58, useEffect as useEffect94, useMemo as useMemo52, useRef as useRef82, useState as useState126 } from "react";
54040
54098
  import * as DialogPrimitive5 from "@radix-ui/react-dialog";
54041
54099
  import { usePreventScroll as usePreventScroll6 } from "@react-aria/overlays";
54042
54100
  import { isIOS } from "@react-aria/utils";
@@ -54123,7 +54181,7 @@ init_button2();
54123
54181
  import { FileText as FileText8, MessageSquare as MessageSquare3 } from "lucide-react";
54124
54182
 
54125
54183
  // src/components/chat/hooks/use-chat-dialog-manager.ts
54126
- import { useCallback as useCallback57, useMemo as useMemo51, useRef as useRef80, useState as useState124 } from "react";
54184
+ import { useCallback as useCallback57, useMemo as useMemo51, useRef as useRef81, useState as useState125 } from "react";
54127
54185
  function useChatDialogManager({
54128
54186
  dialogs,
54129
54187
  activeDialogId,
@@ -54134,8 +54192,8 @@ function useChatDialogManager({
54134
54192
  fetchArchivedDialogs,
54135
54193
  unarchiveDialog
54136
54194
  }) {
54137
- const [renameTarget, setRenameTarget] = useState124(null);
54138
- const [archiveTarget, setArchiveTarget] = useState124(null);
54195
+ const [renameTarget, setRenameTarget] = useState125(null);
54196
+ const [archiveTarget, setArchiveTarget] = useState125(null);
54139
54197
  const handleConfirmRename = useCallback57(
54140
54198
  (name) => {
54141
54199
  if (renameTarget) void renameDialog(renameTarget.id, name);
@@ -54158,12 +54216,12 @@ function useChatDialogManager({
54158
54216
  }
54159
54217
  setArchiveTarget(null);
54160
54218
  }, [archiveTarget, archiveDialog, activeDialogId, clearMessages]);
54161
- const [archiveOpen, setArchiveOpen] = useState124(false);
54162
- const [archivedDialogs, setArchivedDialogs] = useState124([]);
54163
- const [archivedCursor, setArchivedCursor] = useState124(null);
54164
- const [archivedLoading, setArchivedLoading] = useState124(false);
54165
- const [archivedPending, setArchivedPending] = useState124(false);
54166
- const archivedRequestIdRef = useRef80(0);
54219
+ const [archiveOpen, setArchiveOpen] = useState125(false);
54220
+ const [archivedDialogs, setArchivedDialogs] = useState125([]);
54221
+ const [archivedCursor, setArchivedCursor] = useState125(null);
54222
+ const [archivedLoading, setArchivedLoading] = useState125(false);
54223
+ const [archivedPending, setArchivedPending] = useState125(false);
54224
+ const archivedRequestIdRef = useRef81(0);
54167
54225
  const loadArchivedPage = useCallback57(
54168
54226
  async (cursor) => {
54169
54227
  if (!fetchArchivedDialogs) return;
@@ -54204,10 +54262,10 @@ function useChatDialogManager({
54204
54262
  void loadArchivedPage();
54205
54263
  }, [loadArchivedPage]);
54206
54264
  const closeArchive = useCallback57(() => setArchiveOpen(false), []);
54207
- const [viewingArchivedId, setViewingArchivedId] = useState124(
54265
+ const [viewingArchivedId, setViewingArchivedId] = useState125(
54208
54266
  null
54209
54267
  );
54210
- const [openingDialogId, setOpeningDialogId] = useState124(null);
54268
+ const [openingDialogId, setOpeningDialogId] = useState125(null);
54211
54269
  const handleSelectDialog = useCallback57(
54212
54270
  (id) => {
54213
54271
  setViewingArchivedId(null);
@@ -54226,7 +54284,7 @@ function useChatDialogManager({
54226
54284
  },
54227
54285
  [selectDialog]
54228
54286
  );
54229
- const [restoreTarget, setRestoreTarget] = useState124(null);
54287
+ const [restoreTarget, setRestoreTarget] = useState125(null);
54230
54288
  const handleConfirmRestore = useCallback57(async () => {
54231
54289
  if (restoreTarget) {
54232
54290
  try {
@@ -54319,9 +54377,9 @@ var SPLIT_MIN_WIDTH = HISTORY_RAIL_WIDTH + CHAT_BLOCK_MIN_WIDTH;
54319
54377
  var RAIL_COLLAPSED_STORAGE_KEY = "mingo-chat-history-collapsed";
54320
54378
  var RAIL_ANIM_MS = 320;
54321
54379
  function useRailPresence(open) {
54322
- const [mounted, setMounted] = useState125(open);
54323
- const [active, setActive] = useState125(false);
54324
- useEffect93(() => {
54380
+ const [mounted, setMounted] = useState126(open);
54381
+ const [active, setActive] = useState126(false);
54382
+ useEffect94(() => {
54325
54383
  if (open) {
54326
54384
  setMounted(true);
54327
54385
  let raf2 = 0;
@@ -54539,7 +54597,7 @@ function SourceChips({
54539
54597
  onClose,
54540
54598
  onDiscuss
54541
54599
  }) {
54542
- const [expanded, setExpanded] = useState125(false);
54600
+ const [expanded, setExpanded] = useState126(false);
54543
54601
  if (cited.length === 0) {
54544
54602
  const fallback = uncited.slice(0, FALLBACK_TOP_RETRIEVED);
54545
54603
  if (fallback.length === 0) return null;
@@ -54647,7 +54705,7 @@ function EmbeddableChatInner({
54647
54705
  const commandsUrl = runtime.endpoints.commandsUrl;
54648
54706
  const { attachmentsEnabled, user: identityUser } = useChatIdentity();
54649
54707
  const viewUrlPrefix = runtime.endpoints.attachmentViewUrlPrefix;
54650
- useEffect93(() => {
54708
+ useEffect94(() => {
54651
54709
  if (process.env.NODE_ENV !== "production") {
54652
54710
  const hasOpen = open !== void 0;
54653
54711
  const hasHandler = onOpenChange !== void 0;
@@ -54663,13 +54721,13 @@ function EmbeddableChatInner({
54663
54721
  defaultProp: defaultOpen ?? false,
54664
54722
  onChange: onOpenChange
54665
54723
  });
54666
- const [autoFocusInput] = useState125(() => {
54724
+ const [autoFocusInput] = useState126(() => {
54667
54725
  if (typeof window === "undefined") return false;
54668
54726
  return !window.matchMedia("(pointer: coarse)").matches;
54669
54727
  });
54670
54728
  usePreventScroll6({ isDisabled: !isOpen || shellLess });
54671
- const navigatingAwayRef = useRef81(false);
54672
- useEffect93(() => {
54729
+ const navigatingAwayRef = useRef82(false);
54730
+ useEffect94(() => {
54673
54731
  if (!isOpen) return;
54674
54732
  if (shellLess) return;
54675
54733
  if (typeof window === "undefined") return;
@@ -54695,8 +54753,8 @@ function EmbeddableChatInner({
54695
54753
  window.scrollTo(0, scrollY);
54696
54754
  };
54697
54755
  }, [isOpen, shellLess]);
54698
- const chatInputRef = useRef81(null);
54699
- const [quickActionPreview, setQuickActionPreview] = useState125(null);
54756
+ const chatInputRef = useRef82(null);
54757
+ const [quickActionPreview, setQuickActionPreview] = useState126(null);
54700
54758
  const slashCommandsProp = useMemo52(
54701
54759
  () => ({
54702
54760
  fetchCommands: (prefix, signal) => fetchSlashCommands(prefix, signal, commandsUrl),
@@ -54739,7 +54797,7 @@ function EmbeddableChatInner({
54739
54797
  }, [mingoState, mingoDialogCapabilities, effectiveModes]);
54740
54798
  const hasMingoMode = !!effectiveModes.mingo || !!mingoState;
54741
54799
  const initialActiveMode = controlledActiveMode ?? defaultActiveMode ?? (effectiveModes.guide ? "guide" : "mingo");
54742
- const [uncontrolledActiveMode, setUncontrolledActiveMode] = useState125(initialActiveMode);
54800
+ const [uncontrolledActiveMode, setUncontrolledActiveMode] = useState126(initialActiveMode);
54743
54801
  const activeMode = controlledActiveMode ?? uncontrolledActiveMode;
54744
54802
  const handleActiveModeChange = useCallback58(
54745
54803
  (next) => {
@@ -54801,8 +54859,8 @@ function EmbeddableChatInner({
54801
54859
  hasMoreMessages,
54802
54860
  loadMoreMessages
54803
54861
  } = useUnifiedChat({ modes: effectiveModes, activeMode, mingoStateOverride: mingoState });
54804
- const guidePromptSentRef = useRef81(false);
54805
- useEffect93(() => {
54862
+ const guidePromptSentRef = useRef82(false);
54863
+ useEffect94(() => {
54806
54864
  if (!guidePendingPrompt) {
54807
54865
  guidePromptSentRef.current = false;
54808
54866
  return;
@@ -54823,15 +54881,15 @@ function EmbeddableChatInner({
54823
54881
  const { panelRef: galleryPanelRef, modal: galleryModal } = useChatAttachmentImageGallery();
54824
54882
  const contextMaxItems = contextPicker?.maxItems ?? 10;
54825
54883
  const contextPickerForMode = activeMode === "mingo" ? contextPicker : void 0;
54826
- const [contextItems, setContextItems] = useState125([]);
54827
- const [contextPickerOpen, setContextPickerOpen] = useState125(false);
54828
- const [mentionQuery, setMentionQuery] = useState125(null);
54829
- const mentionActiveRef = useRef81(false);
54830
- useEffect93(() => {
54884
+ const [contextItems, setContextItems] = useState126([]);
54885
+ const [contextPickerOpen, setContextPickerOpen] = useState126(false);
54886
+ const [mentionQuery, setMentionQuery] = useState126(null);
54887
+ const mentionActiveRef = useRef82(false);
54888
+ useEffect94(() => {
54831
54889
  mentionActiveRef.current = mentionQuery !== null;
54832
54890
  }, [mentionQuery]);
54833
- const mentionKeysRef = useRef81(/* @__PURE__ */ new Set());
54834
- useEffect93(() => {
54891
+ const mentionKeysRef = useRef82(/* @__PURE__ */ new Set());
54892
+ useEffect94(() => {
54835
54893
  setContextItems([]);
54836
54894
  setMentionQuery(null);
54837
54895
  mentionKeysRef.current.clear();
@@ -54927,7 +54985,7 @@ function EmbeddableChatInner({
54927
54985
  () => effectiveAssistantIcon ? /* @__PURE__ */ jsx369(EntityIcon, { icon: effectiveAssistantIcon, size: 24 }) : /* @__PURE__ */ jsx369(MingoIcon, { className: "h-6 w-6", cornerColor: "var(--ods-flamingo-cyan-base)" }),
54928
54986
  [effectiveAssistantIcon]
54929
54987
  );
54930
- const timestampCacheRef = useRef81(/* @__PURE__ */ new Map());
54988
+ const timestampCacheRef = useRef82(/* @__PURE__ */ new Map());
54931
54989
  const guideUserName = activeMode === "guide" ? [identityUser?.firstName, identityUser?.lastName].filter(Boolean).join(" ").trim() || identityUser?.name?.trim() || void 0 : void 0;
54932
54990
  const guideUserAvatar = activeMode === "guide" ? identityUser?.avatarUrl?.trim() || void 0 : void 0;
54933
54991
  const messages = useMemo52(() => {
@@ -55054,7 +55112,7 @@ function EmbeddableChatInner({
55054
55112
  });
55055
55113
  const handleOpen = useCallback58(() => setIsOpen(true), [setIsOpen]);
55056
55114
  useCloseOnNavigation(handleNavigationClose, null);
55057
- useEffect93(() => {
55115
+ useEffect94(() => {
55058
55116
  const handler = (e) => {
55059
55117
  const detail = e.detail;
55060
55118
  if (!detail || detail.source !== source) return;
@@ -55064,7 +55122,7 @@ function EmbeddableChatInner({
55064
55122
  window.addEventListener("ask-ai:open-with-ref", handler);
55065
55123
  return () => window.removeEventListener("ask-ai:open-with-ref", handler);
55066
55124
  }, [source, discussRef, setIsOpen]);
55067
- useEffect93(() => {
55125
+ useEffect94(() => {
55068
55126
  const handler = (e) => {
55069
55127
  const detail = e.detail;
55070
55128
  if (!detail || detail.source !== source) return;
@@ -55081,7 +55139,7 @@ function EmbeddableChatInner({
55081
55139
  const contentViewKey = hasConversation ? "conversation" : activeMode;
55082
55140
  const isGuideEmpty = !hasConversation && activeMode === "guide";
55083
55141
  const isQuickActionEmpty = !hasConversation && (activeMode === "guide" || activeMode === "mingo");
55084
- useEffect93(() => {
55142
+ useEffect94(() => {
55085
55143
  if (!isQuickActionEmpty) setQuickActionPreview(null);
55086
55144
  }, [isQuickActionEmpty]);
55087
55145
  const guideCanReturnToMingo = isGuideEmpty && hasMingoMode;
@@ -55123,10 +55181,10 @@ function EmbeddableChatInner({
55123
55181
  const uncited = sources.filter((s) => !seenOrder.has(s.index));
55124
55182
  return { cited, uncited };
55125
55183
  }, [lastAssistantMsg, chatLoading]);
55126
- const [portalHost, setPortalHost] = useState125(null);
55127
- const [panelWidth, setPanelWidth] = useState125(0);
55128
- const panelMeasureRef = useRef81(null);
55129
- useEffect93(() => {
55184
+ const [portalHost, setPortalHost] = useState126(null);
55185
+ const [panelWidth, setPanelWidth] = useState126(0);
55186
+ const panelMeasureRef = useRef82(null);
55187
+ useEffect94(() => {
55130
55188
  const el = panelMeasureRef.current;
55131
55189
  if (!el || typeof ResizeObserver === "undefined") return;
55132
55190
  const ro = new ResizeObserver((entries) => {
@@ -55137,8 +55195,8 @@ function EmbeddableChatInner({
55137
55195
  setPanelWidth(el.clientWidth);
55138
55196
  return () => ro.disconnect();
55139
55197
  }, []);
55140
- const [railCollapsed, setRailCollapsed] = useState125(false);
55141
- useEffect93(() => {
55198
+ const [railCollapsed, setRailCollapsed] = useState126(false);
55199
+ useEffect94(() => {
55142
55200
  try {
55143
55201
  if (window.localStorage.getItem(RAIL_COLLAPSED_STORAGE_KEY) === "1")
55144
55202
  setRailCollapsed(true);
@@ -55155,15 +55213,15 @@ function EmbeddableChatInner({
55155
55213
  return next;
55156
55214
  });
55157
55215
  }, []);
55158
- const [railSearchOpen, setRailSearchOpen] = useState125(false);
55216
+ const [railSearchOpen, setRailSearchOpen] = useState126(false);
55159
55217
  const splitEligible = activeMode === "mingo";
55160
55218
  const canSplit = panelWidth >= SPLIT_MIN_WIDTH;
55161
55219
  const wideMingo = splitEligible && canSplit && !previewMode;
55162
55220
  const splitActive = wideMingo && !railCollapsed;
55163
55221
  const railPresence = useRailPresence(splitActive);
55164
55222
  const showWideHeader = wideMingo || railPresence.mounted;
55165
- const [composeOpen, setComposeOpen] = useState125(false);
55166
- useEffect93(() => {
55223
+ const [composeOpen, setComposeOpen] = useState126(false);
55224
+ useEffect94(() => {
55167
55225
  if (hasConversation) setComposeOpen(false);
55168
55226
  }, [hasConversation]);
55169
55227
  const isMingoMode = activeMode === "mingo";
@@ -56280,11 +56338,10 @@ export {
56280
56338
  useCloseOnNavigation,
56281
56339
  useSSE,
56282
56340
  useChat,
56283
- SCROLL_ANCHOR_WIRE_KEY,
56284
- parseScrollAnchor,
56285
56341
  AUTO_CONTINUATION_DIRECTIVE_PREFIX,
56286
56342
  buildAutoContinuationDirective,
56287
- flattenAssistantContent,
56343
+ SCROLL_ANCHOR_WIRE_KEY,
56344
+ parseScrollAnchor,
56288
56345
  parseWireCommandOverride,
56289
56346
  sanitizeTitleForChat,
56290
56347
  formatSingularLookupInvocation,
@@ -56309,6 +56366,7 @@ export {
56309
56366
  computeHistoryPrepend,
56310
56367
  CHIP_ACTION_BUTTON_CLASS,
56311
56368
  chatChipClass,
56369
+ flattenAssistantContent,
56312
56370
  clickupTaskUrl,
56313
56371
  normalizeHistoricalMessageData,
56314
56372
  isHistoricalUserTurn,
@@ -56740,4 +56798,4 @@ export {
56740
56798
  LogsList,
56741
56799
  assets
56742
56800
  };
56743
- //# sourceMappingURL=chunk-BC74IKAX.js.map
56801
+ //# sourceMappingURL=chunk-YMJZOANX.js.map