@flamingo-stack/openframe-frontend-core 0.0.444 → 0.0.445-snapshot.20260717185124

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 (126) hide show
  1. package/dist/{chunk-BYTJNRJW.cjs → chunk-3AFV2YIC.cjs} +40 -40
  2. package/dist/{chunk-BYTJNRJW.cjs.map → chunk-3AFV2YIC.cjs.map} +1 -1
  3. package/dist/{chunk-MG4AMIFX.js → chunk-5NYXGWBN.js} +2 -2
  4. package/dist/{chunk-Q6XOEVPH.cjs → chunk-5WX2V6CY.cjs} +12 -12
  5. package/dist/{chunk-Q6XOEVPH.cjs.map → chunk-5WX2V6CY.cjs.map} +1 -1
  6. package/dist/{chunk-CE3AITV2.js → chunk-5YQSRQHP.js} +6 -6
  7. package/dist/{chunk-OXZLBIR7.cjs → chunk-6XZNIPXP.cjs} +18 -18
  8. package/dist/{chunk-OXZLBIR7.cjs.map → chunk-6XZNIPXP.cjs.map} +1 -1
  9. package/dist/{chunk-VI2QQIGR.cjs → chunk-7IC2QCOL.cjs} +73 -73
  10. package/dist/{chunk-VI2QQIGR.cjs.map → chunk-7IC2QCOL.cjs.map} +1 -1
  11. package/dist/{chunk-4R3SVOKH.cjs → chunk-BAUWT7PV.cjs} +1101 -700
  12. package/dist/chunk-BAUWT7PV.cjs.map +1 -0
  13. package/dist/{chunk-37ZZQXHK.js → chunk-BNYI2FVM.js} +4 -4
  14. package/dist/{chunk-2PLNDTRG.cjs → chunk-DH3DUY6Q.cjs} +32 -32
  15. package/dist/{chunk-2PLNDTRG.cjs.map → chunk-DH3DUY6Q.cjs.map} +1 -1
  16. package/dist/{chunk-FQASXKBK.js → chunk-G2KXNMFQ.js} +2 -2
  17. package/dist/{chunk-PMTR5W5G.js → chunk-GTHA2SYB.js} +5 -5
  18. package/dist/{chunk-LCJGOV6P.js → chunk-I7IOEXRJ.js} +2 -2
  19. package/dist/{chunk-H7H3AFLF.js → chunk-K6JIBV3X.js} +2 -2
  20. package/dist/{chunk-YP7VJPCJ.cjs → chunk-L276GOMD.cjs} +40 -40
  21. package/dist/{chunk-YP7VJPCJ.cjs.map → chunk-L276GOMD.cjs.map} +1 -1
  22. package/dist/{chunk-NDWIFCLS.js → chunk-MAB4TQCO.js} +731 -330
  23. package/dist/{chunk-NDWIFCLS.js.map → chunk-MAB4TQCO.js.map} +1 -1
  24. package/dist/{chunk-ABIRMYG5.js → chunk-MR7BMJHI.js} +6 -6
  25. package/dist/{chunk-FO4CI4R5.cjs → chunk-MS5CEBBQ.cjs} +5 -5
  26. package/dist/{chunk-FO4CI4R5.cjs.map → chunk-MS5CEBBQ.cjs.map} +1 -1
  27. package/dist/{chunk-RALJEQWM.cjs → chunk-N3Y6JYH5.cjs} +15 -15
  28. package/dist/{chunk-RALJEQWM.cjs.map → chunk-N3Y6JYH5.cjs.map} +1 -1
  29. package/dist/{chunk-DCDB3SM4.js → chunk-N4CCB33C.js} +3 -3
  30. package/dist/{chunk-WXU6A6CA.cjs → chunk-NQLY27GH.cjs} +73 -73
  31. package/dist/{chunk-WXU6A6CA.cjs.map → chunk-NQLY27GH.cjs.map} +1 -1
  32. package/dist/{chunk-PHWQLKVE.js → chunk-P47NN7RY.js} +29 -31
  33. package/dist/chunk-P47NN7RY.js.map +1 -0
  34. package/dist/{chunk-2CJ734N2.cjs → chunk-PTT4J5GF.cjs} +3 -3
  35. package/dist/{chunk-2CJ734N2.cjs.map → chunk-PTT4J5GF.cjs.map} +1 -1
  36. package/dist/{chunk-DSW6FIEF.cjs → chunk-SA7AHDS6.cjs} +7 -7
  37. package/dist/{chunk-DSW6FIEF.cjs.map → chunk-SA7AHDS6.cjs.map} +1 -1
  38. package/dist/{chunk-F2XHBAHT.js → chunk-SAV4U37G.js} +2 -2
  39. package/dist/{chunk-3SCNEGL2.js → chunk-SCKAD2MY.js} +5 -5
  40. package/dist/{chunk-7CZ4MJSI.cjs → chunk-VIJARDBM.cjs} +3 -3
  41. package/dist/{chunk-7CZ4MJSI.cjs.map → chunk-VIJARDBM.cjs.map} +1 -1
  42. package/dist/{chunk-PXXS27EE.cjs → chunk-W24U7ZUV.cjs} +40 -42
  43. package/dist/chunk-W24U7ZUV.cjs.map +1 -0
  44. package/dist/{chunk-U7U2CZBZ.js → chunk-XB6D7B3I.js} +3 -3
  45. package/dist/{chunk-DTMJWBDQ.js → chunk-YLMD4UFA.js} +3 -3
  46. package/dist/{chunk-F6NMMPDL.cjs → chunk-ZKYEMGMD.cjs} +29 -29
  47. package/dist/{chunk-F6NMMPDL.cjs.map → chunk-ZKYEMGMD.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-chunk-catchup.d.ts.map +1 -1
  51. package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts.map +1 -1
  52. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +44 -1
  53. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  54. package/dist/components/chat/hooks/use-nats-dialog-subscription.d.ts.map +1 -1
  55. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -1
  56. package/dist/components/chat/index.cjs +10 -4
  57. package/dist/components/chat/index.cjs.map +1 -1
  58. package/dist/components/chat/index.js +9 -3
  59. package/dist/components/chat/utils/message-segment-accumulator.d.ts.map +1 -1
  60. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  61. package/dist/components/contact/index.cjs +5 -5
  62. package/dist/components/contact/index.js +4 -4
  63. package/dist/components/docs/index.cjs +7 -7
  64. package/dist/components/docs/index.js +6 -6
  65. package/dist/components/embeds/index.cjs +5 -5
  66. package/dist/components/embeds/index.js +4 -4
  67. package/dist/components/faq/index.cjs +6 -6
  68. package/dist/components/faq/index.js +5 -5
  69. package/dist/components/features/index.cjs +4 -4
  70. package/dist/components/features/index.js +3 -3
  71. package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
  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 +142 -136
  75. package/dist/components/index.cjs.map +1 -1
  76. package/dist/components/index.js +18 -12
  77. package/dist/components/index.js.map +1 -1
  78. package/dist/components/navigation/index.cjs +4 -4
  79. package/dist/components/navigation/index.js +3 -3
  80. package/dist/components/onboarding-guides/index.cjs +8 -8
  81. package/dist/components/onboarding-guides/index.js +7 -7
  82. package/dist/components/related-content/index.cjs +6 -6
  83. package/dist/components/related-content/index.js +5 -5
  84. package/dist/components/tickets/index.cjs +7 -7
  85. package/dist/components/tickets/index.js +6 -6
  86. package/dist/components/ui/index.cjs +10 -4
  87. package/dist/components/ui/index.cjs.map +1 -1
  88. package/dist/components/ui/index.js +9 -3
  89. package/dist/hooks/index.cjs +3 -3
  90. package/dist/hooks/index.js +2 -2
  91. package/dist/index.cjs +10 -4
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.js +9 -3
  94. package/dist/nats/index.cjs +2 -2
  95. package/dist/nats/index.js +1 -1
  96. package/dist/nats/shared-connection.d.ts +6 -0
  97. package/dist/nats/shared-connection.d.ts.map +1 -1
  98. package/package.json +1 -1
  99. package/src/components/chat/hooks/__tests__/nats-adapter-message-updaters.test.ts +270 -0
  100. package/src/components/chat/hooks/use-chunk-catchup.ts +212 -57
  101. package/src/components/chat/hooks/use-jetstream-dialog-subscription.ts +12 -8
  102. package/src/components/chat/hooks/use-nats-chat-adapter.ts +574 -9
  103. package/src/components/chat/hooks/use-nats-dialog-subscription.ts +12 -6
  104. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +40 -3
  105. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +62 -0
  106. package/src/components/chat/utils/message-segment-accumulator.ts +6 -0
  107. package/src/components/chat/utils/process-historical-messages.ts +25 -3
  108. package/src/components/features/policy-configuration-panel.tsx +34 -49
  109. package/src/nats/shared-connection.ts +42 -29
  110. package/src/stories/PolicyConfigurationPanel.stories.tsx +8 -6
  111. package/dist/chunk-4R3SVOKH.cjs.map +0 -1
  112. package/dist/chunk-PHWQLKVE.js.map +0 -1
  113. package/dist/chunk-PXXS27EE.cjs.map +0 -1
  114. /package/dist/{chunk-MG4AMIFX.js.map → chunk-5NYXGWBN.js.map} +0 -0
  115. /package/dist/{chunk-CE3AITV2.js.map → chunk-5YQSRQHP.js.map} +0 -0
  116. /package/dist/{chunk-37ZZQXHK.js.map → chunk-BNYI2FVM.js.map} +0 -0
  117. /package/dist/{chunk-FQASXKBK.js.map → chunk-G2KXNMFQ.js.map} +0 -0
  118. /package/dist/{chunk-PMTR5W5G.js.map → chunk-GTHA2SYB.js.map} +0 -0
  119. /package/dist/{chunk-LCJGOV6P.js.map → chunk-I7IOEXRJ.js.map} +0 -0
  120. /package/dist/{chunk-H7H3AFLF.js.map → chunk-K6JIBV3X.js.map} +0 -0
  121. /package/dist/{chunk-ABIRMYG5.js.map → chunk-MR7BMJHI.js.map} +0 -0
  122. /package/dist/{chunk-DCDB3SM4.js.map → chunk-N4CCB33C.js.map} +0 -0
  123. /package/dist/{chunk-F2XHBAHT.js.map → chunk-SAV4U37G.js.map} +0 -0
  124. /package/dist/{chunk-3SCNEGL2.js.map → chunk-SCKAD2MY.js.map} +0 -0
  125. /package/dist/{chunk-U7U2CZBZ.js.map → chunk-XB6D7B3I.js.map} +0 -0
  126. /package/dist/{chunk-DTMJWBDQ.js.map → chunk-YLMD4UFA.js.map} +0 -0
@@ -27,7 +27,7 @@ import {
27
27
  useOgPlaceholderUrl,
28
28
  useOnboardingState,
29
29
  useToast
30
- } from "./chunk-MG4AMIFX.js";
30
+ } from "./chunk-5NYXGWBN.js";
31
31
  import {
32
32
  AlertCircleIcon,
33
33
  AnthropicLogoGreyIcon,
@@ -249,7 +249,7 @@ import {
249
249
  acquireClient,
250
250
  releaseClient,
251
251
  startConnectionLifecycle
252
- } from "./chunk-PHWQLKVE.js";
252
+ } from "./chunk-P47NN7RY.js";
253
253
  import {
254
254
  __esm
255
255
  } from "./chunk-GGWZFCYS.js";
@@ -31939,23 +31939,22 @@ function ViewToggle({
31939
31939
 
31940
31940
  // src/components/features/policy-configuration-panel.tsx
31941
31941
  init_cn();
31942
- import { useRef as useRef37, useEffect as useEffect52, useState as useState71 } from "react";
31942
+ import { useEffect as useEffect52, useState as useState71 } from "react";
31943
31943
  import { ChevronDown as ChevronDown8, Shield as Shield2 } from "lucide-react";
31944
31944
  init_button2();
31945
31945
  import { Fragment as Fragment43, jsx as jsx253, jsxs as jsxs197 } from "react/jsx-runtime";
31946
- var approvalLevelOptions = [
31947
- { value: "ALLOW", label: "Allow" },
31948
- { value: "ASK_USER", label: "Ask User" },
31949
- { value: "ASK_TECHNICIAN", label: "Ask Technician" },
31950
- { value: "DENY", label: "Restrict" }
31951
- ];
31952
- var getApprovalLevelLabel = (level, editMode = false) => {
31953
- if (!level) {
31954
- return editMode ? "Set Global Permission" : "";
31955
- }
31956
- const option = approvalLevelOptions.find((opt) => opt.value === level);
31957
- return option?.label || level;
31946
+ var approvalLevelLabels = {
31947
+ ALLOW: "Allow",
31948
+ ASK_USER: "Ask User",
31949
+ ASK_TECHNICIAN: "Ask Technician",
31950
+ DENY: "Restrict"
31958
31951
  };
31952
+ var approvalLevelOptions = Object.keys(approvalLevelLabels).map(
31953
+ (value) => ({ value, label: approvalLevelLabels[value] })
31954
+ );
31955
+ var POLICY_LEVEL_WIDTH = "w-[180px]";
31956
+ var CATEGORY_LEVEL_WIDTH = "w-[256px]";
31957
+ var getApprovalLevelLabel = (level) => approvalLevelLabels[level] ?? level;
31959
31958
  var ApprovalLevelDropdown = ({ value, onChange, allowClear = false, triggerClassName, contentClassName }) => /* @__PURE__ */ jsxs197(DropdownMenu, { children: [
31960
31959
  /* @__PURE__ */ jsx253(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx253(
31961
31960
  Button,
@@ -31967,7 +31966,7 @@ var ApprovalLevelDropdown = ({ value, onChange, allowClear = false, triggerClass
31967
31966
  value ? "text-ods-text-primary" : "text-ods-text-secondary",
31968
31967
  triggerClassName
31969
31968
  ),
31970
- children: getApprovalLevelLabel(value, true)
31969
+ children: value ? getApprovalLevelLabel(value) : "Set Global Permission"
31971
31970
  }
31972
31971
  ) }),
31973
31972
  /* @__PURE__ */ jsxs197(DropdownMenuContent, { align: "end", className: contentClassName, children: [
@@ -31998,7 +31997,7 @@ var PolicyRow = ({ policy, categoryId, editMode, onPermissionChange }) => {
31998
31997
  value: policy.approvalLevel,
31999
31998
  onChange: handleChange,
32000
31999
  triggerClassName: "w-full",
32001
- contentClassName: "w-[180px]"
32000
+ contentClassName: POLICY_LEVEL_WIDTH
32002
32001
  }
32003
32002
  ) }) : policy.approvalLevel ? /* @__PURE__ */ jsx253("span", { className: "md:hidden text-h4 text-ods-text-primary", children: getApprovalLevelLabel(policy.approvalLevel) }) : null
32004
32003
  ] }),
@@ -32007,23 +32006,12 @@ var PolicyRow = ({ policy, categoryId, editMode, onPermissionChange }) => {
32007
32006
  {
32008
32007
  value: policy.approvalLevel,
32009
32008
  onChange: handleChange,
32010
- triggerClassName: "w-[180px]",
32011
- contentClassName: "w-[180px]"
32009
+ triggerClassName: POLICY_LEVEL_WIDTH,
32010
+ contentClassName: POLICY_LEVEL_WIDTH
32012
32011
  }
32013
- ) : /* @__PURE__ */ jsx253("div", { className: "px-[var(--spacing-system-sf)] py-[var(--spacing-system-xsf)] w-[180px]", children: policy.approvalLevel && /* @__PURE__ */ jsx253("span", { className: "text-h4 text-ods-text-primary", children: getApprovalLevelLabel(policy.approvalLevel) }) }) })
32012
+ ) : /* @__PURE__ */ jsx253("div", { className: cn("px-[var(--spacing-system-sf)] py-[var(--spacing-system-xsf)]", POLICY_LEVEL_WIDTH), children: policy.approvalLevel && /* @__PURE__ */ jsx253("span", { className: "text-h4 text-ods-text-primary", children: getApprovalLevelLabel(policy.approvalLevel) }) }) })
32014
32013
  ] });
32015
32014
  };
32016
- var useAnimatedHeight = (isExpanded) => {
32017
- const [height, setHeight] = useState71(0);
32018
- const contentRef = useRef37(null);
32019
- useEffect52(() => {
32020
- if (contentRef.current) {
32021
- const contentHeight = contentRef.current.scrollHeight;
32022
- setHeight(isExpanded ? contentHeight : 0);
32023
- }
32024
- }, [isExpanded]);
32025
- return { contentRef, height };
32026
- };
32027
32015
  var CategorySection = ({
32028
32016
  category,
32029
32017
  editMode,
@@ -32033,7 +32021,7 @@ var CategorySection = ({
32033
32021
  onBulkLevelChange,
32034
32022
  onPolicyPermissionChange
32035
32023
  }) => {
32036
- const { contentRef, height } = useAnimatedHeight(isExpanded);
32024
+ const { innerRef, containerStyle } = useCollapsible({ expanded: isExpanded, durationMs: 300 });
32037
32025
  const handleBulkChange = (level) => onBulkLevelChange(category.id, level);
32038
32026
  return /* @__PURE__ */ jsxs197(Fragment43, { children: [
32039
32027
  /* @__PURE__ */ jsxs197(
@@ -32056,7 +32044,7 @@ var CategorySection = ({
32056
32044
  onChange: handleBulkChange,
32057
32045
  allowClear: true,
32058
32046
  triggerClassName: "w-full",
32059
- contentClassName: "w-[256px]"
32047
+ contentClassName: CATEGORY_LEVEL_WIDTH
32060
32048
  }
32061
32049
  ) })
32062
32050
  ] }),
@@ -32066,16 +32054,10 @@ var CategorySection = ({
32066
32054
  value: bulkLevel,
32067
32055
  onChange: handleBulkChange,
32068
32056
  allowClear: true,
32069
- triggerClassName: "w-[256px]",
32070
- contentClassName: "w-[256px]"
32057
+ triggerClassName: CATEGORY_LEVEL_WIDTH,
32058
+ contentClassName: CATEGORY_LEVEL_WIDTH
32071
32059
  }
32072
- ) }) : /* @__PURE__ */ jsx253(
32073
- "div",
32074
- {
32075
- className: "hidden md:block px-[var(--spacing-system-sf)] py-[var(--spacing-system-xsf)] w-[256px] shrink-0",
32076
- onClick: (e) => e.stopPropagation()
32077
- }
32078
- ),
32060
+ ) }) : /* @__PURE__ */ jsx253("div", { className: cn("hidden md:block px-[var(--spacing-system-sf)] py-[var(--spacing-system-xsf)] shrink-0", CATEGORY_LEVEL_WIDTH) }),
32079
32061
  /* @__PURE__ */ jsx253(
32080
32062
  Button,
32081
32063
  {
@@ -32104,16 +32086,15 @@ var CategorySection = ({
32104
32086
  /* @__PURE__ */ jsx253(
32105
32087
  "div",
32106
32088
  {
32107
- ref: contentRef,
32108
32089
  style: {
32109
- height: height === "auto" ? "auto" : `${height}px`,
32110
- transition: "height 300ms ease-in-out, opacity 300ms ease-in-out"
32090
+ ...containerStyle,
32091
+ transition: `${containerStyle.transition}, opacity 300ms ease-in-out, visibility 300ms`,
32092
+ // visibility drops collapsed content from the tab order and a11y
32093
+ // tree; its discrete transition delays hiding until the fade ends.
32094
+ visibility: isExpanded ? "visible" : "hidden"
32111
32095
  },
32112
- className: cn(
32113
- "overflow-hidden",
32114
- isExpanded ? "opacity-100" : "opacity-0"
32115
- ),
32116
- children: /* @__PURE__ */ jsx253("div", { className: "px-[var(--spacing-system-mf)] pb-[var(--spacing-system-mf)] pt-0", children: /* @__PURE__ */ jsx253("div", { className: "border border-ods-border rounded-md overflow-hidden", children: category.policies.map((policy) => /* @__PURE__ */ jsx253(
32096
+ className: isExpanded ? "opacity-100" : "opacity-0",
32097
+ children: /* @__PURE__ */ jsx253("div", { ref: innerRef, className: "px-[var(--spacing-system-mf)] pb-[var(--spacing-system-mf)] pt-0", children: /* @__PURE__ */ jsx253("div", { className: "border border-ods-border rounded-md overflow-hidden", children: category.policies.map((policy) => /* @__PURE__ */ jsx253(
32117
32098
  PolicyRow,
32118
32099
  {
32119
32100
  policy,
@@ -32176,7 +32157,7 @@ PolicyConfigurationPanel.displayName = "PolicyConfigurationPanel";
32176
32157
  init_button2();
32177
32158
 
32178
32159
  // src/components/ui/phone-input.tsx
32179
- import { useCallback as useCallback28, useEffect as useEffect53, useMemo as useMemo27, useRef as useRef38, useState as useState72 } from "react";
32160
+ import { useCallback as useCallback28, useEffect as useEffect53, useMemo as useMemo27, useRef as useRef37, useState as useState72 } from "react";
32180
32161
  import { jsx as jsx254, jsxs as jsxs198 } from "react/jsx-runtime";
32181
32162
  function PhoneInput({
32182
32163
  value,
@@ -32194,7 +32175,7 @@ function PhoneInput({
32194
32175
  [countryCode, priority, others]
32195
32176
  );
32196
32177
  const [isInvalid, setIsInvalid] = useState72(false);
32197
- const debounceRef = useRef38(null);
32178
+ const debounceRef = useRef37(null);
32198
32179
  const digitCount = useCallback28((val) => val.replace(/[^0-9]/g, "").length, []);
32199
32180
  const runValidation = useCallback28((phone) => {
32200
32181
  if (!phone || digitCount(phone) === 0) {
@@ -32700,7 +32681,7 @@ function useOptionalNotifications() {
32700
32681
  }
32701
32682
 
32702
32683
  // src/components/features/notifications/notification-drawer.tsx
32703
- import { useEffect as useEffect58, useRef as useRef41 } from "react";
32684
+ import { useEffect as useEffect58, useRef as useRef40 } from "react";
32704
32685
 
32705
32686
  // src/components/navigation/app-layout-context.ts
32706
32687
  import { createContext as createContext8, useContext as useContext8 } from "react";
@@ -33468,9 +33449,9 @@ function DrawerScrollList({
33468
33449
  loadMoreRootMargin,
33469
33450
  renderTile
33470
33451
  }) {
33471
- const scrollRef = useRef41(null);
33472
- const sentinelRef = useRef41(null);
33473
- const loadMoreRef = useRef41(loadMore);
33452
+ const scrollRef = useRef40(null);
33453
+ const sentinelRef = useRef40(null);
33454
+ const loadMoreRef = useRef40(loadMore);
33474
33455
  loadMoreRef.current = loadMore;
33475
33456
  useEffect58(() => {
33476
33457
  if (!loadMore || !hasMore || isLoadingMore) return;
@@ -34339,7 +34320,7 @@ function LastEntryRow({ entry, onClick }) {
34339
34320
  // src/components/features/time-tracker/time-tracker-header-button.tsx
34340
34321
  init_cn();
34341
34322
  import * as PopoverPrimitive5 from "@radix-ui/react-popover";
34342
- import { useEffect as useEffect61, useRef as useRef42 } from "react";
34323
+ import { useEffect as useEffect61, useRef as useRef41 } from "react";
34343
34324
 
34344
34325
  // src/components/navigation/header-button.tsx
34345
34326
  init_cn();
@@ -34378,11 +34359,11 @@ function TimeTrackerHeaderButton({ className, disabled }) {
34378
34359
  const layoutContainer = useAppLayoutDrawerContainer();
34379
34360
  const coordination = useAppLayoutDrawerCoordination();
34380
34361
  const isOpen = ctx?.isOpen ?? false;
34381
- const isOpenRef = useRef42(isOpen);
34362
+ const isOpenRef = useRef41(isOpen);
34382
34363
  isOpenRef.current = isOpen;
34383
- const closeRef = useRef42(ctx?.close);
34364
+ const closeRef = useRef41(ctx?.close);
34384
34365
  closeRef.current = ctx?.close;
34385
- const selfHandleRef = useRef42(null);
34366
+ const selfHandleRef = useRef41(null);
34386
34367
  if (!selfHandleRef.current) {
34387
34368
  selfHandleRef.current = {
34388
34369
  close: () => {
@@ -35407,18 +35388,18 @@ function SortableRow({
35407
35388
 
35408
35389
  // src/components/navigation/header.tsx
35409
35390
  init_next_link();
35410
- import React108, { useEffect as useEffect64, useRef as useRef46, useState as useState84 } from "react";
35391
+ import React108, { useEffect as useEffect64, useRef as useRef45, useState as useState84 } from "react";
35411
35392
  init_button2();
35412
35393
 
35413
35394
  // src/components/navigation/mobile-nav-panel.tsx
35414
- import { useRef as useRef45 } from "react";
35395
+ import { useRef as useRef44 } from "react";
35415
35396
  import { usePreventScroll as usePreventScroll3 } from "@react-aria/overlays";
35416
35397
  init_button2();
35417
35398
  import { X as X10 } from "lucide-react";
35418
35399
  import { Fragment as Fragment51, jsx as jsx273, jsxs as jsxs212 } from "react/jsx-runtime";
35419
35400
  var MOBILE_NAV_PANEL_ID = "mobile-nav-panel";
35420
35401
  function MobileNavPanel({ isOpen, config }) {
35421
- const panelRef = useRef45(null);
35402
+ const panelRef = useRef44(null);
35422
35403
  usePreventScroll3({ isDisabled: !isOpen });
35423
35404
  useFocusTrap(panelRef, isOpen, { onEscape: config.onClose });
35424
35405
  const headerHeight = useHeaderHeight(64, { enabled: isOpen });
@@ -35579,8 +35560,8 @@ function Header2({ config, platform }) {
35579
35560
  const [show, setShow] = useState84(true);
35580
35561
  const [lastScrollY, setLastScrollY] = useState84(0);
35581
35562
  const [openDropdowns, setOpenDropdowns] = useState84({});
35582
- const dropdownRefs = useRef46({});
35583
- const triggerRefs = useRef46({});
35563
+ const dropdownRefs = useRef45({});
35564
+ const triggerRefs = useRef45({});
35584
35565
  useEffect64(() => {
35585
35566
  const handleClickOutside = (event) => {
35586
35567
  const target = event.target;
@@ -35906,7 +35887,7 @@ function ClientOnlyHeader({ config, skeleton }) {
35906
35887
  }
35907
35888
 
35908
35889
  // src/components/navigation/sliding-sidebar.tsx
35909
- import { useState as useState86, useEffect as useEffect66, useRef as useRef47 } from "react";
35890
+ import { useState as useState86, useEffect as useEffect66, useRef as useRef46 } from "react";
35910
35891
  import { motion as motion2, AnimatePresence, useReducedMotion } from "framer-motion";
35911
35892
  import { usePreventScroll as usePreventScroll4 } from "@react-aria/overlays";
35912
35893
  init_button2();
@@ -35915,7 +35896,7 @@ function SlidingSidebar({ config }) {
35915
35896
  const [expandedItems, setExpandedItems] = useState86(/* @__PURE__ */ new Set());
35916
35897
  const [mounted, setMounted] = useState86(false);
35917
35898
  const headerHeight = useHeaderHeight();
35918
- const asideRef = useRef47(null);
35899
+ const asideRef = useRef46(null);
35919
35900
  const prefersReducedMotion2 = useReducedMotion();
35920
35901
  usePreventScroll4({ isDisabled: !config.isOpen });
35921
35902
  useFocusTrap(asideRef, config.isOpen, { onEscape: config.onClose, contain: false });
@@ -36087,7 +36068,7 @@ function SlidingSidebar({ config }) {
36087
36068
  }
36088
36069
 
36089
36070
  // src/components/navigation/sticky-section-nav.tsx
36090
- import { useEffect as useEffect67, useState as useState87, useCallback as useCallback35, useRef as useRef48 } from "react";
36071
+ import { useEffect as useEffect67, useState as useState87, useCallback as useCallback35, useRef as useRef47 } from "react";
36091
36072
  import { jsx as jsx279, jsxs as jsxs217 } from "react/jsx-runtime";
36092
36073
  function StickySectionNav({
36093
36074
  sections,
@@ -36149,7 +36130,7 @@ function StickySectionNav({
36149
36130
  }
36150
36131
  function useSectionNavigation(sections, options) {
36151
36132
  const [activeSection, setActiveSection] = useState87(sections[0]?.id || "");
36152
- const isScrollingFromClick = useRef48(false);
36133
+ const isScrollingFromClick = useRef47(false);
36153
36134
  const { offset: offset2 = 100 } = options || {};
36154
36135
  const handleSectionClick = useCallback35((sectionId) => {
36155
36136
  const targetElement = document.getElementById(sectionId);
@@ -36849,10 +36830,10 @@ function NotificationsHeaderButton({
36849
36830
  }
36850
36831
 
36851
36832
  // src/components/navigation/app-layout.tsx
36852
- import { Suspense as Suspense2, useCallback as useCallback38, useMemo as useMemo35, useRef as useRef50, useState as useState89 } from "react";
36833
+ import { Suspense as Suspense2, useCallback as useCallback38, useMemo as useMemo35, useRef as useRef49, useState as useState89 } from "react";
36853
36834
 
36854
36835
  // src/components/navigation/mobile-burger-menu.tsx
36855
- import React113, { useCallback as useCallback37, useRef as useRef49 } from "react";
36836
+ import React113, { useCallback as useCallback37, useRef as useRef48 } from "react";
36856
36837
  import { usePreventScroll as usePreventScroll5 } from "@react-aria/overlays";
36857
36838
  import { Fragment as Fragment55, jsx as jsx288, jsxs as jsxs226 } from "react/jsx-runtime";
36858
36839
  var HEADER_HEIGHT = 48;
@@ -36866,7 +36847,7 @@ var MobileBurgerMenu = React113.memo(function MobileBurgerMenu2({
36866
36847
  onLogout,
36867
36848
  disabled = false
36868
36849
  }) {
36869
- const panelRef = useRef49(null);
36850
+ const panelRef = useRef48(null);
36870
36851
  usePreventScroll5({ isDisabled: !isOpen });
36871
36852
  useFocusTrap(panelRef, isOpen, { onEscape: onClose });
36872
36853
  const handleItemClick = useCallback37((item) => {
@@ -37051,9 +37032,9 @@ function AppLayout({
37051
37032
  }) {
37052
37033
  const [mobileMenuOpen, setMobileMenuOpen] = useState89(false);
37053
37034
  const [drawerContainer, setDrawerContainer] = useState89(null);
37054
- const mobileMenuOpenRef = useRef50(mobileMenuOpen);
37035
+ const mobileMenuOpenRef = useRef49(mobileMenuOpen);
37055
37036
  mobileMenuOpenRef.current = mobileMenuOpen;
37056
- const drawerHandlesRef = useRef50(/* @__PURE__ */ new Set());
37037
+ const drawerHandlesRef = useRef49(/* @__PURE__ */ new Set());
37057
37038
  const handleToggleMobileMenu = useCallback38(() => {
37058
37039
  const opening = !mobileMenuOpenRef.current;
37059
37040
  if (opening) {
@@ -37680,7 +37661,7 @@ ScriptArguments.displayName = "ScriptArguments";
37680
37661
 
37681
37662
  // src/components/shared/onboarding/onboarding-walkthrough.tsx
37682
37663
  init_button2();
37683
- import React115, { useRef as useRef51, useCallback as useCallback39 } from "react";
37664
+ import React115, { useRef as useRef50, useCallback as useCallback39 } from "react";
37684
37665
 
37685
37666
  // src/components/shared/onboarding/onboarding-step-card.tsx
37686
37667
  import React114 from "react";
@@ -37804,10 +37785,10 @@ function OnboardingWalkthrough({
37804
37785
  allStepsComplete,
37805
37786
  markMultipleComplete
37806
37787
  } = useOnboardingState(storageKey);
37807
- const hasAutoMarkedRef = useRef51(false);
37808
- const autoMarkingInProgressRef = useRef51(false);
37809
- const lastCompletionStatusRef = useRef51(null);
37810
- const actionInProgressRef = useRef51(/* @__PURE__ */ new Set());
37788
+ const hasAutoMarkedRef = useRef50(false);
37789
+ const autoMarkingInProgressRef = useRef50(false);
37790
+ const lastCompletionStatusRef = useRef50(null);
37791
+ const actionInProgressRef = useRef50(/* @__PURE__ */ new Set());
37811
37792
  React115.useEffect(() => {
37812
37793
  if (isLoadingCompletion) {
37813
37794
  hasAutoMarkedRef.current = false;
@@ -38495,7 +38476,7 @@ var ListLoader = (props) => /* @__PURE__ */ jsx307(ContentLoader, { ...props, va
38495
38476
 
38496
38477
  // src/components/ui/table/table.tsx
38497
38478
  init_cn();
38498
- import { useEffect as useEffect70, useRef as useRef53 } from "react";
38479
+ import { useEffect as useEffect70, useRef as useRef52 } from "react";
38499
38480
  init_pagination();
38500
38481
  init_button2();
38501
38482
 
@@ -39255,8 +39236,8 @@ function Table({
39255
39236
  };
39256
39237
  const allSelected = selectedRows.length > 0 && selectedRows.length === data.length;
39257
39238
  const someSelected = selectedRows.length > 0 && selectedRows.length < data.length;
39258
- const sentinelRef = useRef53(null);
39259
- const onLoadMoreRef = useRef53(infiniteScroll?.onLoadMore);
39239
+ const sentinelRef = useRef52(null);
39240
+ const onLoadMoreRef = useRef52(infiniteScroll?.onLoadMore);
39260
39241
  onLoadMoreRef.current = infiniteScroll?.onLoadMore;
39261
39242
  useEffect70(() => {
39262
39243
  if (!infiniteScroll?.hasNextPage || infiniteScroll.isFetchingNextPage) return;
@@ -39476,7 +39457,7 @@ import { useMemo as useMemo37 } from "react";
39476
39457
 
39477
39458
  // src/components/ui/query-report-table/query-report-table-header.tsx
39478
39459
  init_cn();
39479
- import { useRef as useRef54, useState as useState92, useCallback as useCallback40 } from "react";
39460
+ import { useRef as useRef53, useState as useState92, useCallback as useCallback40 } from "react";
39480
39461
  import { jsx as jsx319, jsxs as jsxs252 } from "react/jsx-runtime";
39481
39462
  function QueryReportTableHeader({
39482
39463
  columns,
@@ -39505,7 +39486,7 @@ function QueryReportTableHeader({
39505
39486
  );
39506
39487
  }
39507
39488
  function TruncatedHeaderCell({ value, width }) {
39508
- const textRef = useRef54(null);
39489
+ const textRef = useRef53(null);
39509
39490
  const [isTruncated, setIsTruncated] = useState92(false);
39510
39491
  const checkTruncation = useCallback40(() => {
39511
39492
  const el = textRef.current;
@@ -39535,7 +39516,7 @@ function TruncatedHeaderCell({ value, width }) {
39535
39516
 
39536
39517
  // src/components/ui/query-report-table/query-report-table-row.tsx
39537
39518
  init_cn();
39538
- import { useRef as useRef55, useState as useState93, useCallback as useCallback41 } from "react";
39519
+ import { useRef as useRef54, useState as useState93, useCallback as useCallback41 } from "react";
39539
39520
  import { jsx as jsx320, jsxs as jsxs253 } from "react/jsx-runtime";
39540
39521
  function QueryReportTableRow({
39541
39522
  row,
@@ -39581,7 +39562,7 @@ function QueryReportTableRow({
39581
39562
  );
39582
39563
  }
39583
39564
  function TruncatedCell({ value, className }) {
39584
- const textRef = useRef55(null);
39565
+ const textRef = useRef54(null);
39585
39566
  const [isTruncated, setIsTruncated] = useState93(false);
39586
39567
  const checkTruncation = useCallback41(() => {
39587
39568
  const el = textRef.current;
@@ -40083,7 +40064,7 @@ function DataTableEmpty({ className, ...props }) {
40083
40064
  // src/components/ui/data-table/data-table-row.tsx
40084
40065
  init_next_link();
40085
40066
  init_cn();
40086
- import { memo as memo5, useCallback as useCallback43, useRef as useRef56 } from "react";
40067
+ import { memo as memo5, useCallback as useCallback43, useRef as useRef55 } from "react";
40087
40068
  import { flexRender as flexRender2 } from "@tanstack/react-table";
40088
40069
 
40089
40070
  // src/components/ui/data-table/data-table-skeleton.tsx
@@ -40168,7 +40149,7 @@ function DataTableRowImpl({
40168
40149
  const hasSubRow = subRow != null && subRow !== false;
40169
40150
  const isLinkMode = Boolean(href) && !onClick;
40170
40151
  const isWholeCardLink = isLinkMode && !hasSubRow;
40171
- const containerRef = useRef56(null);
40152
+ const containerRef = useRef55(null);
40172
40153
  const handleClick = useCallback43(
40173
40154
  (e) => {
40174
40155
  const target = e.target;
@@ -40336,7 +40317,7 @@ function DataTableBody({
40336
40317
  }
40337
40318
 
40338
40319
  // src/components/ui/data-table/data-table-infinite-footer.tsx
40339
- import { useEffect as useEffect71, useRef as useRef57 } from "react";
40320
+ import { useEffect as useEffect71, useRef as useRef56 } from "react";
40340
40321
  import { Fragment as Fragment63, jsx as jsx330, jsxs as jsxs261 } from "react/jsx-runtime";
40341
40322
  function DataTableInfiniteFooter({
40342
40323
  hasNextPage,
@@ -40345,8 +40326,8 @@ function DataTableInfiniteFooter({
40345
40326
  skeletonRows = 3,
40346
40327
  rootMargin = "200px"
40347
40328
  }) {
40348
- const sentinelRef = useRef57(null);
40349
- const onLoadMoreRef = useRef57(onLoadMore);
40329
+ const sentinelRef = useRef56(null);
40330
+ const onLoadMoreRef = useRef56(onLoadMore);
40350
40331
  onLoadMoreRef.current = onLoadMore;
40351
40332
  useEffect71(() => {
40352
40333
  if (!hasNextPage || isFetchingNextPage) return;
@@ -40983,7 +40964,7 @@ function FilterList({
40983
40964
  // src/components/ui/tag-search-input.tsx
40984
40965
  import {
40985
40966
  useEffect as useEffect73,
40986
- useRef as useRef59,
40967
+ useRef as useRef58,
40987
40968
  useState as useState95
40988
40969
  } from "react";
40989
40970
  init_cn();
@@ -41018,9 +40999,9 @@ function TagSearchInput({
41018
40999
  limitTags,
41019
41000
  placeholder: currentPlaceholder
41020
41001
  });
41021
- const wrapperRef = useRef59(null);
41022
- const hiddenTagsRef = useRef59(null);
41023
- const hiddenTagsPopupRef = useRef59(null);
41002
+ const wrapperRef = useRef58(null);
41003
+ const hiddenTagsRef = useRef58(null);
41004
+ const hiddenTagsPopupRef = useRef58(null);
41024
41005
  const [showHiddenTags, setShowHiddenTags] = useState95(false);
41025
41006
  useEffect73(() => {
41026
41007
  if (!showHiddenTags) return;
@@ -41177,7 +41158,7 @@ function TagSearchInput({
41177
41158
  }
41178
41159
 
41179
41160
  // src/components/ui/markdown-editor.tsx
41180
- import { useRef as useRef60, useCallback as useCallback44, useState as useState96, useEffect as useEffect74 } from "react";
41161
+ import { useRef as useRef59, useCallback as useCallback44, useState as useState96, useEffect as useEffect74 } from "react";
41181
41162
  init_cn();
41182
41163
  import { Loader2 as Loader29, Upload as Upload8 } from "lucide-react";
41183
41164
  import { jsx as jsx335, jsxs as jsxs266 } from "react/jsx-runtime";
@@ -41232,7 +41213,7 @@ function MarkdownEditor({
41232
41213
  onFileUploaded,
41233
41214
  renderPreview
41234
41215
  }) {
41235
- const fileInputRef = useRef60(null);
41216
+ const fileInputRef = useRef59(null);
41236
41217
  const [isUploading, setIsUploading] = useState96(false);
41237
41218
  const [uploadProgress, setUploadProgress] = useState96("");
41238
41219
  const [defaultExtraCommands, setDefaultExtraCommands] = useState96([]);
@@ -41325,11 +41306,11 @@ function MarkdownEditor({
41325
41306
  }
41326
41307
  } : null;
41327
41308
  const extraCommands = uploadCommand ? [...defaultExtraCommands, uploadCommand] : defaultExtraCommands;
41328
- const wrapperRef = useRef60(null);
41329
- const isDraggingRef = useRef60(false);
41330
- const mouseYRef = useRef60(0);
41331
- const rafRef = useRef60(0);
41332
- const scrollParentRef = useRef60(window);
41309
+ const wrapperRef = useRef59(null);
41310
+ const isDraggingRef = useRef59(false);
41311
+ const mouseYRef = useRef59(0);
41312
+ const rafRef = useRef59(0);
41313
+ const scrollParentRef = useRef59(window);
41333
41314
  const EDGE_ZONE = 60;
41334
41315
  const MAX_SCROLL_SPEED = 15;
41335
41316
  const findScrollParent = useCallback44((el) => {
@@ -46932,7 +46913,7 @@ function renderChatInlineEntityCard(chatRef, options = {}) {
46932
46913
  }
46933
46914
 
46934
46915
  // src/components/chat/hooks/use-chunk-catchup.ts
46935
- import { useCallback as useCallback46, useRef as useRef64 } from "react";
46916
+ import { useCallback as useCallback46, useRef as useRef63 } from "react";
46936
46917
  function makeSeqKey(messageType, chunkType, sequenceId) {
46937
46918
  return `${messageType}:${chunkType}:${sequenceId}`;
46938
46919
  }
@@ -46954,20 +46935,22 @@ function useChunkCatchup({
46954
46935
  chatTypes = [CHAT_TYPE.CLIENT],
46955
46936
  fetchChunks
46956
46937
  }) {
46957
- const processedSequenceKeys = useRef64(/* @__PURE__ */ new Set());
46958
- const lastSequenceId = useRef64(null);
46959
- const fetchingInProgress = useRef64(false);
46960
- const lastFetchParams = useRef64(null);
46961
- const chunkBuffer = useRef64([]);
46962
- const bufferUntilInitialCatchupComplete = useRef64(false);
46963
- const hasCompletedInitialCatchup = useRef64(false);
46964
- const dialogIdRef = useRef64(dialogId);
46938
+ const processedSequenceKeys = useRef63(/* @__PURE__ */ new Set());
46939
+ const lastSequenceId = useRef63(null);
46940
+ const lastSequenceIdByType = useRef63(/* @__PURE__ */ new Map());
46941
+ const fetchingInProgress = useRef63(false);
46942
+ const lastFetchParams = useRef63(null);
46943
+ const pendingCatchupRef = useRef63(null);
46944
+ const chunkBuffer = useRef63([]);
46945
+ const bufferUntilInitialCatchupComplete = useRef63(false);
46946
+ const hasCompletedInitialCatchup = useRef63(false);
46947
+ const dialogIdRef = useRef63(dialogId);
46965
46948
  dialogIdRef.current = dialogId;
46966
- const chatTypesRef = useRef64(chatTypes);
46949
+ const chatTypesRef = useRef63(chatTypes);
46967
46950
  chatTypesRef.current = chatTypes;
46968
- const fetchChunksRef = useRef64(fetchChunks);
46951
+ const fetchChunksRef = useRef63(fetchChunks);
46969
46952
  fetchChunksRef.current = fetchChunks;
46970
- const onChunkReceivedRef = useRef64(onChunkReceived);
46953
+ const onChunkReceivedRef = useRef63(onChunkReceived);
46971
46954
  onChunkReceivedRef.current = onChunkReceived;
46972
46955
  const processChunk = useCallback46((chunk, messageType, forceProcess = false) => {
46973
46956
  if (bufferUntilInitialCatchupComplete.current && !forceProcess) {
@@ -46976,8 +46959,14 @@ function useChunkCatchup({
46976
46959
  }
46977
46960
  if (chunk.sequenceId !== void 0 && chunk.sequenceId !== null) {
46978
46961
  const chunkType = typeof chunk.type === "string" ? chunk.type : "";
46979
- processedSequenceKeys.current.add(makeSeqKey(messageType, chunkType, chunk.sequenceId));
46962
+ const key = makeSeqKey(messageType, chunkType, chunk.sequenceId);
46963
+ if (processedSequenceKeys.current.has(key)) return true;
46964
+ processedSequenceKeys.current.add(key);
46980
46965
  lastSequenceId.current = chunk.sequenceId;
46966
+ const prevTypeSeq = lastSequenceIdByType.current.get(messageType);
46967
+ if (prevTypeSeq === void 0 || chunk.sequenceId > prevTypeSeq) {
46968
+ lastSequenceIdByType.current.set(messageType, chunk.sequenceId);
46969
+ }
46981
46970
  }
46982
46971
  onChunkReceivedRef.current(chunk, messageType);
46983
46972
  return true;
@@ -46987,8 +46976,8 @@ function useChunkCatchup({
46987
46976
  const buffered = [...chunkBuffer.current];
46988
46977
  chunkBuffer.current = [];
46989
46978
  buffered.sort((a, b) => {
46990
- const seqA = a.chunk.sequenceId ?? 0;
46991
- const seqB = b.chunk.sequenceId ?? 0;
46979
+ const seqA = a.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
46980
+ const seqB = b.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
46992
46981
  return seqA - seqB;
46993
46982
  });
46994
46983
  buffered.forEach(({ chunk, messageType }) => {
@@ -47003,9 +46992,14 @@ function useChunkCatchup({
47003
46992
  return;
47004
46993
  }
47005
46994
  if (hasCompletedInitialCatchup.current) {
46995
+ if (bufferUntilInitialCatchupComplete.current) {
46996
+ bufferUntilInitialCatchupComplete.current = false;
46997
+ flushBufferedRealtimeChunks();
46998
+ }
47006
46999
  return;
47007
47000
  }
47008
47001
  if (fetchingInProgress.current) {
47002
+ pendingCatchupRef.current = { dialogId: dialogId2, fromSequenceId: fromSequenceId ?? lastSequenceId.current };
47009
47003
  return;
47010
47004
  }
47011
47005
  if (lastFetchParams.current && lastFetchParams.current.dialogId === dialogId2 && lastFetchParams.current.fromSequenceId === fromSequenceId) {
@@ -47022,7 +47016,8 @@ function useChunkCatchup({
47022
47016
  try {
47023
47017
  const chunkPromises = chatTypes2.map(async (chatType) => {
47024
47018
  try {
47025
- const chunks = await fetchChunks2(dialogId2, chatType, fromSequenceId);
47019
+ const typeFromSequenceId = fromSequenceId === void 0 ? void 0 : lastSequenceIdByType.current.get(getChatTypeMessageType(chatType)) ?? null;
47020
+ const chunks = await fetchChunks2(dialogId2, chatType, typeFromSequenceId);
47026
47021
  const messageType = getChatTypeMessageType(chatType);
47027
47022
  return chunks.map((chunk) => ({ chunk, messageType }));
47028
47023
  } catch (error) {
@@ -47042,49 +47037,66 @@ function useChunkCatchup({
47042
47037
  chunkBuffer.current = [];
47043
47038
  const allChunks = [...allCatchupChunks, ...bufferedNatsChunks];
47044
47039
  allChunks.sort((a, b) => {
47045
- const seqA = a.chunk.sequenceId ?? 0;
47046
- const seqB = b.chunk.sequenceId ?? 0;
47040
+ const seqA = a.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
47041
+ const seqB = b.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
47047
47042
  return seqA - seqB;
47048
47043
  });
47049
47044
  const uniqueAllChunks = [];
47050
47045
  const seenInBatch = /* @__PURE__ */ new Set();
47051
47046
  for (const item of allChunks) {
47052
- const k = makeBatchDedupKey(item);
47053
- if (seenInBatch.has(k)) continue;
47054
- seenInBatch.add(k);
47055
- uniqueAllChunks.push(item);
47056
- }
47057
- let lastMessageStartSeqId = null;
47058
- let lastMessageEndSeqId = null;
47059
- for (let i = uniqueAllChunks.length - 1; i >= 0; i--) {
47060
- const seq = uniqueAllChunks[i].chunk.sequenceId;
47061
- if (uniqueAllChunks[i].chunk.type === MESSAGE_TYPE.MESSAGE_END && seq !== void 0 && seq !== null) {
47062
- lastMessageEndSeqId = seq;
47063
- break;
47047
+ const hasSeq = item.chunk.sequenceId !== void 0 && item.chunk.sequenceId !== null;
47048
+ if (hasSeq) {
47049
+ const k = makeBatchDedupKey(item);
47050
+ if (seenInBatch.has(k)) continue;
47051
+ seenInBatch.add(k);
47064
47052
  }
47053
+ uniqueAllChunks.push(item);
47065
47054
  }
47066
- for (let i = uniqueAllChunks.length - 1; i >= 0; i--) {
47067
- const chunk = uniqueAllChunks[i].chunk;
47068
- const seq = chunk.sequenceId;
47069
- if (chunk.type === MESSAGE_TYPE.MESSAGE_START && seq !== void 0 && seq !== null) {
47070
- if (lastMessageEndSeqId === null || seq > lastMessageEndSeqId) {
47071
- lastMessageStartSeqId = seq;
47055
+ const hasNoSeq = (item) => item.chunk.sequenceId === void 0 || item.chunk.sequenceId === null;
47056
+ const byType = /* @__PURE__ */ new Map();
47057
+ for (const item of uniqueAllChunks) {
47058
+ const list = byType.get(item.messageType);
47059
+ if (list) list.push(item);
47060
+ else byType.set(item.messageType, [item]);
47061
+ }
47062
+ const chunksToProcess = [];
47063
+ for (const items of byType.values()) {
47064
+ let lastMessageStartSeqId = null;
47065
+ let lastMessageEndSeqId = null;
47066
+ for (let i = items.length - 1; i >= 0; i--) {
47067
+ const seq = items[i].chunk.sequenceId;
47068
+ if (items[i].chunk.type === MESSAGE_TYPE.MESSAGE_END && seq !== void 0 && seq !== null) {
47069
+ lastMessageEndSeqId = seq;
47072
47070
  break;
47073
47071
  }
47074
47072
  }
47073
+ for (let i = items.length - 1; i >= 0; i--) {
47074
+ const chunk = items[i].chunk;
47075
+ const seq = chunk.sequenceId;
47076
+ if (chunk.type === MESSAGE_TYPE.MESSAGE_START && seq !== void 0 && seq !== null) {
47077
+ if (lastMessageEndSeqId === null || seq > lastMessageEndSeqId) {
47078
+ lastMessageStartSeqId = seq;
47079
+ break;
47080
+ }
47081
+ }
47082
+ }
47083
+ if (lastMessageStartSeqId !== null) {
47084
+ chunksToProcess.push(
47085
+ ...items.filter((item) => hasNoSeq(item) || item.chunk.sequenceId >= lastMessageStartSeqId)
47086
+ );
47087
+ } else if (lastMessageEndSeqId !== null) {
47088
+ chunksToProcess.push(
47089
+ ...items.filter((item) => hasNoSeq(item) || item.chunk.sequenceId > lastMessageEndSeqId)
47090
+ );
47091
+ } else {
47092
+ chunksToProcess.push(...items);
47093
+ }
47075
47094
  }
47076
- let chunksToProcess;
47077
- if (lastMessageStartSeqId !== null) {
47078
- chunksToProcess = uniqueAllChunks.filter(
47079
- (item) => item.chunk.sequenceId !== void 0 && item.chunk.sequenceId >= lastMessageStartSeqId
47080
- );
47081
- } else if (lastMessageEndSeqId !== null) {
47082
- chunksToProcess = uniqueAllChunks.filter(
47083
- (item) => item.chunk.sequenceId !== void 0 && item.chunk.sequenceId > lastMessageEndSeqId
47084
- );
47085
- } else {
47086
- chunksToProcess = uniqueAllChunks;
47087
- }
47095
+ chunksToProcess.sort((a, b) => {
47096
+ const seqA = a.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
47097
+ const seqB = b.chunk.sequenceId ?? Number.MAX_SAFE_INTEGER;
47098
+ return seqA - seqB;
47099
+ });
47088
47100
  chunksToProcess.forEach(({ chunk, messageType }) => {
47089
47101
  if (chunk.sequenceId !== void 0 && chunk.sequenceId !== null) {
47090
47102
  const chunkType = typeof chunk.type === "string" ? chunk.type : "";
@@ -47092,6 +47104,10 @@ function useChunkCatchup({
47092
47104
  if (processedSequenceKeys.current.has(key)) return;
47093
47105
  processedSequenceKeys.current.add(key);
47094
47106
  lastSequenceId.current = chunk.sequenceId;
47107
+ const prevTypeSeq = lastSequenceIdByType.current.get(messageType);
47108
+ if (prevTypeSeq === void 0 || chunk.sequenceId > prevTypeSeq) {
47109
+ lastSequenceIdByType.current.set(messageType, chunk.sequenceId);
47110
+ }
47095
47111
  }
47096
47112
  onChunkReceivedRef.current(chunk, messageType);
47097
47113
  });
@@ -47100,26 +47116,55 @@ function useChunkCatchup({
47100
47116
  } catch (error) {
47101
47117
  console.error("Error during chunk catchup:", error);
47102
47118
  } finally {
47103
- fetchingInProgress.current = false;
47104
- if (bufferUntilInitialCatchupComplete.current) {
47105
- bufferUntilInitialCatchupComplete.current = false;
47106
- hasCompletedInitialCatchup.current = true;
47107
- flushBufferedRealtimeChunks();
47119
+ if (dialogId2 !== dialogIdRef.current) {
47120
+ if (pendingCatchupRef.current?.dialogId === dialogId2) {
47121
+ pendingCatchupRef.current = null;
47122
+ }
47123
+ } else {
47124
+ fetchingInProgress.current = false;
47125
+ const pending = pendingCatchupRef.current;
47126
+ if (pending) {
47127
+ pendingCatchupRef.current = null;
47128
+ if (pending.dialogId === dialogId2) {
47129
+ hasCompletedInitialCatchup.current = false;
47130
+ lastFetchParams.current = null;
47131
+ bufferUntilInitialCatchupComplete.current = true;
47132
+ try {
47133
+ await catchUpChunksRef.current?.(pending.fromSequenceId);
47134
+ } catch (rerunError) {
47135
+ console.error("Queued catch-up re-run failed:", rerunError);
47136
+ }
47137
+ } else if (bufferUntilInitialCatchupComplete.current) {
47138
+ bufferUntilInitialCatchupComplete.current = false;
47139
+ hasCompletedInitialCatchup.current = true;
47140
+ flushBufferedRealtimeChunks();
47141
+ }
47142
+ } else if (bufferUntilInitialCatchupComplete.current) {
47143
+ bufferUntilInitialCatchupComplete.current = false;
47144
+ hasCompletedInitialCatchup.current = true;
47145
+ flushBufferedRealtimeChunks();
47146
+ }
47108
47147
  }
47109
47148
  }
47110
47149
  }, [flushBufferedRealtimeChunks]);
47150
+ const catchUpChunksRef = useRef63(null);
47151
+ catchUpChunksRef.current = catchUpChunks;
47111
47152
  const resetChunkTracking = useCallback46(() => {
47112
47153
  processedSequenceKeys.current.clear();
47113
47154
  lastSequenceId.current = null;
47155
+ lastSequenceIdByType.current.clear();
47114
47156
  fetchingInProgress.current = false;
47115
47157
  lastFetchParams.current = null;
47158
+ pendingCatchupRef.current = null;
47116
47159
  chunkBuffer.current = [];
47117
47160
  bufferUntilInitialCatchupComplete.current = false;
47118
47161
  hasCompletedInitialCatchup.current = false;
47119
47162
  }, []);
47120
47163
  const startInitialBuffering = useCallback46(() => {
47121
- chunkBuffer.current = [];
47122
- bufferUntilInitialCatchupComplete.current = true;
47164
+ if (!bufferUntilInitialCatchupComplete.current) {
47165
+ chunkBuffer.current = [];
47166
+ bufferUntilInitialCatchupComplete.current = true;
47167
+ }
47123
47168
  hasCompletedInitialCatchup.current = false;
47124
47169
  }, []);
47125
47170
  const isBufferingActive = useCallback46(() => bufferUntilInitialCatchupComplete.current, []);
@@ -47128,8 +47173,10 @@ function useChunkCatchup({
47128
47173
  const fromSeq = lastSequenceId.current;
47129
47174
  hasCompletedInitialCatchup.current = false;
47130
47175
  lastFetchParams.current = null;
47131
- bufferUntilInitialCatchupComplete.current = true;
47132
- chunkBuffer.current = [];
47176
+ if (!bufferUntilInitialCatchupComplete.current) {
47177
+ chunkBuffer.current = [];
47178
+ bufferUntilInitialCatchupComplete.current = true;
47179
+ }
47133
47180
  await catchUpChunks(fromSeq);
47134
47181
  }, [catchUpChunks]);
47135
47182
  return {
@@ -47179,7 +47226,7 @@ function useScriptedStream(frames, resetKey, enabled = true) {
47179
47226
  }
47180
47227
 
47181
47228
  // src/components/chat/hooks/use-jetstream-dialog-subscription.ts
47182
- import { useEffect as useEffect79, useRef as useRef65, useState as useState107 } from "react";
47229
+ import { useEffect as useEffect79, useRef as useRef64, useState as useState107 } from "react";
47183
47230
  var DEFAULT_INACTIVE_THRESHOLD_MS = 5 * 6e4;
47184
47231
  var DEFAULT_STREAM_NAME = "CHAT_CHUNKS";
47185
47232
  function useJetStreamDialogSubscription({
@@ -47202,51 +47249,51 @@ function useJetStreamDialogSubscription({
47202
47249
  const [isSubscribed, setIsSubscribed] = useState107(false);
47203
47250
  const [reconnectionCount, setReconnectionCount] = useState107(0);
47204
47251
  const [currentStreamSeq, setCurrentStreamSeq] = useState107(null);
47205
- const clientRef = useRef65(null);
47206
- const subscriptionRef = useRef65(null);
47207
- const highestStreamSeqRef = useRef65(null);
47208
- const onEventRef = useRef65(onEvent);
47252
+ const clientRef = useRef64(null);
47253
+ const subscriptionRef = useRef64(null);
47254
+ const highestStreamSeqRef = useRef64(null);
47255
+ const onEventRef = useRef64(onEvent);
47209
47256
  useEffect79(() => {
47210
47257
  onEventRef.current = onEvent;
47211
47258
  }, [onEvent]);
47212
- const onConnectRef = useRef65(onConnect);
47259
+ const onConnectRef = useRef64(onConnect);
47213
47260
  useEffect79(() => {
47214
47261
  onConnectRef.current = onConnect;
47215
47262
  }, [onConnect]);
47216
- const onDisconnectRef = useRef65(onDisconnect);
47263
+ const onDisconnectRef = useRef64(onDisconnect);
47217
47264
  useEffect79(() => {
47218
47265
  onDisconnectRef.current = onDisconnect;
47219
47266
  }, [onDisconnect]);
47220
- const onSubscribedRef = useRef65(onSubscribed);
47267
+ const onSubscribedRef = useRef64(onSubscribed);
47221
47268
  useEffect79(() => {
47222
47269
  onSubscribedRef.current = onSubscribed;
47223
47270
  }, [onSubscribed]);
47224
- const onBeforeReconnectRef = useRef65(onBeforeReconnect);
47271
+ const onBeforeReconnectRef = useRef64(onBeforeReconnect);
47225
47272
  useEffect79(() => {
47226
47273
  onBeforeReconnectRef.current = onBeforeReconnect;
47227
47274
  }, [onBeforeReconnect]);
47228
- const getNatsWsUrlRef = useRef65(getNatsWsUrl);
47275
+ const getNatsWsUrlRef = useRef64(getNatsWsUrl);
47229
47276
  useEffect79(() => {
47230
47277
  getNatsWsUrlRef.current = getNatsWsUrl;
47231
47278
  }, [getNatsWsUrl]);
47232
- const reconnectionBackoffRef = useRef65(reconnectionBackoff);
47279
+ const reconnectionBackoffRef = useRef64(reconnectionBackoff);
47233
47280
  useEffect79(() => {
47234
47281
  reconnectionBackoffRef.current = reconnectionBackoff;
47235
47282
  }, [reconnectionBackoff]);
47236
- const optStartSeqRef = useRef65(optStartSeq);
47283
+ const optStartSeqRef = useRef64(optStartSeq);
47237
47284
  useEffect79(() => {
47238
47285
  optStartSeqRef.current = optStartSeq;
47239
47286
  }, [optStartSeq]);
47240
- const inactiveThresholdRef = useRef65(inactiveThresholdMs);
47287
+ const inactiveThresholdRef = useRef64(inactiveThresholdMs);
47241
47288
  useEffect79(() => {
47242
47289
  inactiveThresholdRef.current = inactiveThresholdMs;
47243
47290
  }, [inactiveThresholdMs]);
47244
- const hadConnectionBeforeRef = useRef65(false);
47245
- const clientConfigRef = useRef65(clientConfig);
47291
+ const hadConnectionBeforeRef = useRef64(false);
47292
+ const clientConfigRef = useRef64(clientConfig);
47246
47293
  useEffect79(() => {
47247
47294
  clientConfigRef.current = clientConfig;
47248
47295
  }, [clientConfig]);
47249
- const currentWsUrlRef = useRef65("");
47296
+ const currentWsUrlRef = useRef64("");
47250
47297
  const wsUrl = getNatsWsUrl();
47251
47298
  useEffect79(() => {
47252
47299
  if (!enabled || !wsUrl) {
@@ -47329,6 +47376,10 @@ function useJetStreamDialogSubscription({
47329
47376
  }
47330
47377
  };
47331
47378
  }, [enabled, wsUrl]);
47379
+ useEffect79(() => {
47380
+ highestStreamSeqRef.current = null;
47381
+ setCurrentStreamSeq(null);
47382
+ }, [dialogId]);
47332
47383
  useEffect79(() => {
47333
47384
  if (!enabled || !dialogId || !isConnected) {
47334
47385
  if (subscriptionRef.current) {
@@ -47412,15 +47463,11 @@ function useJetStreamDialogSubscription({
47412
47463
  setIsSubscribed(false);
47413
47464
  };
47414
47465
  }, [enabled, dialogId, isConnected, streamName, topic, reconnectionCount]);
47415
- useEffect79(() => {
47416
- highestStreamSeqRef.current = null;
47417
- setCurrentStreamSeq(null);
47418
- }, [dialogId]);
47419
47466
  return { isConnected, isSubscribed, reconnectionCount, currentStreamSeq };
47420
47467
  }
47421
47468
 
47422
47469
  // src/components/chat/hooks/use-nats-dialog-subscription.ts
47423
- import { useEffect as useEffect80, useRef as useRef66, useState as useState108 } from "react";
47470
+ import { useEffect as useEffect80, useRef as useRef65, useState as useState108 } from "react";
47424
47471
  function useNatsDialogSubscription({
47425
47472
  enabled,
47426
47473
  dialogId,
@@ -47437,42 +47484,42 @@ function useNatsDialogSubscription({
47437
47484
  const [isConnected, setIsConnected] = useState108(false);
47438
47485
  const [isSubscribed, setIsSubscribed] = useState108(false);
47439
47486
  const [reconnectionCount, setReconnectionCount] = useState108(0);
47440
- const clientRef = useRef66(null);
47441
- const subscriptionRefs = useRef66(/* @__PURE__ */ new Map());
47442
- const onEventRef = useRef66(onEvent);
47487
+ const clientRef = useRef65(null);
47488
+ const subscriptionRefs = useRef65(/* @__PURE__ */ new Map());
47489
+ const onEventRef = useRef65(onEvent);
47443
47490
  useEffect80(() => {
47444
47491
  onEventRef.current = onEvent;
47445
47492
  }, [onEvent]);
47446
- const onConnectRef = useRef66(onConnect);
47493
+ const onConnectRef = useRef65(onConnect);
47447
47494
  useEffect80(() => {
47448
47495
  onConnectRef.current = onConnect;
47449
47496
  }, [onConnect]);
47450
- const onDisconnectRef = useRef66(onDisconnect);
47497
+ const onDisconnectRef = useRef65(onDisconnect);
47451
47498
  useEffect80(() => {
47452
47499
  onDisconnectRef.current = onDisconnect;
47453
47500
  }, [onDisconnect]);
47454
- const onSubscribedRef = useRef66(onSubscribed);
47501
+ const onSubscribedRef = useRef65(onSubscribed);
47455
47502
  useEffect80(() => {
47456
47503
  onSubscribedRef.current = onSubscribed;
47457
47504
  }, [onSubscribed]);
47458
- const onBeforeReconnectRef = useRef66(onBeforeReconnect);
47505
+ const onBeforeReconnectRef = useRef65(onBeforeReconnect);
47459
47506
  useEffect80(() => {
47460
47507
  onBeforeReconnectRef.current = onBeforeReconnect;
47461
47508
  }, [onBeforeReconnect]);
47462
- const hadConnectionBeforeRef = useRef66(false);
47463
- const getNatsWsUrlRef = useRef66(getNatsWsUrl);
47509
+ const hadConnectionBeforeRef = useRef65(false);
47510
+ const getNatsWsUrlRef = useRef65(getNatsWsUrl);
47464
47511
  useEffect80(() => {
47465
47512
  getNatsWsUrlRef.current = getNatsWsUrl;
47466
47513
  }, [getNatsWsUrl]);
47467
- const reconnectionBackoffRef = useRef66(reconnectionBackoff);
47514
+ const reconnectionBackoffRef = useRef65(reconnectionBackoff);
47468
47515
  useEffect80(() => {
47469
47516
  reconnectionBackoffRef.current = reconnectionBackoff;
47470
47517
  }, [reconnectionBackoff]);
47471
- const clientConfigRef = useRef66(clientConfig);
47518
+ const clientConfigRef = useRef65(clientConfig);
47472
47519
  useEffect80(() => {
47473
47520
  clientConfigRef.current = clientConfig;
47474
47521
  }, [clientConfig]);
47475
- const currentWsUrlRef = useRef66("");
47522
+ const currentWsUrlRef = useRef65("");
47476
47523
  const wsUrl = getNatsWsUrl();
47477
47524
  useEffect80(() => {
47478
47525
  if (!enabled || !wsUrl) {
@@ -47556,13 +47603,15 @@ function useNatsDialogSubscription({
47556
47603
  };
47557
47604
  }, [enabled, wsUrl]);
47558
47605
  const topicsKey = topics.join(",");
47559
- const lastSubscribedDialogIdRef = useRef66(null);
47560
- const isConnectedRef = useRef66(isConnected);
47606
+ const topicsRef = useRef65(topics);
47607
+ topicsRef.current = topics;
47608
+ const lastSubscribedDialogIdRef = useRef65(null);
47609
+ const isConnectedRef = useRef65(isConnected);
47561
47610
  useEffect80(() => {
47562
47611
  isConnectedRef.current = isConnected;
47563
47612
  }, [isConnected]);
47564
- const currentDialogIdRef = useRef66(null);
47565
- const abortControllerRef = useRef66(null);
47613
+ const currentDialogIdRef = useRef65(null);
47614
+ const abortControllerRef = useRef65(null);
47566
47615
  useEffect80(() => {
47567
47616
  currentDialogIdRef.current = dialogId;
47568
47617
  if (!enabled || !dialogId) {
@@ -47615,7 +47664,7 @@ function useNatsDialogSubscription({
47615
47664
  } catch {
47616
47665
  }
47617
47666
  };
47618
- topics.forEach((topic) => {
47667
+ topicsRef.current.forEach((topic) => {
47619
47668
  const subscription = client.subscribeBytes(
47620
47669
  `chat.${dialogId}.${topic}`,
47621
47670
  handleMessage(topic),
@@ -47643,7 +47692,7 @@ function useNatsDialogSubscription({
47643
47692
  lastSubscribedDialogIdRef.current = null;
47644
47693
  abortControllerRef.current = null;
47645
47694
  };
47646
- }, [enabled, dialogId, topicsKey, topics]);
47695
+ }, [enabled, dialogId, topicsKey]);
47647
47696
  useEffect80(() => {
47648
47697
  if (!enabled || !currentDialogIdRef.current || !isConnected) {
47649
47698
  return;
@@ -47666,7 +47715,7 @@ function useNatsDialogSubscription({
47666
47715
  } catch {
47667
47716
  }
47668
47717
  };
47669
- topics.forEach((topic) => {
47718
+ topicsRef.current.forEach((topic) => {
47670
47719
  const subscription = client.subscribeBytes(
47671
47720
  `chat.${dialogId2}.${topic}`,
47672
47721
  handleMessage(topic),
@@ -47680,7 +47729,7 @@ function useNatsDialogSubscription({
47680
47729
  } else if (subscriptionRefs.current.size > 0) {
47681
47730
  setIsSubscribed(true);
47682
47731
  }
47683
- }, [isConnected, enabled, topics, topicsKey]);
47732
+ }, [isConnected, enabled, topicsKey]);
47684
47733
  return { isConnected, isSubscribed, reconnectionCount };
47685
47734
  }
47686
47735
  function buildNatsWsUrl(apiBaseUrl, options) {
@@ -47694,7 +47743,7 @@ function buildNatsWsUrl(apiBaseUrl, options) {
47694
47743
  }
47695
47744
 
47696
47745
  // src/components/chat/hooks/use-realtime-chunk-processor.ts
47697
- import { useCallback as useCallback47, useRef as useRef67, useEffect as useEffect81 } from "react";
47746
+ import { useCallback as useCallback47, useRef as useRef66, useEffect as useEffect81 } from "react";
47698
47747
 
47699
47748
  // src/components/chat/utils/chunk-parser.ts
47700
47749
  function normalizeToolCalls(raw) {
@@ -48041,6 +48090,10 @@ var MessageSegmentAccumulator = class {
48041
48090
  const hasCall = seg.data.toolCalls.some((c) => c.toolExecutionRequestId === execId);
48042
48091
  if (!hasCall) return seg;
48043
48092
  const prev = seg.data.executions?.[execId];
48093
+ if (toolData.type === "EXECUTING_TOOL" && prev?.status === "done") {
48094
+ matched = true;
48095
+ return seg;
48096
+ }
48044
48097
  const next = toolData.type === "EXECUTED_TOOL" ? { status: "done", result: toolData.result, success: toolData.success } : { status: "executing", result: prev?.result, success: prev?.success };
48045
48098
  matched = true;
48046
48099
  return {
@@ -48345,13 +48398,13 @@ function useRealtimeChunkProcessor(options) {
48345
48398
  batchApprovalsEnabled = true,
48346
48399
  isDirectMode = false
48347
48400
  } = options;
48348
- const accumulatorRef = useRef67(
48401
+ const accumulatorRef = useRef66(
48349
48402
  createMessageSegmentAccumulator({
48350
48403
  onApprove: callbacks.onApprove,
48351
48404
  onReject: callbacks.onReject
48352
48405
  })
48353
48406
  );
48354
- const hasInitializedWithData = useRef67(false);
48407
+ const hasInitializedWithData = useRef66(false);
48355
48408
  useEffect81(() => {
48356
48409
  if (initialState && !hasInitializedWithData.current) {
48357
48410
  accumulatorRef.current.initializeWithState(initialState);
@@ -48365,15 +48418,15 @@ function useRealtimeChunkProcessor(options) {
48365
48418
  hasInitializedWithData.current = true;
48366
48419
  }
48367
48420
  }, [initialState, callbacks]);
48368
- const isInStreamRef = useRef67(false);
48369
- const hasEverStreamedRef = useRef67(false);
48370
- const directModeFlagRef = useRef67(isDirectMode);
48371
- const sawDirectMessageRef = useRef67(false);
48372
- const directTeardownFiredRef = useRef67(false);
48421
+ const isInStreamRef = useRef66(false);
48422
+ const hasEverStreamedRef = useRef66(false);
48423
+ const directModeFlagRef = useRef66(isDirectMode);
48424
+ const sawDirectMessageRef = useRef66(false);
48425
+ const directTeardownFiredRef = useRef66(false);
48373
48426
  useEffect81(() => {
48374
48427
  directModeFlagRef.current = isDirectMode;
48375
48428
  }, [isDirectMode]);
48376
- const pendingEscalatedRef = useRef67(/* @__PURE__ */ new Map());
48429
+ const pendingEscalatedRef = useRef66(/* @__PURE__ */ new Map());
48377
48430
  const processChunk = useCallback47(
48378
48431
  (chunk) => {
48379
48432
  const action = parseChunkToAction(chunk);
@@ -48504,6 +48557,16 @@ function useRealtimeChunkProcessor(options) {
48504
48557
  explanation: escalatedData.explanation,
48505
48558
  approvalType: escalatedData.approvalType
48506
48559
  });
48560
+ const emitResolved = (segments) => {
48561
+ if (isInStreamRef.current) {
48562
+ emitSegments(segments);
48563
+ return;
48564
+ }
48565
+ const delta = segments.filter(
48566
+ (s) => s.type === "approval_request" && s.data.requestId === requestId || s.type === "approval_batch" && s.data.approvalRequestId === requestId
48567
+ );
48568
+ emitSegments(delta, { append: true });
48569
+ };
48507
48570
  if (escalatedData.toolCalls && escalatedData.toolCalls.length > 0) {
48508
48571
  if (batchApprovalsEnabled) {
48509
48572
  const segments = accumulator.addApprovalBatch(
@@ -48514,7 +48577,7 @@ function useRealtimeChunkProcessor(options) {
48514
48577
  void 0,
48515
48578
  resolvedByName
48516
48579
  );
48517
- emitSegments(segments);
48580
+ emitResolved(segments);
48518
48581
  } else {
48519
48582
  let segments = accumulator.getSegments();
48520
48583
  for (const call of escalatedData.toolCalls) {
@@ -48527,7 +48590,7 @@ function useRealtimeChunkProcessor(options) {
48527
48590
  status
48528
48591
  );
48529
48592
  }
48530
- emitSegments(segments);
48593
+ emitResolved(segments);
48531
48594
  }
48532
48595
  } else {
48533
48596
  const segments = accumulator.addApprovalRequest(
@@ -48537,7 +48600,7 @@ function useRealtimeChunkProcessor(options) {
48537
48600
  escalatedData.approvalType,
48538
48601
  status
48539
48602
  );
48540
- emitSegments(segments);
48603
+ emitResolved(segments);
48541
48604
  }
48542
48605
  } else {
48543
48606
  accumulator.updateApprovalStatus(requestId, status, resolvedByName);
@@ -48617,6 +48680,8 @@ function useRealtimeChunkProcessor(options) {
48617
48680
  hasInitializedWithData.current = false;
48618
48681
  sawDirectMessageRef.current = false;
48619
48682
  directTeardownFiredRef.current = false;
48683
+ isInStreamRef.current = false;
48684
+ hasEverStreamedRef.current = false;
48620
48685
  }, []);
48621
48686
  const updateApprovalStatus = useCallback47(
48622
48687
  (requestId, status, resolvedByName) => {
@@ -48762,7 +48827,7 @@ function useEmptyStateConfig(emptyStateUrl, options) {
48762
48827
  }
48763
48828
 
48764
48829
  // src/components/chat/hooks/use-chat-attachments.ts
48765
- import { useCallback as useCallback48, useMemo as useMemo41, useRef as useRef68, useState as useState110 } from "react";
48830
+ import { useCallback as useCallback48, useMemo as useMemo41, useRef as useRef67, useState as useState110 } from "react";
48766
48831
  import { fileTypeFromBlob } from "file-type";
48767
48832
  var CHAT_ATTACHMENTS_BUCKET = "chat-attachments";
48768
48833
  var CHAT_ATTACHMENTS_FOLDER = "chat";
@@ -48839,7 +48904,7 @@ function useChatAttachments() {
48839
48904
  const runtime = useRequiredChatRuntime();
48840
48905
  const uploadUrlEndpoint = runtime.endpoints.attachmentUploadUrl;
48841
48906
  const [attachments, setAttachments] = useState110([]);
48842
- const controllersRef = useRef68(/* @__PURE__ */ new Map());
48907
+ const controllersRef = useRef67(/* @__PURE__ */ new Map());
48843
48908
  const updateOne = useCallback48((id, patch) => {
48844
48909
  setAttachments((prev) => prev.map((a) => a.id === id ? { ...a, ...patch } : a));
48845
48910
  }, []);
@@ -48928,7 +48993,7 @@ function useChatAttachments() {
48928
48993
  },
48929
48994
  [uploadUrlEndpoint, updateOne]
48930
48995
  );
48931
- const attachmentsRef = useRef68([]);
48996
+ const attachmentsRef = useRef67([]);
48932
48997
  attachmentsRef.current = attachments;
48933
48998
  const addFiles = useCallback48(
48934
48999
  (files) => {
@@ -49005,13 +49070,13 @@ function useChatAttachments() {
49005
49070
  }
49006
49071
 
49007
49072
  // src/components/chat/hooks/use-chat-attachment-image-gallery.tsx
49008
- import { useCallback as useCallback49, useEffect as useEffect83, useRef as useRef69, useState as useState111 } from "react";
49073
+ import { useCallback as useCallback49, useEffect as useEffect83, useRef as useRef68, useState as useState111 } from "react";
49009
49074
  import { jsx as jsx359 } from "react/jsx-runtime";
49010
49075
  var CLOSED = { isOpen: false, images: [], initialIndex: 0 };
49011
49076
  function useChatAttachmentImageGallery() {
49012
49077
  const runtime = useRequiredChatRuntime();
49013
49078
  const viewUrlPrefix = runtime.endpoints.attachmentViewUrlPrefix;
49014
- const panelRef = useRef69(null);
49079
+ const panelRef = useRef68(null);
49015
49080
  const [state, setState] = useState111(CLOSED);
49016
49081
  const handleClose = useCallback49(() => setState(CLOSED), []);
49017
49082
  useEffect83(() => {
@@ -49115,10 +49180,10 @@ function useChatIdentity() {
49115
49180
  }
49116
49181
 
49117
49182
  // src/components/chat/hooks/use-close-on-navigation.ts
49118
- import { useEffect as useEffect85, useRef as useRef70 } from "react";
49183
+ import { useEffect as useEffect85, useRef as useRef69 } from "react";
49119
49184
  function useCloseOnNavigation(close, pathname) {
49120
- const prevPathnameRef = useRef70(null);
49121
- const initializedRef = useRef70(false);
49185
+ const prevPathnameRef = useRef69(null);
49186
+ const initializedRef = useRef69(false);
49122
49187
  useEffect85(() => {
49123
49188
  if (!initializedRef.current) {
49124
49189
  initializedRef.current = true;
@@ -49133,14 +49198,14 @@ function useCloseOnNavigation(close, pathname) {
49133
49198
  }
49134
49199
 
49135
49200
  // src/components/chat/hooks/use-chat.ts
49136
- import { useState as useState114, useCallback as useCallback51, useEffect as useEffect86, useRef as useRef72 } from "react";
49201
+ import { useState as useState114, useCallback as useCallback51, useEffect as useEffect86, useRef as useRef71 } from "react";
49137
49202
 
49138
49203
  // src/components/chat/hooks/use-sse.ts
49139
- import { useState as useState113, useCallback as useCallback50, useRef as useRef71 } from "react";
49204
+ import { useState as useState113, useCallback as useCallback50, useRef as useRef70 } from "react";
49140
49205
  function useSSE({ useMock = true, debugMode = false, streamFn } = {}) {
49141
49206
  const [isStreaming, setIsStreaming] = useState113(false);
49142
49207
  const [error, setError] = useState113(null);
49143
- const abortControllerRef = useRef71(null);
49208
+ const abortControllerRef = useRef70(null);
49144
49209
  const fallbackStream = useCallback50(async function* () {
49145
49210
  throw new Error(
49146
49211
  "[useSSE] No streamFn provided and `useMock: true` is no longer wired into the lib. Supply a `streamFn` (see `createDocStreamFn` in use-embedded-chat) or migrate the mock to your host code."
@@ -49208,8 +49273,8 @@ function useChat({
49208
49273
  } = {}) {
49209
49274
  const [messages, setMessages] = useState114(() => initialMessages ?? []);
49210
49275
  const [isTyping, setIsTyping] = useState114(false);
49211
- const currentAssistantSegmentsRef = useRef72([]);
49212
- const onMessagesChangeRef = useRef72(onMessagesChange);
49276
+ const currentAssistantSegmentsRef = useRef71([]);
49277
+ const onMessagesChangeRef = useRef71(onMessagesChange);
49213
49278
  onMessagesChangeRef.current = onMessagesChange;
49214
49279
  useEffect86(() => {
49215
49280
  onMessagesChangeRef.current?.(messages);
@@ -49500,7 +49565,7 @@ function useChat({
49500
49565
  }
49501
49566
 
49502
49567
  // src/components/chat/hooks/use-sse-chat-adapter.ts
49503
- import { useState as useState115, useEffect as useEffect87, useCallback as useCallback52, useMemo as useMemo42, useRef as useRef73 } from "react";
49568
+ import { useState as useState115, useEffect as useEffect87, useCallback as useCallback52, useMemo as useMemo42, useRef as useRef72 } from "react";
49504
49569
  function createEmptyTurnMeta() {
49505
49570
  return {
49506
49571
  provider: null,
@@ -49821,20 +49886,20 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
49821
49886
  const runtime = useRequiredChatRuntime();
49822
49887
  const source = runtime.source || DEFAULT_CHAT_SOURCE;
49823
49888
  const tableIdForDocumentType = options?.tableIdForDocumentType ?? defaultTableIdForDocumentType;
49824
- const persistedRef = useRef73(null);
49889
+ const persistedRef = useRef72(null);
49825
49890
  if (persistedRef.current === null) {
49826
49891
  pruneStaleChatStorage(source);
49827
49892
  persistedRef.current = loadPersistedChat(source) || { messages: [], sources: [], sendCount: 0 };
49828
49893
  }
49829
- const sourcesMapRef = useRef73(
49894
+ const sourcesMapRef = useRef72(
49830
49895
  new Map(persistedRef.current.sources)
49831
49896
  );
49832
- const refsMapRef = useRef73(
49897
+ const refsMapRef = useRef72(
49833
49898
  new Map(persistedRef.current.refs ?? [])
49834
49899
  );
49835
- const metaMapRef = useRef73(/* @__PURE__ */ new Map());
49836
- const messagesRef = useRef73(persistedRef.current.messages);
49837
- const sendCountRef = useRef73(persistedRef.current.sendCount);
49900
+ const metaMapRef = useRef72(/* @__PURE__ */ new Map());
49901
+ const messagesRef = useRef72(persistedRef.current.messages);
49902
+ const sendCountRef = useRef72(persistedRef.current.sendCount);
49838
49903
  const [streamingPhase, setStreamingPhase] = useState115("idle");
49839
49904
  const [metaTick, setMetaTick] = useState115(0);
49840
49905
  const bumpMetaTick = useCallback52(() => setMetaTick((t) => t + 1), []);
@@ -50108,7 +50173,7 @@ import {
50108
50173
  useCallback as useCallback53,
50109
50174
  useEffect as useEffect88,
50110
50175
  useMemo as useMemo43,
50111
- useRef as useRef74,
50176
+ useRef as useRef73,
50112
50177
  useState as useState116
50113
50178
  } from "react";
50114
50179
 
@@ -50147,7 +50212,15 @@ function processHistoricalMessages(messages, options = {}) {
50147
50212
  onReject,
50148
50213
  chatTypeFilter,
50149
50214
  approvalStatuses = {},
50150
- displayApprovalTypes
50215
+ // An omitted option means "display every approval type" — the original
50216
+ // history semantics. Deliberately NOT defaulted to the realtime
50217
+ // processor's ['CLIENT']: consumers that pass a wider list to their
50218
+ // realtime processor but omit it on the history path would silently lose
50219
+ // pending non-CLIENT approval cards on every reload/reconnect refetch
50220
+ // (they also ignore `escalatedApprovals`). Realtime/history parity is
50221
+ // opt-in: pass the same explicit list to both.
50222
+ displayApprovalTypes,
50223
+ batchApprovalsEnabled
50151
50224
  } = options;
50152
50225
  const processedMessages = [];
50153
50226
  const accumulator = createMessageSegmentAccumulator({ onApprove, onReject });
@@ -50212,7 +50285,13 @@ function processHistoricalMessages(messages, options = {}) {
50212
50285
  }
50213
50286
  lastAssistantId = msg.id;
50214
50287
  messageDataArray.forEach((data) => {
50215
- processMessageData(data, accumulator, approvalStatuses, { displayApprovalTypes }, escalatedApprovals);
50288
+ processMessageData(
50289
+ data,
50290
+ accumulator,
50291
+ approvalStatuses,
50292
+ { displayApprovalTypes, batchApprovalsEnabled },
50293
+ escalatedApprovals
50294
+ );
50216
50295
  });
50217
50296
  const nextMsg = messages[index + 1];
50218
50297
  const isLastMessage = index === messages.length - 1;
@@ -50436,7 +50515,7 @@ function extractErrorMessages(messages, options = {}) {
50436
50515
  return errorMessages;
50437
50516
  }
50438
50517
  function processHistoricalMessagesWithErrors(messages, options = {}) {
50439
- const { chatTypeFilter, assistantName = "Fae", assistantType = "fae", assistantAvatar, onApprove, onReject, approvalStatuses = {}, displayApprovalTypes } = options;
50518
+ const { chatTypeFilter, assistantName = "Fae", assistantType = "fae", assistantAvatar, onApprove, onReject, approvalStatuses = {}, displayApprovalTypes, batchApprovalsEnabled } = options;
50440
50519
  const processedMessages = [];
50441
50520
  const accumulator = createMessageSegmentAccumulator({ onApprove, onReject });
50442
50521
  const escalatedApprovals = /* @__PURE__ */ new Map();
@@ -50500,7 +50579,13 @@ function processHistoricalMessagesWithErrors(messages, options = {}) {
50500
50579
  }
50501
50580
  lastAssistantId = msg.id;
50502
50581
  messageDataArray.forEach((data) => {
50503
- processMessageData(data, accumulator, approvalStatuses, { displayApprovalTypes }, escalatedApprovals);
50582
+ processMessageData(
50583
+ data,
50584
+ accumulator,
50585
+ approvalStatuses,
50586
+ { displayApprovalTypes, batchApprovalsEnabled },
50587
+ escalatedApprovals
50588
+ );
50504
50589
  });
50505
50590
  const nextMsg = messages[index + 1];
50506
50591
  const isLastMessage = index === messages.length - 1;
@@ -50529,6 +50614,65 @@ function processHistoricalMessagesWithErrors(messages, options = {}) {
50529
50614
  };
50530
50615
  }
50531
50616
 
50617
+ // src/components/chat/utils/extract-incomplete-message-state.ts
50618
+ function extractIncompleteMessageState(lastMessage) {
50619
+ if (!lastMessage || lastMessage.role !== "assistant" || typeof lastMessage.content === "string") {
50620
+ return void 0;
50621
+ }
50622
+ const segments = lastMessage.content;
50623
+ const pendingApprovals = /* @__PURE__ */ new Map();
50624
+ const executingTools = /* @__PURE__ */ new Map();
50625
+ let hasIncompleteState = false;
50626
+ segments.forEach((segment) => {
50627
+ switch (segment.type) {
50628
+ case "tool_execution":
50629
+ if (segment.data.type === "EXECUTING_TOOL") {
50630
+ const toolKey = segment.data.toolExecutionRequestId || `${segment.data.integratedToolType}-${segment.data.toolFunction}`;
50631
+ executingTools.set(toolKey, {
50632
+ integratedToolType: segment.data.integratedToolType,
50633
+ toolFunction: segment.data.toolFunction,
50634
+ toolTitle: segment.data.toolTitle,
50635
+ parameters: segment.data.parameters
50636
+ });
50637
+ hasIncompleteState = true;
50638
+ }
50639
+ break;
50640
+ case "approval_request":
50641
+ if (segment.status === "pending" && segment.data.requestId) {
50642
+ pendingApprovals.set(segment.data.requestId, {
50643
+ command: segment.data.command,
50644
+ explanation: segment.data.explanation,
50645
+ approvalType: segment.data.approvalType || "CLIENT"
50646
+ });
50647
+ hasIncompleteState = true;
50648
+ }
50649
+ break;
50650
+ case "approval_batch": {
50651
+ const allDone = !!segment.data.executions && segment.data.toolCalls.every(
50652
+ (c) => segment.data.executions?.[c.toolExecutionRequestId]?.status === "done"
50653
+ );
50654
+ if (segment.status !== "rejected" && !allDone) {
50655
+ hasIncompleteState = true;
50656
+ }
50657
+ break;
50658
+ }
50659
+ case "context_compaction":
50660
+ if (segment.status === "started") {
50661
+ hasIncompleteState = true;
50662
+ }
50663
+ break;
50664
+ }
50665
+ });
50666
+ if (!hasIncompleteState) {
50667
+ return void 0;
50668
+ }
50669
+ return {
50670
+ existingSegments: segments,
50671
+ pendingApprovals: pendingApprovals.size > 0 ? pendingApprovals : void 0,
50672
+ executingTools: executingTools.size > 0 ? executingTools : void 0
50673
+ };
50674
+ }
50675
+
50532
50676
  // src/components/chat/hooks/use-nats-chat-adapter.ts
50533
50677
  function nextId(role) {
50534
50678
  return `${role}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
@@ -50551,6 +50695,110 @@ function updateTrailingAssistant(prev, segments) {
50551
50695
  { ...last, segments }
50552
50696
  ];
50553
50697
  }
50698
+ var CONTENT_DEDUP_WINDOW = 4;
50699
+ var SYSTEM_DEDUP_WINDOW = 10;
50700
+ function hasRecentMessage(prev, predicate, window2) {
50701
+ const start = Math.max(0, prev.length - window2);
50702
+ for (let i = prev.length - 1; i >= start; i--) {
50703
+ if (predicate(prev[i])) return true;
50704
+ }
50705
+ return false;
50706
+ }
50707
+ function appendToTrailingAssistant(prev, segments) {
50708
+ if (segments.length === 0) return prev;
50709
+ const last = prev[prev.length - 1];
50710
+ if (!last || last.role !== "assistant") {
50711
+ return [
50712
+ ...prev,
50713
+ { id: nextId("assistant"), role: "assistant", content: "", segments }
50714
+ ];
50715
+ }
50716
+ const merged = [...last.segments ?? []];
50717
+ for (const seg of segments) {
50718
+ const tail = merged[merged.length - 1];
50719
+ if (seg.type === "text" && tail?.type === "text") {
50720
+ merged[merged.length - 1] = { type: "text", text: tail.text + seg.text };
50721
+ } else if (seg.type === "thinking" && tail?.type === "thinking") {
50722
+ merged[merged.length - 1] = { type: "thinking", text: tail.text + seg.text };
50723
+ } else if (seg.type === "approval_batch") {
50724
+ const idx = merged.findIndex(
50725
+ (m) => m.type === "approval_batch" && m.data.approvalRequestId === seg.data.approvalRequestId
50726
+ );
50727
+ if (idx !== -1) merged[idx] = seg;
50728
+ else merged.push(seg);
50729
+ } else if (seg.type === "approval_request") {
50730
+ const idx = merged.findIndex(
50731
+ (m) => m.type === "approval_request" && m.data.requestId === seg.data.requestId && m.data.command === seg.data.command
50732
+ );
50733
+ if (idx !== -1) merged[idx] = seg;
50734
+ else merged.push(seg);
50735
+ } else {
50736
+ merged.push(seg);
50737
+ }
50738
+ }
50739
+ return [...prev.slice(0, -1), { ...last, segments: merged }];
50740
+ }
50741
+ function upsertTrailingCompaction(prev, segments) {
50742
+ const compaction = [...segments].reverse().find((s) => s.type === "context_compaction");
50743
+ if (!compaction) return prev;
50744
+ const last = prev[prev.length - 1];
50745
+ if (!last || last.role !== "assistant") {
50746
+ return [
50747
+ ...prev,
50748
+ { id: nextId("assistant"), role: "assistant", content: "", segments: [compaction] }
50749
+ ];
50750
+ }
50751
+ const existing = last.segments ?? [];
50752
+ const startedIdx = existing.map((s) => s.type === "context_compaction" && s.status === "started").lastIndexOf(true);
50753
+ const merged = startedIdx !== -1 ? existing.map((s, i) => i === startedIdx ? compaction : s) : [...existing, compaction];
50754
+ return [...prev.slice(0, -1), { ...last, segments: merged }];
50755
+ }
50756
+ function applyToolExecutionToMessages(prev, segment) {
50757
+ const toolData = segment.data;
50758
+ const execId = toolData.toolExecutionRequestId;
50759
+ for (let i = prev.length - 1; i >= 0; i--) {
50760
+ const message2 = prev[i];
50761
+ if (message2.role !== "assistant" || !message2.segments) continue;
50762
+ for (let j = message2.segments.length - 1; j >= 0; j--) {
50763
+ const seg = message2.segments[j];
50764
+ if (execId && seg.type === "approval_batch" && seg.data.toolCalls.some((c) => c.toolExecutionRequestId === execId)) {
50765
+ const prevExec = seg.data.executions?.[execId];
50766
+ if (toolData.type === "EXECUTING_TOOL" && prevExec?.status === "done") {
50767
+ return prev;
50768
+ }
50769
+ const nextExec = toolData.type === "EXECUTED_TOOL" ? { status: "done", result: toolData.result, success: toolData.success } : { status: "executing", result: prevExec?.result, success: prevExec?.success };
50770
+ const nextSegments = [...message2.segments];
50771
+ nextSegments[j] = {
50772
+ ...seg,
50773
+ data: { ...seg.data, executions: { ...seg.data.executions ?? {}, [execId]: nextExec } }
50774
+ };
50775
+ const next = [...prev];
50776
+ next[i] = { ...message2, segments: nextSegments };
50777
+ return next;
50778
+ }
50779
+ if (seg.type === "tool_execution") {
50780
+ const matches = execId ? seg.data.toolExecutionRequestId === execId : seg.data.type === "EXECUTING_TOOL" && seg.data.integratedToolType === toolData.integratedToolType && seg.data.toolFunction === toolData.toolFunction;
50781
+ if (!matches) continue;
50782
+ if (toolData.type === "EXECUTING_TOOL" && seg.data.type === "EXECUTED_TOOL") {
50783
+ return prev;
50784
+ }
50785
+ const nextSegments = [...message2.segments];
50786
+ nextSegments[j] = {
50787
+ type: "tool_execution",
50788
+ data: {
50789
+ ...toolData,
50790
+ toolTitle: toolData.toolTitle ?? seg.data.toolTitle,
50791
+ parameters: toolData.parameters || seg.data.parameters
50792
+ }
50793
+ };
50794
+ const next = [...prev];
50795
+ next[i] = { ...message2, segments: nextSegments };
50796
+ return next;
50797
+ }
50798
+ }
50799
+ }
50800
+ return appendToTrailingAssistant(prev, [segment]);
50801
+ }
50554
50802
  function mapProcessedToUnified(processed) {
50555
50803
  const out = [];
50556
50804
  for (const m of processed) {
@@ -50590,6 +50838,7 @@ function useNatsChatAdapter(config, options = {}) {
50590
50838
  fetchChunks,
50591
50839
  topics,
50592
50840
  batchApprovalsEnabled,
50841
+ displayApprovalTypes,
50593
50842
  fetchDialogs,
50594
50843
  fetchDialogMessages,
50595
50844
  createDialog: createDialogCallback,
@@ -50609,11 +50858,17 @@ function useNatsChatAdapter(config, options = {}) {
50609
50858
  const isManagedMode = fetchDialogs !== void 0;
50610
50859
  const [internalDialogId, setInternalDialogId] = useState116(null);
50611
50860
  const dialogId = isManagedMode ? internalDialogId : controlledDialogId !== void 0 ? controlledDialogId : null;
50861
+ const currentDialogIdRef = useRef73(dialogId);
50862
+ currentDialogIdRef.current = dialogId;
50612
50863
  const [messages, setMessages] = useState116([]);
50613
50864
  const [streamingPhase, setStreamingPhase] = useState116("idle");
50614
- const streamingPhaseRef = useRef74(streamingPhase);
50865
+ const streamingPhaseRef = useRef73(streamingPhase);
50615
50866
  streamingPhaseRef.current = streamingPhase;
50616
- const suppressAgentBusyRef = useRef74(false);
50867
+ const suppressAgentBusyRef = useRef73(0);
50868
+ const adoptTrailingAssistantRef = useRef73(false);
50869
+ const hasConnectedOnceRef = useRef73(false);
50870
+ const seenParticipantSeqsRef = useRef73(/* @__PURE__ */ new Set());
50871
+ const pendingEchoTextsRef = useRef73([]);
50617
50872
  const [approvalStatuses, setApprovalStatuses] = useState116({});
50618
50873
  const [dialogs, setDialogs] = useState116([]);
50619
50874
  const [dialogsNextCursor, setDialogsNextCursor] = useState116(null);
@@ -50666,9 +50921,9 @@ function useNatsChatAdapter(config, options = {}) {
50666
50921
  },
50667
50922
  [rejectRequestCallback]
50668
50923
  );
50669
- const handleApproveRef = useRef74(handleApprove);
50924
+ const handleApproveRef = useRef73(handleApprove);
50670
50925
  handleApproveRef.current = handleApprove;
50671
- const handleRejectRef = useRef74(handleReject);
50926
+ const handleRejectRef = useRef73(handleReject);
50672
50927
  handleRejectRef.current = handleReject;
50673
50928
  const accumApprove = useCallback53((requestId) => {
50674
50929
  if (!requestId) return;
@@ -50678,18 +50933,40 @@ function useNatsChatAdapter(config, options = {}) {
50678
50933
  if (!requestId) return;
50679
50934
  return handleRejectRef.current(requestId);
50680
50935
  }, []);
50681
- const callbacksRef = useRef74({
50682
- onSegmentsUpdate: (segments) => {
50936
+ const callbacksRef = useRef73({
50937
+ onSegmentsUpdate: (segments, meta) => {
50938
+ if (meta?.append && meta.isCompacting) {
50939
+ setMessages((prev) => upsertTrailingCompaction(prev, segments));
50940
+ return;
50941
+ }
50942
+ if (meta?.append) {
50943
+ setMessages((prev) => appendToTrailingAssistant(prev, segments));
50944
+ return;
50945
+ }
50683
50946
  setMessages((prev) => updateTrailingAssistant(prev, segments));
50684
50947
  },
50685
- onStreamStart: () => setStreamingPhase("streaming"),
50948
+ onStreamStart: () => {
50949
+ setStreamingPhase("streaming");
50950
+ const adoptTail = adoptTrailingAssistantRef.current;
50951
+ adoptTrailingAssistantRef.current = false;
50952
+ setMessages((prev) => {
50953
+ const last = prev[prev.length - 1];
50954
+ if (!last || last.role !== "assistant" || adoptTail) return prev;
50955
+ const hasContent = (last.segments?.length ?? 0) > 0 || last.content !== "";
50956
+ if (!hasContent) return prev;
50957
+ return [
50958
+ ...prev,
50959
+ { id: nextId("assistant"), role: "assistant", content: "", segments: [] }
50960
+ ];
50961
+ });
50962
+ },
50686
50963
  onStreamEnd: () => setStreamingPhase("idle"),
50687
50964
  // Agent is executing (approved) commands outside an open stream — keep
50688
50965
  // the composer locked exactly like the in-stream phases. An open stream
50689
50966
  // keeps ownership: only 'idle' upgrades to 'thinking'. Suppressed during
50690
50967
  // initial catchup so a replayed dead tail can't lock a finished dialog.
50691
50968
  onAgentBusy: () => {
50692
- if (suppressAgentBusyRef.current) return;
50969
+ if (suppressAgentBusyRef.current > 0) return;
50693
50970
  setStreamingPhase((p) => p === "idle" ? "thinking" : p);
50694
50971
  },
50695
50972
  // Terminal turn failures can arrive without a MESSAGE_END; unlock the
@@ -50704,33 +50981,177 @@ function useNatsChatAdapter(config, options = {}) {
50704
50981
  provider: meta.providerName || null,
50705
50982
  modelLabel: meta.modelDisplayName || meta.modelName || null,
50706
50983
  contextWindowMaxTokens: meta.contextWindow || null
50707
- })
50984
+ }),
50985
+ // Post-MESSAGE_END tool chunks (approved commands executing after the
50986
+ // approval bubble, async batch results). Routed through the cross-message
50987
+ // updater — the accumulator was reset at MESSAGE_END, so the old
50988
+ // fallthrough replaced the whole trailing bubble with one tool segment.
50989
+ onToolExecuted: (segment) => {
50990
+ setMessages((prev) => applyToolExecutionToMessages(prev, segment));
50991
+ },
50992
+ // Cross-message approval status flip. Wiring this also makes the
50993
+ // processor skip its cumulative re-emit for resolved approvals — which,
50994
+ // post-MESSAGE_END, was an empty array that blanked the trailing bubble.
50995
+ onApprovalResolved: (requestId, status, _approvalType, resolvedByName) => {
50996
+ setMessages((prev) => {
50997
+ let changed = false;
50998
+ const next = prev.map((m) => {
50999
+ if (m.role !== "assistant" || !m.segments) return m;
51000
+ let msgChanged = false;
51001
+ const segs = m.segments.map((s) => {
51002
+ if (s.type === "approval_request" && s.data.requestId === requestId && s.status !== status) {
51003
+ msgChanged = true;
51004
+ return { ...s, status };
51005
+ }
51006
+ if (s.type === "approval_batch" && s.data.approvalRequestId === requestId) {
51007
+ const nextResolvedBy = resolvedByName ?? s.resolvedByName;
51008
+ if (s.status === status && nextResolvedBy === s.resolvedByName) return s;
51009
+ msgChanged = true;
51010
+ return { ...s, status, resolvedByName: nextResolvedBy };
51011
+ }
51012
+ return s;
51013
+ });
51014
+ if (!msgChanged) return m;
51015
+ changed = true;
51016
+ return { ...m, segments: segs };
51017
+ });
51018
+ return changed ? next : prev;
51019
+ });
51020
+ setApprovalStatuses(
51021
+ (prev) => prev[requestId] === status ? prev : { ...prev, [requestId]: status }
51022
+ );
51023
+ },
51024
+ // MESSAGE_REQUEST echo — a user message from THIS or another session.
51025
+ onUserMessage: (text, meta) => {
51026
+ if (!text) return;
51027
+ const seq = meta?.streamSeq;
51028
+ if (typeof seq === "number") {
51029
+ if (seenParticipantSeqsRef.current.has(seq)) return;
51030
+ seenParticipantSeqsRef.current.add(seq);
51031
+ }
51032
+ if (meta?.ownerType !== "ADMIN") {
51033
+ const echoIdx = pendingEchoTextsRef.current.indexOf(text);
51034
+ if (echoIdx !== -1) {
51035
+ pendingEchoTextsRef.current.splice(echoIdx, 1);
51036
+ return;
51037
+ }
51038
+ }
51039
+ const authorType = meta?.ownerType === "ADMIN" ? "admin" : "user";
51040
+ setMessages((prev) => {
51041
+ if (typeof seq !== "number" && hasRecentMessage(
51042
+ prev,
51043
+ (m) => m.role === "user" && (m.authorType ?? "user") === authorType && m.content === text,
51044
+ CONTENT_DEDUP_WINDOW
51045
+ )) {
51046
+ return prev;
51047
+ }
51048
+ return [
51049
+ ...prev,
51050
+ {
51051
+ id: nextId("user"),
51052
+ role: "user",
51053
+ content: text,
51054
+ ...meta?.displayName ? { name: meta.displayName } : {},
51055
+ authorType,
51056
+ ...meta?.contextItems && meta.contextItems.length > 0 ? {
51057
+ contextItems: meta.contextItems.map((ci) => ({
51058
+ type: ci.type,
51059
+ id: ci.id,
51060
+ label: ci.label ?? ci.id
51061
+ }))
51062
+ } : {}
51063
+ }
51064
+ ];
51065
+ });
51066
+ },
51067
+ // Technician / admin direct message into the dialog.
51068
+ onDirectMessage: (text, meta) => {
51069
+ if (!text) return;
51070
+ const seq = meta?.streamSeq;
51071
+ if (typeof seq === "number") {
51072
+ if (seenParticipantSeqsRef.current.has(seq)) return;
51073
+ seenParticipantSeqsRef.current.add(seq);
51074
+ }
51075
+ setMessages((prev) => {
51076
+ if (typeof seq !== "number" && hasRecentMessage(
51077
+ prev,
51078
+ (m) => m.role === "user" && m.authorType === "admin" && m.content === text,
51079
+ CONTENT_DEDUP_WINDOW
51080
+ )) {
51081
+ return prev;
51082
+ }
51083
+ return [
51084
+ ...prev,
51085
+ {
51086
+ id: `direct-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
51087
+ role: "user",
51088
+ content: text,
51089
+ name: meta?.displayName ?? "Admin",
51090
+ authorType: "admin"
51091
+ }
51092
+ ];
51093
+ });
51094
+ },
51095
+ // System notice — rendered as a name-only row (same shape the history
51096
+ // processor produces via `pushStandaloneMessages`).
51097
+ onSystemMessage: (text, meta) => {
51098
+ if (!text) return;
51099
+ const seq = meta?.streamSeq;
51100
+ if (typeof seq === "number") {
51101
+ if (seenParticipantSeqsRef.current.has(seq)) return;
51102
+ seenParticipantSeqsRef.current.add(seq);
51103
+ }
51104
+ setMessages((prev) => {
51105
+ if (typeof seq !== "number" && hasRecentMessage(prev, (m) => m.authorType === "system" && m.name === text, SYSTEM_DEDUP_WINDOW)) {
51106
+ return prev;
51107
+ }
51108
+ return [
51109
+ ...prev,
51110
+ {
51111
+ id: `system-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
51112
+ role: "user",
51113
+ content: "",
51114
+ name: text,
51115
+ authorType: "system"
51116
+ }
51117
+ ];
51118
+ });
51119
+ }
50708
51120
  });
50709
51121
  const { processChunk, reset: resetAccumulator } = useRealtimeChunkProcessor({
50710
51122
  callbacks: {
50711
- onSegmentsUpdate: (segments) => callbacksRef.current.onSegmentsUpdate(segments),
51123
+ onSegmentsUpdate: (segments, meta) => callbacksRef.current.onSegmentsUpdate(segments, meta),
50712
51124
  onStreamStart: () => callbacksRef.current.onStreamStart(),
50713
51125
  onStreamEnd: () => callbacksRef.current.onStreamEnd(),
50714
51126
  onAgentBusy: () => callbacksRef.current.onAgentBusy(),
50715
51127
  onError: () => callbacksRef.current.onError(),
50716
51128
  onTokenUsage: (data) => callbacksRef.current.onTokenUsage(data),
50717
51129
  onMetadata: (meta) => callbacksRef.current.onMetadata(meta),
51130
+ onToolExecuted: (segment) => callbacksRef.current.onToolExecuted(segment),
51131
+ onApprovalResolved: (requestId, status, approvalType, resolvedByName) => callbacksRef.current.onApprovalResolved(requestId, status, approvalType, resolvedByName),
51132
+ onUserMessage: (text, meta) => callbacksRef.current.onUserMessage(text, meta),
51133
+ onDirectMessage: (text, meta) => callbacksRef.current.onDirectMessage(text, meta),
51134
+ onSystemMessage: (text, meta) => callbacksRef.current.onSystemMessage(text, meta),
50718
51135
  onApprove: accumApprove,
50719
51136
  onReject: accumReject
50720
51137
  },
50721
- batchApprovalsEnabled
51138
+ batchApprovalsEnabled,
51139
+ approvalStatuses,
51140
+ ...displayApprovalTypes ? { displayApprovalTypes } : {}
50722
51141
  });
50723
51142
  const {
50724
51143
  processChunk: catchupProcessChunk,
50725
51144
  catchUpChunks,
50726
51145
  startInitialBuffering,
50727
- resetChunkTracking
51146
+ resetChunkTracking,
51147
+ resetAndCatchUp,
51148
+ isBufferingActive
50728
51149
  } = useChunkCatchup({
50729
51150
  dialogId: active ? dialogId : null,
50730
51151
  onChunkReceived: (chunk) => processChunk(chunk),
50731
51152
  fetchChunks
50732
51153
  });
50733
- const historyLoadSeqRef = useRef74(0);
51154
+ const historyLoadSeqRef = useRef73(0);
50734
51155
  const loadDialogHistory = useCallback53(
50735
51156
  async (id, cursor) => {
50736
51157
  if (!fetchDialogMessages) return;
@@ -50753,11 +51174,13 @@ function useNatsChatAdapter(config, options = {}) {
50753
51174
  onApprove: accumApprove,
50754
51175
  onReject: accumReject,
50755
51176
  approvalStatuses,
50756
- batchApprovalsEnabled
51177
+ batchApprovalsEnabled,
51178
+ ...displayApprovalTypes ? { displayApprovalTypes } : {}
50757
51179
  }
50758
51180
  );
50759
51181
  const unified = mapProcessedToUnified(rawProcessed);
50760
51182
  if (cursor === void 0) {
51183
+ adoptTrailingAssistantRef.current = isBufferingActive() && extractIncompleteMessageState(rawProcessed[rawProcessed.length - 1]) !== void 0;
50761
51184
  setMessages(unified);
50762
51185
  } else {
50763
51186
  setMessages((prev) => [...unified, ...prev]);
@@ -50781,16 +51204,21 @@ function useNatsChatAdapter(config, options = {}) {
50781
51204
  chatTypeFilter,
50782
51205
  approvalStatuses,
50783
51206
  batchApprovalsEnabled,
51207
+ displayApprovalTypes,
50784
51208
  accumApprove,
50785
- accumReject
51209
+ accumReject,
51210
+ isBufferingActive
50786
51211
  ]
50787
51212
  );
50788
- const prevDialogIdRef = useRef74(void 0);
51213
+ const prevDialogIdRef = useRef73(void 0);
50789
51214
  useEffect88(() => {
50790
51215
  if (prevDialogIdRef.current === dialogId) return;
50791
51216
  prevDialogIdRef.current = dialogId;
50792
51217
  historyLoadSeqRef.current += 1;
50793
51218
  resetAccumulator();
51219
+ adoptTrailingAssistantRef.current = false;
51220
+ seenParticipantSeqsRef.current.clear();
51221
+ pendingEchoTextsRef.current = [];
50794
51222
  setMessages([]);
50795
51223
  setMessagesNextCursor(null);
50796
51224
  setDialogTokenUsage(null);
@@ -50802,13 +51230,16 @@ function useNatsChatAdapter(config, options = {}) {
50802
51230
  }, [active, dialogId, loadDialogHistory, resetAccumulator]);
50803
51231
  useEffect88(() => {
50804
51232
  if (!active || !dialogId) return;
50805
- suppressAgentBusyRef.current = true;
51233
+ suppressAgentBusyRef.current += 1;
50806
51234
  resetChunkTracking();
50807
51235
  startInitialBuffering();
50808
51236
  catchUpChunks().catch((err) => {
50809
51237
  console.error("[useNatsChatAdapter] initial catchup failed:", err);
50810
51238
  }).finally(() => {
50811
- suppressAgentBusyRef.current = false;
51239
+ suppressAgentBusyRef.current = Math.max(0, suppressAgentBusyRef.current - 1);
51240
+ if (dialogId === currentDialogIdRef.current) {
51241
+ adoptTrailingAssistantRef.current = false;
51242
+ }
50812
51243
  });
50813
51244
  }, [active, dialogId, resetChunkTracking, startInitialBuffering, catchUpChunks]);
50814
51245
  useNatsDialogSubscription({
@@ -50823,6 +51254,30 @@ function useNatsChatAdapter(config, options = {}) {
50823
51254
  onEvent: (payload, messageType) => {
50824
51255
  catchupProcessChunk(payload, messageType);
50825
51256
  setConnectionState("connected");
51257
+ },
51258
+ onConnect: () => {
51259
+ if (!hasConnectedOnceRef.current) {
51260
+ hasConnectedOnceRef.current = true;
51261
+ return;
51262
+ }
51263
+ suppressAgentBusyRef.current += 1;
51264
+ startInitialBuffering();
51265
+ void (async () => {
51266
+ try {
51267
+ if (dialogId && fetchDialogMessages) {
51268
+ await loadDialogHistory(dialogId);
51269
+ }
51270
+ if (dialogId !== currentDialogIdRef.current) return;
51271
+ await resetAndCatchUp();
51272
+ } catch (err) {
51273
+ console.error("[useNatsChatAdapter] reconnect catchup failed:", err);
51274
+ } finally {
51275
+ suppressAgentBusyRef.current = Math.max(0, suppressAgentBusyRef.current - 1);
51276
+ if (dialogId === currentDialogIdRef.current) {
51277
+ adoptTrailingAssistantRef.current = false;
51278
+ }
51279
+ }
51280
+ })();
50826
51281
  }
50827
51282
  });
50828
51283
  useEffect88(() => {
@@ -50832,7 +51287,7 @@ function useNatsChatAdapter(config, options = {}) {
50832
51287
  }
50833
51288
  setConnectionState("connecting");
50834
51289
  }, [active, dialogId]);
50835
- const initialDialogsLoadedRef = useRef74(false);
51290
+ const initialDialogsLoadedRef = useRef73(false);
50836
51291
  const loadDialogsPage = useCallback53(
50837
51292
  async (cursor) => {
50838
51293
  if (!fetchDialogs) return;
@@ -50874,6 +51329,8 @@ function useNatsChatAdapter(config, options = {}) {
50874
51329
  const sendMessage = useCallback53(
50875
51330
  async (text, sendOptions) => {
50876
51331
  const hidden = sendOptions?.hidden ?? false;
51332
+ pendingEchoTextsRef.current.push(text);
51333
+ if (pendingEchoTextsRef.current.length > 5) pendingEchoTextsRef.current.shift();
50877
51334
  setMessages((prev) => [
50878
51335
  ...prev,
50879
51336
  {
@@ -51105,7 +51562,7 @@ function useNatsChatAdapter(config, options = {}) {
51105
51562
  }
51106
51563
 
51107
51564
  // src/components/chat/hooks/use-unified-chat.ts
51108
- import { useCallback as useCallback54, useMemo as useMemo44, useRef as useRef75 } from "react";
51565
+ import { useCallback as useCallback54, useMemo as useMemo44, useRef as useRef74 } from "react";
51109
51566
  var EMPTY_SSE_OPTIONS = {};
51110
51567
  function createDisabledNatsConfig() {
51111
51568
  return {
@@ -51120,7 +51577,7 @@ function createDisabledNatsConfig() {
51120
51577
  }
51121
51578
  function useUnifiedChat(options) {
51122
51579
  const { modes, activeMode, mingoStateOverride } = options;
51123
- const disabledNatsRef = useRef75(null);
51580
+ const disabledNatsRef = useRef74(null);
51124
51581
  if (disabledNatsRef.current === null) {
51125
51582
  disabledNatsRef.current = createDisabledNatsConfig();
51126
51583
  }
@@ -51134,7 +51591,7 @@ function useUnifiedChat(options) {
51134
51591
  { active: natsActive }
51135
51592
  );
51136
51593
  const activeState = activeMode === "guide" ? sseState : mingoStateOverride ?? natsState;
51137
- const activeStateRef = useRef75(activeState);
51594
+ const activeStateRef = useRef74(activeState);
51138
51595
  activeStateRef.current = activeState;
51139
51596
  const stopMessage = useCallback54(() => activeStateRef.current.stopMessage(), []);
51140
51597
  const clearMessages = useCallback54(
@@ -51254,65 +51711,6 @@ function useUnifiedChat(options) {
51254
51711
  );
51255
51712
  }
51256
51713
 
51257
- // src/components/chat/utils/extract-incomplete-message-state.ts
51258
- function extractIncompleteMessageState(lastMessage) {
51259
- if (!lastMessage || lastMessage.role !== "assistant" || typeof lastMessage.content === "string") {
51260
- return void 0;
51261
- }
51262
- const segments = lastMessage.content;
51263
- const pendingApprovals = /* @__PURE__ */ new Map();
51264
- const executingTools = /* @__PURE__ */ new Map();
51265
- let hasIncompleteState = false;
51266
- segments.forEach((segment) => {
51267
- switch (segment.type) {
51268
- case "tool_execution":
51269
- if (segment.data.type === "EXECUTING_TOOL") {
51270
- const toolKey = segment.data.toolExecutionRequestId || `${segment.data.integratedToolType}-${segment.data.toolFunction}`;
51271
- executingTools.set(toolKey, {
51272
- integratedToolType: segment.data.integratedToolType,
51273
- toolFunction: segment.data.toolFunction,
51274
- toolTitle: segment.data.toolTitle,
51275
- parameters: segment.data.parameters
51276
- });
51277
- hasIncompleteState = true;
51278
- }
51279
- break;
51280
- case "approval_request":
51281
- if (segment.status === "pending" && segment.data.requestId) {
51282
- pendingApprovals.set(segment.data.requestId, {
51283
- command: segment.data.command,
51284
- explanation: segment.data.explanation,
51285
- approvalType: segment.data.approvalType || "CLIENT"
51286
- });
51287
- hasIncompleteState = true;
51288
- }
51289
- break;
51290
- case "approval_batch": {
51291
- const allDone = !!segment.data.executions && segment.data.toolCalls.every(
51292
- (c) => segment.data.executions?.[c.toolExecutionRequestId]?.status === "done"
51293
- );
51294
- if (segment.status !== "rejected" && !allDone) {
51295
- hasIncompleteState = true;
51296
- }
51297
- break;
51298
- }
51299
- case "context_compaction":
51300
- if (segment.status === "started") {
51301
- hasIncompleteState = true;
51302
- }
51303
- break;
51304
- }
51305
- });
51306
- if (!hasIncompleteState) {
51307
- return void 0;
51308
- }
51309
- return {
51310
- existingSegments: segments,
51311
- pendingApprovals: pendingApprovals.size > 0 ? pendingApprovals : void 0,
51312
- executingTools: executingTools.size > 0 ? executingTools : void 0
51313
- };
51314
- }
51315
-
51316
51714
  // src/components/chat/utils/history-merge.ts
51317
51715
  var SYNTHETIC_REALTIME_ID_PREFIXES = ["assistant-", "user-", "direct-", "system-", "error-"];
51318
51716
  function isSyntheticRealtimeId(id) {
@@ -51503,7 +51901,7 @@ function buildStreamFrames(messages) {
51503
51901
 
51504
51902
  // src/components/chat/embeddable-chat.tsx
51505
51903
  init_cn();
51506
- import { useCallback as useCallback56, useEffect as useEffect89, useMemo as useMemo46, useRef as useRef77, useState as useState118 } from "react";
51904
+ import { useCallback as useCallback56, useEffect as useEffect89, useMemo as useMemo46, useRef as useRef76, useState as useState118 } from "react";
51507
51905
  import * as DialogPrimitive4 from "@radix-ui/react-dialog";
51508
51906
  import { usePreventScroll as usePreventScroll6 } from "@react-aria/overlays";
51509
51907
  import { isIOS } from "@react-aria/utils";
@@ -51584,7 +51982,7 @@ init_button2();
51584
51982
  import { FileText as FileText8, MessageSquare as MessageSquare3 } from "lucide-react";
51585
51983
 
51586
51984
  // src/components/chat/hooks/use-chat-dialog-manager.ts
51587
- import { useCallback as useCallback55, useMemo as useMemo45, useRef as useRef76, useState as useState117 } from "react";
51985
+ import { useCallback as useCallback55, useMemo as useMemo45, useRef as useRef75, useState as useState117 } from "react";
51588
51986
  function useChatDialogManager({
51589
51987
  dialogs,
51590
51988
  activeDialogId,
@@ -51624,7 +52022,7 @@ function useChatDialogManager({
51624
52022
  const [archivedCursor, setArchivedCursor] = useState117(null);
51625
52023
  const [archivedLoading, setArchivedLoading] = useState117(false);
51626
52024
  const [archivedPending, setArchivedPending] = useState117(false);
51627
- const archivedRequestIdRef = useRef76(0);
52025
+ const archivedRequestIdRef = useRef75(0);
51628
52026
  const loadArchivedPage = useCallback55(
51629
52027
  async (cursor) => {
51630
52028
  if (!fetchArchivedDialogs) return;
@@ -52121,7 +52519,7 @@ function EmbeddableChatInner({
52121
52519
  return !window.matchMedia("(pointer: coarse)").matches;
52122
52520
  });
52123
52521
  usePreventScroll6({ isDisabled: !isOpen || shellLess });
52124
- const navigatingAwayRef = useRef77(false);
52522
+ const navigatingAwayRef = useRef76(false);
52125
52523
  useEffect89(() => {
52126
52524
  if (!isOpen) return;
52127
52525
  if (shellLess) return;
@@ -52148,7 +52546,7 @@ function EmbeddableChatInner({
52148
52546
  window.scrollTo(0, scrollY);
52149
52547
  };
52150
52548
  }, [isOpen, shellLess]);
52151
- const chatInputRef = useRef77(null);
52549
+ const chatInputRef = useRef76(null);
52152
52550
  const [quickActionPreview, setQuickActionPreview] = useState118(null);
52153
52551
  const slashCommandsProp = useMemo46(
52154
52552
  () => ({
@@ -52252,7 +52650,7 @@ function EmbeddableChatInner({
52252
52650
  hasMoreMessages,
52253
52651
  loadMoreMessages
52254
52652
  } = useUnifiedChat({ modes: effectiveModes, activeMode, mingoStateOverride: mingoState });
52255
- const guidePromptSentRef = useRef77(false);
52653
+ const guidePromptSentRef = useRef76(false);
52256
52654
  useEffect89(() => {
52257
52655
  if (!guidePendingPrompt) {
52258
52656
  guidePromptSentRef.current = false;
@@ -52277,11 +52675,11 @@ function EmbeddableChatInner({
52277
52675
  const [contextItems, setContextItems] = useState118([]);
52278
52676
  const [contextPickerOpen, setContextPickerOpen] = useState118(false);
52279
52677
  const [mentionQuery, setMentionQuery] = useState118(null);
52280
- const mentionActiveRef = useRef77(false);
52678
+ const mentionActiveRef = useRef76(false);
52281
52679
  useEffect89(() => {
52282
52680
  mentionActiveRef.current = mentionQuery !== null;
52283
52681
  }, [mentionQuery]);
52284
- const mentionKeysRef = useRef77(/* @__PURE__ */ new Set());
52682
+ const mentionKeysRef = useRef76(/* @__PURE__ */ new Set());
52285
52683
  useEffect89(() => {
52286
52684
  setContextItems([]);
52287
52685
  setMentionQuery(null);
@@ -52378,7 +52776,7 @@ function EmbeddableChatInner({
52378
52776
  () => effectiveAssistantIcon ? /* @__PURE__ */ jsx362(EntityIcon, { icon: effectiveAssistantIcon, size: 24 }) : /* @__PURE__ */ jsx362(MingoIcon, { className: "h-6 w-6", cornerColor: "var(--ods-flamingo-cyan-base)" }),
52379
52777
  [effectiveAssistantIcon]
52380
52778
  );
52381
- const timestampCacheRef = useRef77(/* @__PURE__ */ new Map());
52779
+ const timestampCacheRef = useRef76(/* @__PURE__ */ new Map());
52382
52780
  const guideUserName = activeMode === "guide" ? [identityUser?.firstName, identityUser?.lastName].filter(Boolean).join(" ").trim() || identityUser?.name?.trim() || void 0 : void 0;
52383
52781
  const guideUserAvatar = activeMode === "guide" ? identityUser?.avatarUrl?.trim() || void 0 : void 0;
52384
52782
  const messages = useMemo46(() => {
@@ -52576,7 +52974,7 @@ function EmbeddableChatInner({
52576
52974
  }, [lastAssistantMsg, chatLoading]);
52577
52975
  const [portalHost, setPortalHost] = useState118(null);
52578
52976
  const [panelWidth, setPanelWidth] = useState118(0);
52579
- const panelMeasureRef = useRef77(null);
52977
+ const panelMeasureRef = useRef76(null);
52580
52978
  useEffect89(() => {
52581
52979
  const el = panelMeasureRef.current;
52582
52980
  if (!el || typeof ResizeObserver === "undefined") return;
@@ -53697,11 +54095,14 @@ export {
53697
54095
  processHistoricalMessages,
53698
54096
  extractErrorMessages,
53699
54097
  processHistoricalMessagesWithErrors,
54098
+ extractIncompleteMessageState,
54099
+ appendToTrailingAssistant,
54100
+ upsertTrailingCompaction,
54101
+ applyToolExecutionToMessages,
53700
54102
  mapProcessedToUnified,
53701
54103
  historicalToUnified,
53702
54104
  useNatsChatAdapter,
53703
54105
  useUnifiedChat,
53704
- extractIncompleteMessageState,
53705
54106
  SYNTHETIC_REALTIME_ID_PREFIXES,
53706
54107
  flattenMessagePagesChronological,
53707
54108
  maxPersistedStreamSeq,
@@ -54118,4 +54519,4 @@ export {
54118
54519
  LogsList,
54119
54520
  assets
54120
54521
  };
54121
- //# sourceMappingURL=chunk-NDWIFCLS.js.map
54522
+ //# sourceMappingURL=chunk-MAB4TQCO.js.map