@flamingo-stack/openframe-frontend-core 0.0.429 → 0.0.430

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 (108) hide show
  1. package/dist/{chunk-GMR5AA3C.js → chunk-2ELINEWQ.js} +2 -2
  2. package/dist/{chunk-YGITDP6O.cjs → chunk-374KFDET.cjs} +31 -31
  3. package/dist/{chunk-YGITDP6O.cjs.map → chunk-374KFDET.cjs.map} +1 -1
  4. package/dist/{chunk-4VODJPTB.js → chunk-3AWPRVFM.js} +2 -2
  5. package/dist/{chunk-RTOVYU4D.js → chunk-3OKVH6FW.js} +4 -4
  6. package/dist/{chunk-2WJ25MTA.js → chunk-3XWBE3SM.js} +4 -4
  7. package/dist/{chunk-TJ4HJ3KX.js → chunk-67LZDLIO.js} +2 -2
  8. package/dist/{chunk-7PA4B6SD.js → chunk-A6JKKKIF.js} +4 -4
  9. package/dist/{chunk-KHKB5RY2.js → chunk-AY5TBDWZ.js} +2 -2
  10. package/dist/{chunk-CRGH6TV6.cjs → chunk-CJOFXDTK.cjs} +26 -26
  11. package/dist/{chunk-CRGH6TV6.cjs.map → chunk-CJOFXDTK.cjs.map} +1 -1
  12. package/dist/{chunk-B3Y47C2U.cjs → chunk-CTY37UUO.cjs} +59 -59
  13. package/dist/{chunk-B3Y47C2U.cjs.map → chunk-CTY37UUO.cjs.map} +1 -1
  14. package/dist/{chunk-OLGFIDZY.cjs → chunk-D4K53CES.cjs} +26 -26
  15. package/dist/{chunk-OLGFIDZY.cjs.map → chunk-D4K53CES.cjs.map} +1 -1
  16. package/dist/{chunk-WXKFFVGC.cjs → chunk-FL4IOCYH.cjs} +5 -5
  17. package/dist/{chunk-WXKFFVGC.cjs.map → chunk-FL4IOCYH.cjs.map} +1 -1
  18. package/dist/{chunk-7MJTM6QT.cjs → chunk-FYMD7CCA.cjs} +7 -7
  19. package/dist/{chunk-7MJTM6QT.cjs.map → chunk-FYMD7CCA.cjs.map} +1 -1
  20. package/dist/{chunk-Y2TW664W.js → chunk-IMOJWQDR.js} +4 -4
  21. package/dist/{chunk-2LJA3ABH.cjs → chunk-KDVGC6EG.cjs} +37 -37
  22. package/dist/{chunk-2LJA3ABH.cjs.map → chunk-KDVGC6EG.cjs.map} +1 -1
  23. package/dist/{chunk-NYISC4Z3.js → chunk-NZBQGODM.js} +2 -2
  24. package/dist/{chunk-XDBD6BJN.cjs → chunk-PP5KNHMK.cjs} +318 -215
  25. package/dist/chunk-PP5KNHMK.cjs.map +1 -0
  26. package/dist/{chunk-E4PKZNR7.cjs → chunk-Q7SYPXUX.cjs} +11 -11
  27. package/dist/{chunk-E4PKZNR7.cjs.map → chunk-Q7SYPXUX.cjs.map} +1 -1
  28. package/dist/{chunk-MAYEJ3NY.js → chunk-S7UXICHB.js} +2 -2
  29. package/dist/{chunk-B3FBMRHQ.js → chunk-TDITU4KW.js} +2 -2
  30. package/dist/{chunk-62L7S7HQ.js → chunk-TYANQCZA.js} +269 -166
  31. package/dist/chunk-TYANQCZA.js.map +1 -0
  32. package/dist/{chunk-BN3V465H.cjs → chunk-WQN4B6CM.cjs} +15 -15
  33. package/dist/{chunk-BN3V465H.cjs.map → chunk-WQN4B6CM.cjs.map} +1 -1
  34. package/dist/{chunk-CCL6JEMS.cjs → chunk-WQR7H56P.cjs} +62 -62
  35. package/dist/{chunk-CCL6JEMS.cjs.map → chunk-WQR7H56P.cjs.map} +1 -1
  36. package/dist/{chunk-GGJUXN6Z.cjs → chunk-ZUP2ZKS6.cjs} +9 -9
  37. package/dist/{chunk-GGJUXN6Z.cjs.map → chunk-ZUP2ZKS6.cjs.map} +1 -1
  38. package/dist/components/case-studies/index.cjs +8 -8
  39. package/dist/components/case-studies/index.js +2 -2
  40. package/dist/components/chat/hooks/index.d.ts +1 -0
  41. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  42. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +10 -1
  43. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  44. package/dist/components/chat/hooks/use-scripted-stream.d.ts +3 -0
  45. package/dist/components/chat/hooks/use-scripted-stream.d.ts.map +1 -0
  46. package/dist/components/chat/index.cjs +12 -2
  47. package/dist/components/chat/index.cjs.map +1 -1
  48. package/dist/components/chat/index.js +11 -1
  49. package/dist/components/chat/utils/index.d.ts +1 -0
  50. package/dist/components/chat/utils/index.d.ts.map +1 -1
  51. package/dist/components/chat/utils/scripted-stream.d.ts +38 -0
  52. package/dist/components/chat/utils/scripted-stream.d.ts.map +1 -0
  53. package/dist/components/contact/index.cjs +3 -3
  54. package/dist/components/contact/index.js +2 -2
  55. package/dist/components/docs/index.cjs +5 -5
  56. package/dist/components/docs/index.js +4 -4
  57. package/dist/components/embeds/index.cjs +3 -3
  58. package/dist/components/embeds/index.js +2 -2
  59. package/dist/components/faq/index.cjs +3 -3
  60. package/dist/components/faq/index.js +2 -2
  61. package/dist/components/features/board/index.d.ts +2 -2
  62. package/dist/components/features/board/index.d.ts.map +1 -1
  63. package/dist/components/features/board/ticket-card.d.ts +22 -2
  64. package/dist/components/features/board/ticket-card.d.ts.map +1 -1
  65. package/dist/components/features/index.cjs +6 -2
  66. package/dist/components/features/index.cjs.map +1 -1
  67. package/dist/components/features/index.js +5 -1
  68. package/dist/components/help-center-pages/index.cjs +20 -20
  69. package/dist/components/help-center-pages/index.js +11 -11
  70. package/dist/components/index.cjs +142 -128
  71. package/dist/components/index.cjs.map +1 -1
  72. package/dist/components/index.js +23 -9
  73. package/dist/components/index.js.map +1 -1
  74. package/dist/components/navigation/index.cjs +2 -2
  75. package/dist/components/navigation/index.js +1 -1
  76. package/dist/components/onboarding-guides/index.cjs +5 -5
  77. package/dist/components/onboarding-guides/index.js +4 -4
  78. package/dist/components/related-content/index.cjs +3 -3
  79. package/dist/components/related-content/index.js +2 -2
  80. package/dist/components/tickets/index.cjs +5 -5
  81. package/dist/components/tickets/index.js +4 -4
  82. package/dist/components/ui/index.cjs +12 -2
  83. package/dist/components/ui/index.cjs.map +1 -1
  84. package/dist/components/ui/index.js +11 -1
  85. package/dist/index.cjs +16 -2
  86. package/dist/index.cjs.map +1 -1
  87. package/dist/index.js +15 -1
  88. package/package.json +1 -1
  89. package/src/components/chat/hooks/index.ts +1 -0
  90. package/src/components/chat/hooks/use-nats-chat-adapter.ts +23 -0
  91. package/src/components/chat/hooks/use-scripted-stream.ts +69 -0
  92. package/src/components/chat/utils/index.ts +2 -0
  93. package/src/components/chat/utils/scripted-stream.ts +111 -0
  94. package/src/components/features/board/index.ts +2 -2
  95. package/src/components/features/board/ticket-card.tsx +108 -64
  96. package/dist/chunk-62L7S7HQ.js.map +0 -1
  97. package/dist/chunk-XDBD6BJN.cjs.map +0 -1
  98. /package/dist/{chunk-GMR5AA3C.js.map → chunk-2ELINEWQ.js.map} +0 -0
  99. /package/dist/{chunk-4VODJPTB.js.map → chunk-3AWPRVFM.js.map} +0 -0
  100. /package/dist/{chunk-RTOVYU4D.js.map → chunk-3OKVH6FW.js.map} +0 -0
  101. /package/dist/{chunk-2WJ25MTA.js.map → chunk-3XWBE3SM.js.map} +0 -0
  102. /package/dist/{chunk-TJ4HJ3KX.js.map → chunk-67LZDLIO.js.map} +0 -0
  103. /package/dist/{chunk-7PA4B6SD.js.map → chunk-A6JKKKIF.js.map} +0 -0
  104. /package/dist/{chunk-KHKB5RY2.js.map → chunk-AY5TBDWZ.js.map} +0 -0
  105. /package/dist/{chunk-Y2TW664W.js.map → chunk-IMOJWQDR.js.map} +0 -0
  106. /package/dist/{chunk-NYISC4Z3.js.map → chunk-NZBQGODM.js.map} +0 -0
  107. /package/dist/{chunk-MAYEJ3NY.js.map → chunk-S7UXICHB.js.map} +0 -0
  108. /package/dist/{chunk-B3FBMRHQ.js.map → chunk-TDITU4KW.js.map} +0 -0
@@ -34607,43 +34607,13 @@ var PRIORITY_COLOR_CLASS = {
34607
34607
  };
34608
34608
  var MAX_VISIBLE_TAGS = 2;
34609
34609
  var MAX_VISIBLE_ASSIGNEES = 3;
34610
- function TicketCard({
34611
- ticket,
34612
- columnId,
34613
- columnColor,
34614
- href,
34615
- isOverlay = false,
34616
- dragDisabled,
34617
- approved = false,
34618
- renderAssignSlot,
34619
- onApprove,
34620
- onReject
34621
- }) {
34622
- const sortableData = React103.useMemo(
34623
- () => ({ columnId, type: "ticket" }),
34624
- [columnId]
34625
- );
34626
- const sortable = useSortable({
34627
- id: ticket.id,
34628
- data: sortableData,
34629
- disabled: dragDisabled
34630
- });
34610
+ var TICKET_CARD_SHELL = "relative flex flex-col gap-[var(--spacing-system-sf)] rounded-md border border-ods-border bg-ods-bg p-[var(--spacing-system-sf)] select-none text-left";
34611
+ function TicketCardBody({ ticket, columnColor, renderAssignSlot, onApprove, onReject }) {
34631
34612
  const showNewMessage = !!ticket.hasNewMessage && !!columnColor;
34632
34613
  const newMessageTextColor = columnColor ? getReadableTextColor(columnColor) : void 0;
34633
- const style = isOverlay ? {} : {
34634
- transform: CSS.Transform.toString(sortable.transform),
34635
- transition: sortable.transition
34636
- };
34637
- if (showNewMessage) style.borderColor = columnColor;
34638
34614
  const showDeviceRow = !!(ticket.deviceHostnames?.length || ticket.organizationName);
34639
- const deviceText = [
34640
- ticket.deviceHostnames?.join(", "),
34641
- ticket.organizationName
34642
- ].filter(Boolean).join(", ");
34643
- const handleClick = (e) => {
34644
- if (sortable.isDragging) e.preventDefault();
34645
- };
34646
- const hasRightSection = !!(approved || ticket.priority || ticket.assignees?.length || renderAssignSlot);
34615
+ const deviceText = [ticket.deviceHostnames?.join(", "), ticket.organizationName].filter(Boolean).join(", ");
34616
+ const hasRightSection = !!(ticket.priority || ticket.assignees?.length || renderAssignSlot);
34647
34617
  const rightSection = hasRightSection ? /* @__PURE__ */ jsxs206("div", { className: "pointer-events-auto flex shrink-0 items-center gap-[var(--spacing-system-xsf)]", children: [
34648
34618
  ticket.priority && /* @__PURE__ */ jsx267(
34649
34619
  Flag02Icon,
@@ -34652,15 +34622,6 @@ function TicketCard({
34652
34622
  "aria-label": `Priority: ${ticket.priority}`
34653
34623
  }
34654
34624
  ),
34655
- approved && /* @__PURE__ */ jsx267(
34656
- CheckCircleIcon,
34657
- {
34658
- size: 20,
34659
- color: "var(--ods-attention-green-success)",
34660
- className: "shrink-0",
34661
- "aria-label": "Approved"
34662
- }
34663
- ),
34664
34625
  renderAssignSlot ? renderAssignSlot(ticket) : ticket.assignees?.length ? /* @__PURE__ */ jsxs206("div", { className: "flex -space-x-2", children: [
34665
34626
  ticket.assignees.slice(0, MAX_VISIBLE_ASSIGNEES).map((a) => /* @__PURE__ */ jsx267(
34666
34627
  SquareAvatar,
@@ -34681,7 +34642,7 @@ function TicketCard({
34681
34642
  ] }) : null;
34682
34643
  const timestampLabel = ticket.createdAt ? formatTicketRelativeTime(ticket.createdAt) : null;
34683
34644
  const tooltipLabel = ticket.createdAt ? formatTicketFullTimestamp(ticket.createdAt) : null;
34684
- const body = /* @__PURE__ */ jsxs206(Fragment47, { children: [
34645
+ return /* @__PURE__ */ jsxs206(Fragment47, { children: [
34685
34646
  /* @__PURE__ */ jsxs206("div", { className: "flex items-start gap-[var(--spacing-system-sf)]", children: [
34686
34647
  /* @__PURE__ */ jsxs206("div", { className: "flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-zero)]", title: ticket.title, children: [
34687
34648
  /* @__PURE__ */ jsx267("p", { className: "text-h3 truncate text-ods-text-primary", children: ticket.title }),
@@ -34706,17 +34667,55 @@ function TicketCard({
34706
34667
  style: { backgroundColor: columnColor, color: newMessageTextColor }
34707
34668
  }
34708
34669
  ),
34709
- ticket.pendingApproval && /* @__PURE__ */ jsx267(
34710
- BoardTicketApproval,
34711
- {
34712
- pendingApproval: ticket.pendingApproval,
34713
- onApprove: onApprove ? (requestId) => onApprove(ticket.id, requestId) : void 0,
34714
- onReject: onReject ? (requestId) => onReject(ticket.id, requestId) : void 0
34715
- }
34716
- )
34670
+ ticket.pendingApproval && /* @__PURE__ */ jsx267(BoardTicketApproval, { pendingApproval: ticket.pendingApproval, onApprove, onReject })
34717
34671
  ] });
34672
+ }
34673
+ function TicketCardView({ className, ...bodyProps }) {
34674
+ const { ticket, columnColor } = bodyProps;
34675
+ const showNewMessage = !!ticket.hasNewMessage && !!columnColor;
34676
+ return /* @__PURE__ */ jsx267(
34677
+ "div",
34678
+ {
34679
+ className: cn(TICKET_CARD_SHELL, className),
34680
+ style: showNewMessage ? { borderColor: columnColor } : void 0,
34681
+ children: /* @__PURE__ */ jsx267("div", { className: "relative z-10 flex flex-col gap-[var(--spacing-system-sf)]", children: /* @__PURE__ */ jsx267(TicketCardBody, { ...bodyProps }) })
34682
+ }
34683
+ );
34684
+ }
34685
+ function TicketCard({
34686
+ ticket,
34687
+ columnId,
34688
+ columnColor,
34689
+ href,
34690
+ isOverlay = false,
34691
+ dragDisabled,
34692
+ renderAssignSlot,
34693
+ onApprove,
34694
+ onReject
34695
+ }) {
34696
+ const sortableData = React103.useMemo(() => ({ columnId, type: "ticket" }), [columnId]);
34697
+ const sortable = useSortable({ id: ticket.id, data: sortableData, disabled: dragDisabled });
34698
+ const showNewMessage = !!ticket.hasNewMessage && !!columnColor;
34699
+ const style = isOverlay ? {} : {
34700
+ transform: CSS.Transform.toString(sortable.transform),
34701
+ transition: sortable.transition
34702
+ };
34703
+ if (showNewMessage) style.borderColor = columnColor;
34704
+ const handleClick = (e) => {
34705
+ if (sortable.isDragging) e.preventDefault();
34706
+ };
34707
+ const body = /* @__PURE__ */ jsx267(
34708
+ TicketCardBody,
34709
+ {
34710
+ ticket,
34711
+ columnColor,
34712
+ renderAssignSlot,
34713
+ onApprove: onApprove ? (requestId) => onApprove(ticket.id, requestId) : void 0,
34714
+ onReject: onReject ? (requestId) => onReject(ticket.id, requestId) : void 0
34715
+ }
34716
+ );
34718
34717
  const cardClasses = cn(
34719
- "relative flex flex-col gap-[var(--spacing-system-sf)] rounded-md border border-ods-border bg-ods-bg p-[var(--spacing-system-sf)] select-none text-left",
34718
+ TICKET_CARD_SHELL,
34720
34719
  !dragDisabled && "cursor-pointer",
34721
34720
  sortable.isDragging && !isOverlay && "opacity-40",
34722
34721
  isOverlay && "rotate-1 shadow-card-hover"
@@ -35860,7 +35859,7 @@ function SlidingSidebar({ config }) {
35860
35859
  const [mounted, setMounted] = useState85(false);
35861
35860
  const headerHeight = useHeaderHeight();
35862
35861
  const asideRef = useRef46(null);
35863
- const prefersReducedMotion = useReducedMotion();
35862
+ const prefersReducedMotion2 = useReducedMotion();
35864
35863
  usePreventScroll4({ isDisabled: !config.isOpen });
35865
35864
  useFocusTrap(asideRef, config.isOpen, { onEscape: config.onClose, contain: false });
35866
35865
  useEffect65(() => {
@@ -36003,7 +36002,7 @@ function SlidingSidebar({ config }) {
36003
36002
  animate: {
36004
36003
  x: config.isOpen ? 0 : config.position === "right" ? "100%" : "-100%"
36005
36004
  },
36006
- transition: prefersReducedMotion ? { duration: 0 } : {
36005
+ transition: prefersReducedMotion2 ? { duration: 0 } : {
36007
36006
  type: "spring",
36008
36007
  damping: 25,
36009
36008
  stiffness: 300,
@@ -47087,8 +47086,43 @@ function useChunkCatchup({
47087
47086
  };
47088
47087
  }
47089
47088
 
47089
+ // src/components/chat/hooks/use-scripted-stream.ts
47090
+ import { useEffect as useEffect77, useState as useState105 } from "react";
47091
+ var EMPTY_FRAME = { messages: [], phase: "idle", typing: false, delayMs: 0 };
47092
+ function prefersReducedMotion() {
47093
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
47094
+ }
47095
+ function useScriptedStream(frames, resetKey, enabled = true) {
47096
+ const [index, setIndex] = useState105(0);
47097
+ const [reducedMotion, setReducedMotion] = useState105(false);
47098
+ const [prevKey, setPrevKey] = useState105(resetKey);
47099
+ if (resetKey !== prevKey) {
47100
+ setPrevKey(resetKey);
47101
+ setIndex(0);
47102
+ }
47103
+ useEffect77(() => {
47104
+ setReducedMotion(prefersReducedMotion());
47105
+ const mq = window.matchMedia?.("(prefers-reduced-motion: reduce)");
47106
+ if (!mq) return;
47107
+ const onChange = () => setReducedMotion(mq.matches);
47108
+ mq.addEventListener("change", onChange);
47109
+ return () => mq.removeEventListener("change", onChange);
47110
+ }, []);
47111
+ const playing = enabled && !reducedMotion && frames.length > 0;
47112
+ const lastIndex = Math.max(0, frames.length - 1);
47113
+ useEffect77(() => {
47114
+ if (!playing || index >= lastIndex) return;
47115
+ const current = frames[Math.min(index, lastIndex)] ?? EMPTY_FRAME;
47116
+ const t = setTimeout(() => setIndex((i) => Math.min(i + 1, lastIndex)), current.delayMs);
47117
+ return () => clearTimeout(t);
47118
+ }, [index, frames, playing, lastIndex]);
47119
+ if (frames.length === 0) return EMPTY_FRAME;
47120
+ if (!playing) return frames[lastIndex];
47121
+ return frames[Math.min(index, lastIndex)] ?? EMPTY_FRAME;
47122
+ }
47123
+
47090
47124
  // src/components/chat/hooks/use-jetstream-dialog-subscription.ts
47091
- import { useEffect as useEffect77, useRef as useRef64, useState as useState105 } from "react";
47125
+ import { useEffect as useEffect78, useRef as useRef64, useState as useState106 } from "react";
47092
47126
  var DEFAULT_INACTIVE_THRESHOLD_MS = 5 * 6e4;
47093
47127
  var DEFAULT_STREAM_NAME = "CHAT_CHUNKS";
47094
47128
  function useJetStreamDialogSubscription({
@@ -47107,57 +47141,57 @@ function useJetStreamDialogSubscription({
47107
47141
  reconnectionBackoff,
47108
47142
  inactiveThresholdMs
47109
47143
  }) {
47110
- const [isConnected, setIsConnected] = useState105(false);
47111
- const [isSubscribed, setIsSubscribed] = useState105(false);
47112
- const [reconnectionCount, setReconnectionCount] = useState105(0);
47113
- const [currentStreamSeq, setCurrentStreamSeq] = useState105(null);
47144
+ const [isConnected, setIsConnected] = useState106(false);
47145
+ const [isSubscribed, setIsSubscribed] = useState106(false);
47146
+ const [reconnectionCount, setReconnectionCount] = useState106(0);
47147
+ const [currentStreamSeq, setCurrentStreamSeq] = useState106(null);
47114
47148
  const clientRef = useRef64(null);
47115
47149
  const subscriptionRef = useRef64(null);
47116
47150
  const highestStreamSeqRef = useRef64(null);
47117
47151
  const onEventRef = useRef64(onEvent);
47118
- useEffect77(() => {
47152
+ useEffect78(() => {
47119
47153
  onEventRef.current = onEvent;
47120
47154
  }, [onEvent]);
47121
47155
  const onConnectRef = useRef64(onConnect);
47122
- useEffect77(() => {
47156
+ useEffect78(() => {
47123
47157
  onConnectRef.current = onConnect;
47124
47158
  }, [onConnect]);
47125
47159
  const onDisconnectRef = useRef64(onDisconnect);
47126
- useEffect77(() => {
47160
+ useEffect78(() => {
47127
47161
  onDisconnectRef.current = onDisconnect;
47128
47162
  }, [onDisconnect]);
47129
47163
  const onSubscribedRef = useRef64(onSubscribed);
47130
- useEffect77(() => {
47164
+ useEffect78(() => {
47131
47165
  onSubscribedRef.current = onSubscribed;
47132
47166
  }, [onSubscribed]);
47133
47167
  const onBeforeReconnectRef = useRef64(onBeforeReconnect);
47134
- useEffect77(() => {
47168
+ useEffect78(() => {
47135
47169
  onBeforeReconnectRef.current = onBeforeReconnect;
47136
47170
  }, [onBeforeReconnect]);
47137
47171
  const getNatsWsUrlRef = useRef64(getNatsWsUrl);
47138
- useEffect77(() => {
47172
+ useEffect78(() => {
47139
47173
  getNatsWsUrlRef.current = getNatsWsUrl;
47140
47174
  }, [getNatsWsUrl]);
47141
47175
  const reconnectionBackoffRef = useRef64(reconnectionBackoff);
47142
- useEffect77(() => {
47176
+ useEffect78(() => {
47143
47177
  reconnectionBackoffRef.current = reconnectionBackoff;
47144
47178
  }, [reconnectionBackoff]);
47145
47179
  const optStartSeqRef = useRef64(optStartSeq);
47146
- useEffect77(() => {
47180
+ useEffect78(() => {
47147
47181
  optStartSeqRef.current = optStartSeq;
47148
47182
  }, [optStartSeq]);
47149
47183
  const inactiveThresholdRef = useRef64(inactiveThresholdMs);
47150
- useEffect77(() => {
47184
+ useEffect78(() => {
47151
47185
  inactiveThresholdRef.current = inactiveThresholdMs;
47152
47186
  }, [inactiveThresholdMs]);
47153
47187
  const hadConnectionBeforeRef = useRef64(false);
47154
47188
  const clientConfigRef = useRef64(clientConfig);
47155
- useEffect77(() => {
47189
+ useEffect78(() => {
47156
47190
  clientConfigRef.current = clientConfig;
47157
47191
  }, [clientConfig]);
47158
47192
  const currentWsUrlRef = useRef64("");
47159
47193
  const wsUrl = getNatsWsUrl();
47160
- useEffect77(() => {
47194
+ useEffect78(() => {
47161
47195
  if (!enabled || !wsUrl) {
47162
47196
  if (currentWsUrlRef.current && clientRef.current) {
47163
47197
  releaseClient(currentWsUrlRef.current);
@@ -47238,7 +47272,7 @@ function useJetStreamDialogSubscription({
47238
47272
  }
47239
47273
  };
47240
47274
  }, [enabled, wsUrl]);
47241
- useEffect77(() => {
47275
+ useEffect78(() => {
47242
47276
  if (!enabled || !dialogId || !isConnected) {
47243
47277
  if (subscriptionRef.current) {
47244
47278
  try {
@@ -47321,7 +47355,7 @@ function useJetStreamDialogSubscription({
47321
47355
  setIsSubscribed(false);
47322
47356
  };
47323
47357
  }, [enabled, dialogId, isConnected, streamName, topic, reconnectionCount]);
47324
- useEffect77(() => {
47358
+ useEffect78(() => {
47325
47359
  highestStreamSeqRef.current = null;
47326
47360
  setCurrentStreamSeq(null);
47327
47361
  }, [dialogId]);
@@ -47329,7 +47363,7 @@ function useJetStreamDialogSubscription({
47329
47363
  }
47330
47364
 
47331
47365
  // src/components/chat/hooks/use-nats-dialog-subscription.ts
47332
- import { useEffect as useEffect78, useRef as useRef65, useState as useState106 } from "react";
47366
+ import { useEffect as useEffect79, useRef as useRef65, useState as useState107 } from "react";
47333
47367
  function useNatsDialogSubscription({
47334
47368
  enabled,
47335
47369
  dialogId,
@@ -47343,47 +47377,47 @@ function useNatsDialogSubscription({
47343
47377
  clientConfig = {},
47344
47378
  reconnectionBackoff
47345
47379
  }) {
47346
- const [isConnected, setIsConnected] = useState106(false);
47347
- const [isSubscribed, setIsSubscribed] = useState106(false);
47348
- const [reconnectionCount, setReconnectionCount] = useState106(0);
47380
+ const [isConnected, setIsConnected] = useState107(false);
47381
+ const [isSubscribed, setIsSubscribed] = useState107(false);
47382
+ const [reconnectionCount, setReconnectionCount] = useState107(0);
47349
47383
  const clientRef = useRef65(null);
47350
47384
  const subscriptionRefs = useRef65(/* @__PURE__ */ new Map());
47351
47385
  const onEventRef = useRef65(onEvent);
47352
- useEffect78(() => {
47386
+ useEffect79(() => {
47353
47387
  onEventRef.current = onEvent;
47354
47388
  }, [onEvent]);
47355
47389
  const onConnectRef = useRef65(onConnect);
47356
- useEffect78(() => {
47390
+ useEffect79(() => {
47357
47391
  onConnectRef.current = onConnect;
47358
47392
  }, [onConnect]);
47359
47393
  const onDisconnectRef = useRef65(onDisconnect);
47360
- useEffect78(() => {
47394
+ useEffect79(() => {
47361
47395
  onDisconnectRef.current = onDisconnect;
47362
47396
  }, [onDisconnect]);
47363
47397
  const onSubscribedRef = useRef65(onSubscribed);
47364
- useEffect78(() => {
47398
+ useEffect79(() => {
47365
47399
  onSubscribedRef.current = onSubscribed;
47366
47400
  }, [onSubscribed]);
47367
47401
  const onBeforeReconnectRef = useRef65(onBeforeReconnect);
47368
- useEffect78(() => {
47402
+ useEffect79(() => {
47369
47403
  onBeforeReconnectRef.current = onBeforeReconnect;
47370
47404
  }, [onBeforeReconnect]);
47371
47405
  const hadConnectionBeforeRef = useRef65(false);
47372
47406
  const getNatsWsUrlRef = useRef65(getNatsWsUrl);
47373
- useEffect78(() => {
47407
+ useEffect79(() => {
47374
47408
  getNatsWsUrlRef.current = getNatsWsUrl;
47375
47409
  }, [getNatsWsUrl]);
47376
47410
  const reconnectionBackoffRef = useRef65(reconnectionBackoff);
47377
- useEffect78(() => {
47411
+ useEffect79(() => {
47378
47412
  reconnectionBackoffRef.current = reconnectionBackoff;
47379
47413
  }, [reconnectionBackoff]);
47380
47414
  const clientConfigRef = useRef65(clientConfig);
47381
- useEffect78(() => {
47415
+ useEffect79(() => {
47382
47416
  clientConfigRef.current = clientConfig;
47383
47417
  }, [clientConfig]);
47384
47418
  const currentWsUrlRef = useRef65("");
47385
47419
  const wsUrl = getNatsWsUrl();
47386
- useEffect78(() => {
47420
+ useEffect79(() => {
47387
47421
  if (!enabled || !wsUrl) {
47388
47422
  if (currentWsUrlRef.current && clientRef.current) {
47389
47423
  releaseClient(currentWsUrlRef.current);
@@ -47467,12 +47501,12 @@ function useNatsDialogSubscription({
47467
47501
  const topicsKey = topics.join(",");
47468
47502
  const lastSubscribedDialogIdRef = useRef65(null);
47469
47503
  const isConnectedRef = useRef65(isConnected);
47470
- useEffect78(() => {
47504
+ useEffect79(() => {
47471
47505
  isConnectedRef.current = isConnected;
47472
47506
  }, [isConnected]);
47473
47507
  const currentDialogIdRef = useRef65(null);
47474
47508
  const abortControllerRef = useRef65(null);
47475
- useEffect78(() => {
47509
+ useEffect79(() => {
47476
47510
  currentDialogIdRef.current = dialogId;
47477
47511
  if (!enabled || !dialogId) {
47478
47512
  if (subscriptionRefs.current.size > 0) {
@@ -47553,7 +47587,7 @@ function useNatsDialogSubscription({
47553
47587
  abortControllerRef.current = null;
47554
47588
  };
47555
47589
  }, [enabled, dialogId, topicsKey, topics]);
47556
- useEffect78(() => {
47590
+ useEffect79(() => {
47557
47591
  if (!enabled || !currentDialogIdRef.current || !isConnected) {
47558
47592
  return;
47559
47593
  }
@@ -47603,7 +47637,7 @@ function buildNatsWsUrl(apiBaseUrl, options) {
47603
47637
  }
47604
47638
 
47605
47639
  // src/components/chat/hooks/use-realtime-chunk-processor.ts
47606
- import { useCallback as useCallback46, useRef as useRef66, useEffect as useEffect79 } from "react";
47640
+ import { useCallback as useCallback46, useRef as useRef66, useEffect as useEffect80 } from "react";
47607
47641
 
47608
47642
  // src/components/chat/utils/chunk-parser.ts
47609
47643
  function normalizeToolCalls(raw) {
@@ -48261,7 +48295,7 @@ function useRealtimeChunkProcessor(options) {
48261
48295
  })
48262
48296
  );
48263
48297
  const hasInitializedWithData = useRef66(false);
48264
- useEffect79(() => {
48298
+ useEffect80(() => {
48265
48299
  if (initialState && !hasInitializedWithData.current) {
48266
48300
  accumulatorRef.current.initializeWithState(initialState);
48267
48301
  if (initialState.escalatedApprovals) {
@@ -48279,7 +48313,7 @@ function useRealtimeChunkProcessor(options) {
48279
48313
  const directModeFlagRef = useRef66(isDirectMode);
48280
48314
  const sawDirectMessageRef = useRef66(false);
48281
48315
  const directTeardownFiredRef = useRef66(false);
48282
- useEffect79(() => {
48316
+ useEffect80(() => {
48283
48317
  directModeFlagRef.current = isDirectMode;
48284
48318
  }, [isDirectMode]);
48285
48319
  const pendingEscalatedRef = useRef66(/* @__PURE__ */ new Map());
@@ -48546,7 +48580,7 @@ function useRealtimeChunkProcessor(options) {
48546
48580
  }
48547
48581
 
48548
48582
  // src/components/chat/hooks/use-slash-commands.ts
48549
- import { useEffect as useEffect80, useState as useState107 } from "react";
48583
+ import { useEffect as useEffect81, useState as useState108 } from "react";
48550
48584
  import { useQuery as useQuery2 } from "@tanstack/react-query";
48551
48585
  async function fetchSlashCommands(prefix, signal, commandsUrl) {
48552
48586
  try {
@@ -48563,9 +48597,9 @@ async function fetchSlashCommands(prefix, signal, commandsUrl) {
48563
48597
  }
48564
48598
  }
48565
48599
  function useSlashCommands(prefix, commandsUrl) {
48566
- const [commands, setCommands] = useState107([]);
48567
- const [loading, setLoading] = useState107(false);
48568
- useEffect80(() => {
48600
+ const [commands, setCommands] = useState108([]);
48601
+ const [loading, setLoading] = useState108(false);
48602
+ useEffect81(() => {
48569
48603
  if (prefix == null) {
48570
48604
  setCommands([]);
48571
48605
  return;
@@ -48671,7 +48705,7 @@ function useEmptyStateConfig(emptyStateUrl, options) {
48671
48705
  }
48672
48706
 
48673
48707
  // src/components/chat/hooks/use-chat-attachments.ts
48674
- import { useCallback as useCallback47, useMemo as useMemo41, useRef as useRef67, useState as useState108 } from "react";
48708
+ import { useCallback as useCallback47, useMemo as useMemo41, useRef as useRef67, useState as useState109 } from "react";
48675
48709
  import { fileTypeFromBlob } from "file-type";
48676
48710
  var CHAT_ATTACHMENTS_BUCKET = "chat-attachments";
48677
48711
  var CHAT_ATTACHMENTS_FOLDER = "chat";
@@ -48747,7 +48781,7 @@ function uploadWithProgress(url, file, token, onProgress, signal) {
48747
48781
  function useChatAttachments() {
48748
48782
  const runtime = useRequiredChatRuntime();
48749
48783
  const uploadUrlEndpoint = runtime.endpoints.attachmentUploadUrl;
48750
- const [attachments, setAttachments] = useState108([]);
48784
+ const [attachments, setAttachments] = useState109([]);
48751
48785
  const controllersRef = useRef67(/* @__PURE__ */ new Map());
48752
48786
  const updateOne = useCallback47((id, patch) => {
48753
48787
  setAttachments((prev) => prev.map((a) => a.id === id ? { ...a, ...patch } : a));
@@ -48914,16 +48948,16 @@ function useChatAttachments() {
48914
48948
  }
48915
48949
 
48916
48950
  // src/components/chat/hooks/use-chat-attachment-image-gallery.tsx
48917
- import { useCallback as useCallback48, useEffect as useEffect81, useRef as useRef68, useState as useState109 } from "react";
48951
+ import { useCallback as useCallback48, useEffect as useEffect82, useRef as useRef68, useState as useState110 } from "react";
48918
48952
  import { jsx as jsx358 } from "react/jsx-runtime";
48919
48953
  var CLOSED = { isOpen: false, images: [], initialIndex: 0 };
48920
48954
  function useChatAttachmentImageGallery() {
48921
48955
  const runtime = useRequiredChatRuntime();
48922
48956
  const viewUrlPrefix = runtime.endpoints.attachmentViewUrlPrefix;
48923
48957
  const panelRef = useRef68(null);
48924
- const [state, setState] = useState109(CLOSED);
48958
+ const [state, setState] = useState110(CLOSED);
48925
48959
  const handleClose = useCallback48(() => setState(CLOSED), []);
48926
- useEffect81(() => {
48960
+ useEffect82(() => {
48927
48961
  const root = panelRef.current;
48928
48962
  if (!root) return;
48929
48963
  const onClick = (ev) => {
@@ -48969,7 +49003,7 @@ function absolutize(prefix) {
48969
49003
  }
48970
49004
 
48971
49005
  // src/components/chat/hooks/use-chat-identity.ts
48972
- import { createContext as createContext12, createElement as createElement2, useContext as useContext12, useEffect as useEffect82, useState as useState110 } from "react";
49006
+ import { createContext as createContext12, createElement as createElement2, useContext as useContext12, useEffect as useEffect83, useState as useState111 } from "react";
48973
49007
  var ANON_DEFAULTS = {
48974
49008
  authTier: "anon",
48975
49009
  source: null,
@@ -48980,9 +49014,9 @@ function useResolveChatIdentity(enabled) {
48980
49014
  const runtime = useRequiredChatRuntime();
48981
49015
  const url = runtime.endpoints.identityUrl;
48982
49016
  const proxyEmail = getEmbedProxyAuth()?.email ?? null;
48983
- const [data, setData] = useState110(ANON_DEFAULTS);
48984
- const [isLoading, setIsLoading] = useState110(enabled);
48985
- useEffect82(() => {
49017
+ const [data, setData] = useState111(ANON_DEFAULTS);
49018
+ const [isLoading, setIsLoading] = useState111(enabled);
49019
+ useEffect83(() => {
48986
49020
  if (!enabled) return;
48987
49021
  let cancelled = false;
48988
49022
  const ctrl = new AbortController();
@@ -49024,11 +49058,11 @@ function useChatIdentity() {
49024
49058
  }
49025
49059
 
49026
49060
  // src/components/chat/hooks/use-close-on-navigation.ts
49027
- import { useEffect as useEffect83, useRef as useRef69 } from "react";
49061
+ import { useEffect as useEffect84, useRef as useRef69 } from "react";
49028
49062
  function useCloseOnNavigation(close, pathname) {
49029
49063
  const prevPathnameRef = useRef69(null);
49030
49064
  const initializedRef = useRef69(false);
49031
- useEffect83(() => {
49065
+ useEffect84(() => {
49032
49066
  if (!initializedRef.current) {
49033
49067
  initializedRef.current = true;
49034
49068
  prevPathnameRef.current = pathname;
@@ -49042,13 +49076,13 @@ function useCloseOnNavigation(close, pathname) {
49042
49076
  }
49043
49077
 
49044
49078
  // src/components/chat/hooks/use-chat.ts
49045
- import { useState as useState112, useCallback as useCallback50, useEffect as useEffect84, useRef as useRef71 } from "react";
49079
+ import { useState as useState113, useCallback as useCallback50, useEffect as useEffect85, useRef as useRef71 } from "react";
49046
49080
 
49047
49081
  // src/components/chat/hooks/use-sse.ts
49048
- import { useState as useState111, useCallback as useCallback49, useRef as useRef70 } from "react";
49082
+ import { useState as useState112, useCallback as useCallback49, useRef as useRef70 } from "react";
49049
49083
  function useSSE({ useMock = true, debugMode = false, streamFn } = {}) {
49050
- const [isStreaming, setIsStreaming] = useState111(false);
49051
- const [error, setError] = useState111(null);
49084
+ const [isStreaming, setIsStreaming] = useState112(false);
49085
+ const [error, setError] = useState112(null);
49052
49086
  const abortControllerRef = useRef70(null);
49053
49087
  const fallbackStream = useCallback49(async function* () {
49054
49088
  throw new Error(
@@ -49115,12 +49149,12 @@ function useChat({
49115
49149
  initialMessages,
49116
49150
  onMessagesChange
49117
49151
  } = {}) {
49118
- const [messages, setMessages] = useState112(() => initialMessages ?? []);
49119
- const [isTyping, setIsTyping] = useState112(false);
49152
+ const [messages, setMessages] = useState113(() => initialMessages ?? []);
49153
+ const [isTyping, setIsTyping] = useState113(false);
49120
49154
  const currentAssistantSegmentsRef = useRef71([]);
49121
49155
  const onMessagesChangeRef = useRef71(onMessagesChange);
49122
49156
  onMessagesChangeRef.current = onMessagesChange;
49123
- useEffect84(() => {
49157
+ useEffect85(() => {
49124
49158
  onMessagesChangeRef.current?.(messages);
49125
49159
  }, [messages]);
49126
49160
  const {
@@ -49409,7 +49443,7 @@ function useChat({
49409
49443
  }
49410
49444
 
49411
49445
  // src/components/chat/hooks/use-sse-chat-adapter.ts
49412
- import { useState as useState113, useEffect as useEffect85, useCallback as useCallback51, useMemo as useMemo42, useRef as useRef72 } from "react";
49446
+ import { useState as useState114, useEffect as useEffect86, useCallback as useCallback51, useMemo as useMemo42, useRef as useRef72 } from "react";
49413
49447
  function createEmptyTurnMeta() {
49414
49448
  return {
49415
49449
  provider: null,
@@ -49744,8 +49778,8 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
49744
49778
  const metaMapRef = useRef72(/* @__PURE__ */ new Map());
49745
49779
  const messagesRef = useRef72(persistedRef.current.messages);
49746
49780
  const sendCountRef = useRef72(persistedRef.current.sendCount);
49747
- const [streamingPhase, setStreamingPhase] = useState113("idle");
49748
- const [metaTick, setMetaTick] = useState113(0);
49781
+ const [streamingPhase, setStreamingPhase] = useState114("idle");
49782
+ const [metaTick, setMetaTick] = useState114(0);
49749
49783
  const bumpMetaTick = useCallback51(() => setMetaTick((t) => t + 1), []);
49750
49784
  const streamFn = useMemo42(
49751
49785
  () => createDocStreamFn(
@@ -49933,7 +49967,7 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
49933
49967
  }
49934
49968
  }
49935
49969
  }, [chatClearMessages, source, bumpMetaTick]);
49936
- useEffect85(() => {
49970
+ useEffect86(() => {
49937
49971
  if (!isTyping && !isStreaming && streamingPhase !== "idle") {
49938
49972
  setStreamingPhase("idle");
49939
49973
  }
@@ -50015,10 +50049,10 @@ var noopRejectRequest = async (_id, _reason) => {
50015
50049
  // src/components/chat/hooks/use-nats-chat-adapter.ts
50016
50050
  import {
50017
50051
  useCallback as useCallback52,
50018
- useEffect as useEffect86,
50052
+ useEffect as useEffect87,
50019
50053
  useMemo as useMemo43,
50020
50054
  useRef as useRef73,
50021
- useState as useState114
50055
+ useState as useState115
50022
50056
  } from "react";
50023
50057
 
50024
50058
  // src/components/chat/utils/process-historical-messages.ts
@@ -50481,6 +50515,14 @@ function mapProcessedToUnified(processed) {
50481
50515
  }
50482
50516
  return out;
50483
50517
  }
50518
+ function historicalToUnified(messages, options = {}) {
50519
+ const { messages: processed } = processHistoricalMessagesWithErrors(messages, options);
50520
+ const byId = new Map(processed.map((p) => [p.id, p]));
50521
+ return mapProcessedToUnified(processed).map((u) => {
50522
+ const p = byId.get(u.id);
50523
+ return p ? { ...u, name: p.name, avatar: p.avatar ?? null, authorType: p.authorType, timestamp: p.timestamp } : u;
50524
+ });
50525
+ }
50484
50526
  function useNatsChatAdapter(config, options = {}) {
50485
50527
  const { active = true } = options;
50486
50528
  const {
@@ -50508,26 +50550,26 @@ function useNatsChatAdapter(config, options = {}) {
50508
50550
  modelLabel = null
50509
50551
  } = config;
50510
50552
  const isManagedMode = fetchDialogs !== void 0;
50511
- const [internalDialogId, setInternalDialogId] = useState114(null);
50553
+ const [internalDialogId, setInternalDialogId] = useState115(null);
50512
50554
  const dialogId = isManagedMode ? internalDialogId : controlledDialogId !== void 0 ? controlledDialogId : null;
50513
- const [messages, setMessages] = useState114([]);
50514
- const [streamingPhase, setStreamingPhase] = useState114("idle");
50555
+ const [messages, setMessages] = useState115([]);
50556
+ const [streamingPhase, setStreamingPhase] = useState115("idle");
50515
50557
  const streamingPhaseRef = useRef73(streamingPhase);
50516
50558
  streamingPhaseRef.current = streamingPhase;
50517
50559
  const suppressAgentBusyRef = useRef73(false);
50518
- const [approvalStatuses, setApprovalStatuses] = useState114({});
50519
- const [dialogs, setDialogs] = useState114([]);
50520
- const [dialogsNextCursor, setDialogsNextCursor] = useState114(null);
50521
- const [isDialogsLoading, setIsDialogsLoading] = useState114(false);
50522
- const [dialogsError, setDialogsError] = useState114(false);
50523
- const [isCreatingDialog, setIsCreatingDialog] = useState114(false);
50524
- const [messagesNextCursor, setMessagesNextCursor] = useState114(null);
50525
- const [isMessagesLoading, setIsMessagesLoading] = useState114(false);
50526
- const [dialogTokenUsage, setDialogTokenUsage] = useState114(
50560
+ const [approvalStatuses, setApprovalStatuses] = useState115({});
50561
+ const [dialogs, setDialogs] = useState115([]);
50562
+ const [dialogsNextCursor, setDialogsNextCursor] = useState115(null);
50563
+ const [isDialogsLoading, setIsDialogsLoading] = useState115(false);
50564
+ const [dialogsError, setDialogsError] = useState115(false);
50565
+ const [isCreatingDialog, setIsCreatingDialog] = useState115(false);
50566
+ const [messagesNextCursor, setMessagesNextCursor] = useState115(null);
50567
+ const [isMessagesLoading, setIsMessagesLoading] = useState115(false);
50568
+ const [dialogTokenUsage, setDialogTokenUsage] = useState115(
50527
50569
  null
50528
50570
  );
50529
- const [liveModel, setLiveModel] = useState114(null);
50530
- const [connectionState, setConnectionState] = useState114("connecting");
50571
+ const [liveModel, setLiveModel] = useState115(null);
50572
+ const [connectionState, setConnectionState] = useState115("connecting");
50531
50573
  const handleApprove = useCallback52(
50532
50574
  async (requestId) => {
50533
50575
  if (!approveRequestCallback) return;
@@ -50687,7 +50729,7 @@ function useNatsChatAdapter(config, options = {}) {
50687
50729
  ]
50688
50730
  );
50689
50731
  const prevDialogIdRef = useRef73(void 0);
50690
- useEffect86(() => {
50732
+ useEffect87(() => {
50691
50733
  if (prevDialogIdRef.current === dialogId) return;
50692
50734
  prevDialogIdRef.current = dialogId;
50693
50735
  historyLoadSeqRef.current += 1;
@@ -50701,7 +50743,7 @@ function useNatsChatAdapter(config, options = {}) {
50701
50743
  if (!active || !dialogId) return;
50702
50744
  void loadDialogHistory(dialogId);
50703
50745
  }, [active, dialogId, loadDialogHistory, resetAccumulator]);
50704
- useEffect86(() => {
50746
+ useEffect87(() => {
50705
50747
  if (!active || !dialogId) return;
50706
50748
  suppressAgentBusyRef.current = true;
50707
50749
  resetChunkTracking();
@@ -50726,7 +50768,7 @@ function useNatsChatAdapter(config, options = {}) {
50726
50768
  setConnectionState("connected");
50727
50769
  }
50728
50770
  });
50729
- useEffect86(() => {
50771
+ useEffect87(() => {
50730
50772
  if (!active || !dialogId) {
50731
50773
  setConnectionState("connected");
50732
50774
  return;
@@ -50765,7 +50807,7 @@ function useNatsChatAdapter(config, options = {}) {
50765
50807
  const reloadDialogs = useCallback52(() => {
50766
50808
  void loadDialogsPage();
50767
50809
  }, [loadDialogsPage]);
50768
- useEffect86(() => {
50810
+ useEffect87(() => {
50769
50811
  if (!fetchDialogs) return;
50770
50812
  if (!active) return;
50771
50813
  if (initialDialogsLoadedRef.current) return;
@@ -51344,8 +51386,62 @@ function chatChipClass({ tone, density = "chip", extra }) {
51344
51386
  return extra ? `${base} ${extra}` : base;
51345
51387
  }
51346
51388
 
51389
+ // src/components/chat/utils/scripted-stream.ts
51390
+ function normalizeHistoricalMessageData(md) {
51391
+ return Array.isArray(md) ? md : md ? [md] : [];
51392
+ }
51393
+ function isHistoricalUserTurn(m) {
51394
+ return !!m.owner;
51395
+ }
51396
+ var isTextSegment = (d) => d?.type === "TEXT" && typeof d.text === "string";
51397
+ var THINK_MS = 550;
51398
+ var TOKEN_MS = 55;
51399
+ var USER_MS = 480;
51400
+ var SEGMENT_MS = 340;
51401
+ var POST_MS = 240;
51402
+ function tokenize(text) {
51403
+ return text.match(/\s*\S+\s*/g) ?? (text ? [text] : []);
51404
+ }
51405
+ function buildStreamFrames(messages) {
51406
+ const frames = [];
51407
+ const revealed = [];
51408
+ const push = (msgs, phase, typing, delayMs) => frames.push({ messages: msgs.slice(), phase, typing, delayMs });
51409
+ messages.forEach((msg) => {
51410
+ if (isHistoricalUserTurn(msg)) {
51411
+ revealed.push(msg);
51412
+ push(revealed, "idle", false, USER_MS);
51413
+ return;
51414
+ }
51415
+ if (revealed.length > 0) push(revealed, "thinking", true, THINK_MS);
51416
+ const segs = normalizeHistoricalMessageData(msg.messageData);
51417
+ const built = [];
51418
+ const emit = () => push([...revealed, { ...msg, messageData: [...built] }], "streaming", false, 0);
51419
+ segs.forEach((seg) => {
51420
+ if (isTextSegment(seg)) {
51421
+ const tokens = tokenize(seg.text);
51422
+ let acc = "";
51423
+ built.push({ ...seg, text: "" });
51424
+ tokens.forEach((tok) => {
51425
+ acc += tok;
51426
+ built[built.length - 1] = { ...seg, text: acc };
51427
+ push([...revealed, { ...msg, messageData: [...built] }], "streaming", false, TOKEN_MS);
51428
+ });
51429
+ built[built.length - 1] = { ...seg };
51430
+ } else {
51431
+ built.push(seg);
51432
+ emit();
51433
+ frames[frames.length - 1].delayMs = SEGMENT_MS;
51434
+ }
51435
+ });
51436
+ revealed.push(msg);
51437
+ push(revealed, "idle", false, POST_MS);
51438
+ });
51439
+ if (frames.length === 0) push(revealed, "idle", false, 0);
51440
+ return frames;
51441
+ }
51442
+
51347
51443
  // src/components/chat/embeddable-chat.tsx
51348
- import { useCallback as useCallback55, useEffect as useEffect87, useMemo as useMemo46, useRef as useRef75, useState as useState116 } from "react";
51444
+ import { useCallback as useCallback55, useEffect as useEffect88, useMemo as useMemo46, useRef as useRef75, useState as useState117 } from "react";
51349
51445
  import * as DialogPrimitive4 from "@radix-ui/react-dialog";
51350
51446
  import { usePreventScroll as usePreventScroll6 } from "@react-aria/overlays";
51351
51447
  import { isIOS } from "@react-aria/utils";
@@ -51426,7 +51522,7 @@ init_button2();
51426
51522
  import { FileText as FileText8, MessageSquare as MessageSquare3 } from "lucide-react";
51427
51523
 
51428
51524
  // src/components/chat/hooks/use-chat-dialog-manager.ts
51429
- import { useCallback as useCallback54, useMemo as useMemo45, useState as useState115 } from "react";
51525
+ import { useCallback as useCallback54, useMemo as useMemo45, useState as useState116 } from "react";
51430
51526
  function useChatDialogManager({
51431
51527
  dialogs,
51432
51528
  activeDialogId,
@@ -51437,8 +51533,8 @@ function useChatDialogManager({
51437
51533
  fetchArchivedDialogs,
51438
51534
  unarchiveDialog
51439
51535
  }) {
51440
- const [renameTarget, setRenameTarget] = useState115(null);
51441
- const [archiveTarget, setArchiveTarget] = useState115(null);
51536
+ const [renameTarget, setRenameTarget] = useState116(null);
51537
+ const [archiveTarget, setArchiveTarget] = useState116(null);
51442
51538
  const handleConfirmRename = useCallback54(
51443
51539
  (name) => {
51444
51540
  if (renameTarget) void renameDialog(renameTarget.id, name);
@@ -51461,10 +51557,10 @@ function useChatDialogManager({
51461
51557
  }
51462
51558
  setArchiveTarget(null);
51463
51559
  }, [archiveTarget, archiveDialog, activeDialogId, clearMessages]);
51464
- const [archiveOpen, setArchiveOpen] = useState115(false);
51465
- const [archivedDialogs, setArchivedDialogs] = useState115([]);
51466
- const [archivedCursor, setArchivedCursor] = useState115(null);
51467
- const [archivedLoading, setArchivedLoading] = useState115(false);
51560
+ const [archiveOpen, setArchiveOpen] = useState116(false);
51561
+ const [archivedDialogs, setArchivedDialogs] = useState116([]);
51562
+ const [archivedCursor, setArchivedCursor] = useState116(null);
51563
+ const [archivedLoading, setArchivedLoading] = useState116(false);
51468
51564
  const loadArchivedPage = useCallback54(
51469
51565
  async (cursor) => {
51470
51566
  if (!fetchArchivedDialogs) return;
@@ -51490,10 +51586,10 @@ function useChatDialogManager({
51490
51586
  void loadArchivedPage();
51491
51587
  }, [loadArchivedPage]);
51492
51588
  const closeArchive = useCallback54(() => setArchiveOpen(false), []);
51493
- const [viewingArchivedId, setViewingArchivedId] = useState115(
51589
+ const [viewingArchivedId, setViewingArchivedId] = useState116(
51494
51590
  null
51495
51591
  );
51496
- const [openingDialogId, setOpeningDialogId] = useState115(null);
51592
+ const [openingDialogId, setOpeningDialogId] = useState116(null);
51497
51593
  const handleSelectDialog = useCallback54(
51498
51594
  (id) => {
51499
51595
  setViewingArchivedId(null);
@@ -51512,7 +51608,7 @@ function useChatDialogManager({
51512
51608
  },
51513
51609
  [selectDialog]
51514
51610
  );
51515
- const [restoreTarget, setRestoreTarget] = useState115(null);
51611
+ const [restoreTarget, setRestoreTarget] = useState116(null);
51516
51612
  const handleConfirmRestore = useCallback54(async () => {
51517
51613
  if (restoreTarget) {
51518
51614
  try {
@@ -51764,7 +51860,7 @@ function SourceChips({
51764
51860
  onClose,
51765
51861
  onDiscuss
51766
51862
  }) {
51767
- const [expanded, setExpanded] = useState116(false);
51863
+ const [expanded, setExpanded] = useState117(false);
51768
51864
  if (cited.length === 0) {
51769
51865
  const fallback = uncited.slice(0, FALLBACK_TOP_RETRIEVED);
51770
51866
  if (fallback.length === 0) return null;
@@ -51870,7 +51966,7 @@ function EmbeddableChatInner({
51870
51966
  const commandsUrl = runtime.endpoints.commandsUrl;
51871
51967
  const { attachmentsEnabled, user: identityUser } = useChatIdentity();
51872
51968
  const viewUrlPrefix = runtime.endpoints.attachmentViewUrlPrefix;
51873
- useEffect87(() => {
51969
+ useEffect88(() => {
51874
51970
  if (process.env.NODE_ENV !== "production") {
51875
51971
  const hasOpen = open !== void 0;
51876
51972
  const hasHandler = onOpenChange !== void 0;
@@ -51886,13 +51982,13 @@ function EmbeddableChatInner({
51886
51982
  defaultProp: defaultOpen ?? false,
51887
51983
  onChange: onOpenChange
51888
51984
  });
51889
- const [autoFocusInput] = useState116(() => {
51985
+ const [autoFocusInput] = useState117(() => {
51890
51986
  if (typeof window === "undefined") return false;
51891
51987
  return !window.matchMedia("(pointer: coarse)").matches;
51892
51988
  });
51893
51989
  usePreventScroll6({ isDisabled: !isOpen || shellLess });
51894
51990
  const navigatingAwayRef = useRef75(false);
51895
- useEffect87(() => {
51991
+ useEffect88(() => {
51896
51992
  if (!isOpen) return;
51897
51993
  if (shellLess) return;
51898
51994
  if (typeof window === "undefined") return;
@@ -51919,7 +52015,7 @@ function EmbeddableChatInner({
51919
52015
  };
51920
52016
  }, [isOpen, shellLess]);
51921
52017
  const chatInputRef = useRef75(null);
51922
- const [quickActionPreview, setQuickActionPreview] = useState116(null);
52018
+ const [quickActionPreview, setQuickActionPreview] = useState117(null);
51923
52019
  const slashCommandsProp = useMemo46(
51924
52020
  () => ({
51925
52021
  fetchCommands: (prefix, signal) => fetchSlashCommands(prefix, signal, commandsUrl),
@@ -51962,7 +52058,7 @@ function EmbeddableChatInner({
51962
52058
  }, [mingoState, mingoDialogCapabilities, effectiveModes]);
51963
52059
  const hasMingoMode = !!effectiveModes.mingo || !!mingoState;
51964
52060
  const initialActiveMode = controlledActiveMode ?? defaultActiveMode ?? (effectiveModes.guide ? "guide" : "mingo");
51965
- const [uncontrolledActiveMode, setUncontrolledActiveMode] = useState116(initialActiveMode);
52061
+ const [uncontrolledActiveMode, setUncontrolledActiveMode] = useState117(initialActiveMode);
51966
52062
  const activeMode = controlledActiveMode ?? uncontrolledActiveMode;
51967
52063
  const handleActiveModeChange = useCallback55(
51968
52064
  (next) => {
@@ -52023,7 +52119,7 @@ function EmbeddableChatInner({
52023
52119
  loadMoreMessages
52024
52120
  } = useUnifiedChat({ modes: effectiveModes, activeMode, mingoStateOverride: mingoState });
52025
52121
  const guidePromptSentRef = useRef75(false);
52026
- useEffect87(() => {
52122
+ useEffect88(() => {
52027
52123
  if (!guidePendingPrompt) {
52028
52124
  guidePromptSentRef.current = false;
52029
52125
  return;
@@ -52044,15 +52140,15 @@ function EmbeddableChatInner({
52044
52140
  const { panelRef: galleryPanelRef, modal: galleryModal } = useChatAttachmentImageGallery();
52045
52141
  const contextMaxItems = contextPicker?.maxItems ?? 10;
52046
52142
  const contextPickerForMode = activeMode === "mingo" ? contextPicker : void 0;
52047
- const [contextItems, setContextItems] = useState116([]);
52048
- const [contextPickerOpen, setContextPickerOpen] = useState116(false);
52049
- const [mentionQuery, setMentionQuery] = useState116(null);
52143
+ const [contextItems, setContextItems] = useState117([]);
52144
+ const [contextPickerOpen, setContextPickerOpen] = useState117(false);
52145
+ const [mentionQuery, setMentionQuery] = useState117(null);
52050
52146
  const mentionActiveRef = useRef75(false);
52051
- useEffect87(() => {
52147
+ useEffect88(() => {
52052
52148
  mentionActiveRef.current = mentionQuery !== null;
52053
52149
  }, [mentionQuery]);
52054
52150
  const mentionKeysRef = useRef75(/* @__PURE__ */ new Set());
52055
- useEffect87(() => {
52151
+ useEffect88(() => {
52056
52152
  setContextItems([]);
52057
52153
  setMentionQuery(null);
52058
52154
  mentionKeysRef.current.clear();
@@ -52273,7 +52369,7 @@ function EmbeddableChatInner({
52273
52369
  });
52274
52370
  const handleOpen = useCallback55(() => setIsOpen(true), [setIsOpen]);
52275
52371
  useCloseOnNavigation(handleNavigationClose, null);
52276
- useEffect87(() => {
52372
+ useEffect88(() => {
52277
52373
  const handler = (e) => {
52278
52374
  const detail = e.detail;
52279
52375
  if (!detail || detail.source !== source) return;
@@ -52283,7 +52379,7 @@ function EmbeddableChatInner({
52283
52379
  window.addEventListener("ask-ai:open-with-ref", handler);
52284
52380
  return () => window.removeEventListener("ask-ai:open-with-ref", handler);
52285
52381
  }, [source, discussRef, setIsOpen]);
52286
- useEffect87(() => {
52382
+ useEffect88(() => {
52287
52383
  const handler = (e) => {
52288
52384
  const detail = e.detail;
52289
52385
  if (!detail || detail.source !== source) return;
@@ -52300,7 +52396,7 @@ function EmbeddableChatInner({
52300
52396
  const contentViewKey = hasConversation ? "conversation" : activeMode;
52301
52397
  const isGuideEmpty = !hasConversation && activeMode === "guide";
52302
52398
  const isQuickActionEmpty = !hasConversation && (activeMode === "guide" || activeMode === "mingo");
52303
- useEffect87(() => {
52399
+ useEffect88(() => {
52304
52400
  if (!isQuickActionEmpty) setQuickActionPreview(null);
52305
52401
  }, [isQuickActionEmpty]);
52306
52402
  const guideCanReturnToMingo = isGuideEmpty && hasMingoMode;
@@ -52342,7 +52438,7 @@ function EmbeddableChatInner({
52342
52438
  const uncited = sources.filter((s) => !seenOrder.has(s.index));
52343
52439
  return { cited, uncited };
52344
52440
  }, [lastAssistantMsg, chatLoading]);
52345
- const [portalHost, setPortalHost] = useState116(null);
52441
+ const [portalHost, setPortalHost] = useState117(null);
52346
52442
  const body = /* @__PURE__ */ jsxs286(PortalContainerContext.Provider, { value: portalHost, children: [
52347
52443
  /* @__PURE__ */ jsx361(
52348
52444
  "div",
@@ -53198,6 +53294,7 @@ export {
53198
53294
  normalizeContent2 as normalizeContent,
53199
53295
  NETWORK_CONFIG,
53200
53296
  useChunkCatchup,
53297
+ useScriptedStream,
53201
53298
  useJetStreamDialogSubscription,
53202
53299
  useNatsDialogSubscription,
53203
53300
  buildNatsWsUrl,
@@ -53236,6 +53333,7 @@ export {
53236
53333
  extractErrorMessages,
53237
53334
  processHistoricalMessagesWithErrors,
53238
53335
  mapProcessedToUnified,
53336
+ historicalToUnified,
53239
53337
  useNatsChatAdapter,
53240
53338
  useUnifiedChat,
53241
53339
  extractIncompleteMessageState,
@@ -53247,6 +53345,9 @@ export {
53247
53345
  CHIP_ACTION_BUTTON_CLASS,
53248
53346
  chatChipClass,
53249
53347
  clickupTaskUrl,
53348
+ normalizeHistoricalMessageData,
53349
+ isHistoricalUserTurn,
53350
+ buildStreamFrames,
53250
53351
  EmbeddableChat,
53251
53352
  FilterCheckboxItem,
53252
53353
  TagKeyValueFilter,
@@ -53546,6 +53647,8 @@ export {
53546
53647
  BoardColumnHeader,
53547
53648
  tintOnDark,
53548
53649
  BoardTicketApproval,
53650
+ TicketCardBody,
53651
+ TicketCardView,
53549
53652
  TicketCard,
53550
53653
  TicketCardSkeleton,
53551
53654
  BoardColumn,
@@ -53646,4 +53749,4 @@ export {
53646
53749
  LogsList,
53647
53750
  assets
53648
53751
  };
53649
- //# sourceMappingURL=chunk-62L7S7HQ.js.map
53752
+ //# sourceMappingURL=chunk-TYANQCZA.js.map