@opengeni/react 1.0.2-canary.37191796234001 → 1.0.2

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 (75) hide show
  1. package/README.md +15 -6
  2. package/dist/artifacts.js +1 -1
  3. package/dist/{browser-viewer-GTR5XQ7X.js → browser-viewer-SHYKQRNX.js} +4 -4
  4. package/dist/{chunk-CR7U7HAR.js → chunk-26ZNDDLZ.js} +3 -3
  5. package/dist/{chunk-ELCE5SXV.js → chunk-3CTRFMAK.js} +2 -2
  6. package/dist/{chunk-XOAMRDDK.js → chunk-742CZ3L3.js} +2 -2
  7. package/dist/{chunk-H2NJQORO.js → chunk-DO544OSV.js} +7 -1
  8. package/dist/chunk-DO544OSV.js.map +1 -0
  9. package/dist/{chunk-IQUCRAT7.js → chunk-EESD3PY3.js} +2 -2
  10. package/dist/{chunk-23J2ZNXT.js → chunk-EN3YTHKR.js} +3 -3
  11. package/dist/{chunk-JFNEV4LU.js → chunk-GYVRFZDY.js} +3 -3
  12. package/dist/{chunk-YWFG7ZX7.js → chunk-HDJWDK7W.js} +3 -3
  13. package/dist/{chunk-NZUI76EM.js → chunk-J6DBS4T3.js} +2 -2
  14. package/dist/{chunk-SJZDKVW2.js → chunk-JIQYUGVL.js} +4 -4
  15. package/dist/{chunk-XUW2UWQM.js → chunk-RLUSC2WA.js} +3 -3
  16. package/dist/{chunk-XUW2UWQM.js.map → chunk-RLUSC2WA.js.map} +1 -1
  17. package/dist/{chunk-Q5QBEZIQ.js → chunk-RSI7XYXL.js} +2 -2
  18. package/dist/{chunk-NEXLLTP4.js → chunk-TKOTKRWY.js} +4 -4
  19. package/dist/{chunk-NEXLLTP4.js.map → chunk-TKOTKRWY.js.map} +1 -1
  20. package/dist/{chunk-TMJRG4YC.js → chunk-VV5E43LD.js} +432 -180
  21. package/dist/chunk-VV5E43LD.js.map +1 -0
  22. package/dist/{chunk-FFA2OVOV.js → chunk-WGXVEJO5.js} +3 -3
  23. package/dist/{chunk-E3G7SAYZ.js → chunk-YM2DE7BQ.js} +2 -2
  24. package/dist/components/open-geni-chat.d.ts +6 -3
  25. package/dist/components/session-conversation.d.ts +6 -3
  26. package/dist/components/session-proxy-scope.d.ts +21 -0
  27. package/dist/composer.js +6 -6
  28. package/dist/{computer-viewer-ENHVAZ2Q.js → computer-viewer-6SRGWRUX.js} +4 -4
  29. package/dist/index.js +17 -17
  30. package/dist/index.js.map +1 -1
  31. package/dist/interaction.js +4 -4
  32. package/dist/{latest-question-755OW5DS.js → latest-question-HTRIS4KJ.js} +2 -2
  33. package/dist/lib/host-theme.d.ts +7 -0
  34. package/dist/machines.js +3 -3
  35. package/dist/{model-policy-picker-menu-PWRI7R2X.js → model-policy-picker-menu-M54ISBMN.js} +4 -4
  36. package/dist/model-policy.js +1 -1
  37. package/dist/realtime.js +3 -3
  38. package/dist/{sandbox-files-BBC47SLD.js → sandbox-files-GORZOUUJ.js} +4 -4
  39. package/dist/session-ui.js +9 -9
  40. package/dist/session.js +5 -5
  41. package/dist/timeline/turn-summary.d.ts +3 -1
  42. package/dist/timeline/types.d.ts +6 -0
  43. package/dist/usage.js +1 -1
  44. package/package.json +3 -3
  45. package/src/components/message-timeline.tsx +704 -450
  46. package/src/components/open-geni-chat.tsx +56 -37
  47. package/src/components/session-conversation.tsx +87 -73
  48. package/src/components/session-proxy-scope.tsx +92 -0
  49. package/src/hooks/use-session-background-commands.ts +2 -2
  50. package/src/hooks/use-video-artifact-playback.ts +1 -1
  51. package/src/lib/host-theme.ts +15 -2
  52. package/src/model-policy.ts +2 -2
  53. package/src/session-context.ts +3 -3
  54. package/src/timeline/projection.ts +9 -0
  55. package/src/timeline/turn-summary.tsx +10 -0
  56. package/src/timeline/types.ts +6 -0
  57. package/dist/chunk-H2NJQORO.js.map +0 -1
  58. package/dist/chunk-TMJRG4YC.js.map +0 -1
  59. /package/dist/{browser-viewer-GTR5XQ7X.js.map → browser-viewer-SHYKQRNX.js.map} +0 -0
  60. /package/dist/{chunk-CR7U7HAR.js.map → chunk-26ZNDDLZ.js.map} +0 -0
  61. /package/dist/{chunk-ELCE5SXV.js.map → chunk-3CTRFMAK.js.map} +0 -0
  62. /package/dist/{chunk-XOAMRDDK.js.map → chunk-742CZ3L3.js.map} +0 -0
  63. /package/dist/{chunk-IQUCRAT7.js.map → chunk-EESD3PY3.js.map} +0 -0
  64. /package/dist/{chunk-23J2ZNXT.js.map → chunk-EN3YTHKR.js.map} +0 -0
  65. /package/dist/{chunk-JFNEV4LU.js.map → chunk-GYVRFZDY.js.map} +0 -0
  66. /package/dist/{chunk-YWFG7ZX7.js.map → chunk-HDJWDK7W.js.map} +0 -0
  67. /package/dist/{chunk-NZUI76EM.js.map → chunk-J6DBS4T3.js.map} +0 -0
  68. /package/dist/{chunk-SJZDKVW2.js.map → chunk-JIQYUGVL.js.map} +0 -0
  69. /package/dist/{chunk-Q5QBEZIQ.js.map → chunk-RSI7XYXL.js.map} +0 -0
  70. /package/dist/{chunk-FFA2OVOV.js.map → chunk-WGXVEJO5.js.map} +0 -0
  71. /package/dist/{chunk-E3G7SAYZ.js.map → chunk-YM2DE7BQ.js.map} +0 -0
  72. /package/dist/{computer-viewer-ENHVAZ2Q.js.map → computer-viewer-6SRGWRUX.js.map} +0 -0
  73. /package/dist/{latest-question-755OW5DS.js.map → latest-question-HTRIS4KJ.js.map} +0 -0
  74. /package/dist/{model-policy-picker-menu-PWRI7R2X.js.map → model-policy-picker-menu-M54ISBMN.js.map} +0 -0
  75. /package/dist/{sandbox-files-BBC47SLD.js.map → sandbox-files-GORZOUUJ.js.map} +0 -0
@@ -28,15 +28,18 @@ import {
28
28
  useSessionControl,
29
29
  useSessionEvents,
30
30
  useTurnQueue
31
- } from "./chunk-SJZDKVW2.js";
31
+ } from "./chunk-JIQYUGVL.js";
32
32
  import {
33
33
  buildTimeline,
34
34
  groupTimeline
35
- } from "./chunk-H2NJQORO.js";
35
+ } from "./chunk-DO544OSV.js";
36
36
  import {
37
37
  mcpToolLeaf,
38
38
  toolDisplayName
39
39
  } from "./chunk-ERGYJIBB.js";
40
+ import {
41
+ OpenGeniProvider
42
+ } from "./chunk-3CTRFMAK.js";
40
43
  import {
41
44
  ActivityDisclosure,
42
45
  BodyNote,
@@ -96,10 +99,10 @@ import {
96
99
  StopButton,
97
100
  Surface,
98
101
  useChatComposerController
99
- } from "./chunk-23J2ZNXT.js";
102
+ } from "./chunk-EN3YTHKR.js";
100
103
  import {
101
104
  useComposer
102
- } from "./chunk-Q5QBEZIQ.js";
105
+ } from "./chunk-RSI7XYXL.js";
103
106
  import {
104
107
  LightboxProvider,
105
108
  Tooltip,
@@ -109,11 +112,11 @@ import {
109
112
  } from "./chunk-BRM6FVZA.js";
110
113
  import {
111
114
  ModelPolicyPicker
112
- } from "./chunk-CR7U7HAR.js";
115
+ } from "./chunk-26ZNDDLZ.js";
113
116
  import {
114
117
  projectPickerRows,
115
118
  sortPickerRows
116
- } from "./chunk-XUW2UWQM.js";
119
+ } from "./chunk-RLUSC2WA.js";
117
120
  import {
118
121
  formatBytes,
119
122
  formatClockTime,
@@ -136,7 +139,7 @@ import {
136
139
  import {
137
140
  useOpenGeni,
138
141
  useOpenGeniClient
139
- } from "./chunk-NEXLLTP4.js";
142
+ } from "./chunk-TKOTKRWY.js";
140
143
  import {
141
144
  cn
142
145
  } from "./chunk-22KP6LR5.js";
@@ -4536,6 +4539,7 @@ import {
4536
4539
  createContext as createContext8,
4537
4540
  useContext as useContext9,
4538
4541
  useEffect as useEffect6,
4542
+ useLayoutEffect as useLayoutEffect2,
4539
4543
  useMemo as useMemo2,
4540
4544
  useRef as useRef6,
4541
4545
  useState as useState9
@@ -4591,6 +4595,7 @@ function TurnSummary({
4591
4595
  copyText,
4592
4596
  contextCompactionCount,
4593
4597
  status,
4598
+ onOpenStateChange,
4594
4599
  children
4595
4600
  }) {
4596
4601
  const forcedDefaultOpen = useForcedDefaultOpen();
@@ -4601,6 +4606,11 @@ function TurnSummary({
4601
4606
  const initialSettle = Boolean(settleFold) && !restingOpen && remembered === void 0;
4602
4607
  const [settling, setSettling] = useState9(initialSettle);
4603
4608
  const [open, setOpen] = useState9(initialSettle ? true : restingOpen);
4609
+ const reportOpen = useRef6(onOpenStateChange);
4610
+ reportOpen.current = onOpenStateChange;
4611
+ useLayoutEffect2(() => {
4612
+ reportOpen.current?.(open);
4613
+ }, [open]);
4604
4614
  const readerOwnsOpen = useRef6(remembered !== void 0);
4605
4615
  useEffect6(() => {
4606
4616
  if (status && defaultOpen && remembered === void 0 && !readerOwnsOpen.current) setOpen(true);
@@ -5080,7 +5090,7 @@ import {
5080
5090
  useCallback,
5081
5091
  useContext as useContext10,
5082
5092
  useId as useId3,
5083
- useLayoutEffect as useLayoutEffect2,
5093
+ useLayoutEffect as useLayoutEffect3,
5084
5094
  useRef as useRef7,
5085
5095
  useState as useState10
5086
5096
  } from "react";
@@ -5245,7 +5255,7 @@ function UserMessageBody({
5245
5255
  () => disclosure?.expandedByMessageId.get(messageId) ?? false
5246
5256
  );
5247
5257
  const searchReveal = useTimelineSearchReveal();
5248
- useLayoutEffect2(() => {
5258
+ useLayoutEffect3(() => {
5249
5259
  if (!searchReveal) return;
5250
5260
  setExpanded(true);
5251
5261
  disclosure?.expandedByMessageId.set(messageId, true);
@@ -5339,7 +5349,7 @@ function UserMessageBody({
5339
5349
  }
5340
5350
  });
5341
5351
  }, [readCollapsible, syncCollapsedInteractivity, syncDisclosurePresentation]);
5342
- useLayoutEffect2(() => {
5352
+ useLayoutEffect3(() => {
5343
5353
  const cancelPendingMeasurement = measure();
5344
5354
  const content = contentRef.current;
5345
5355
  const threshold = thresholdRef.current;
@@ -5364,7 +5374,7 @@ function UserMessageBody({
5364
5374
  }
5365
5375
  };
5366
5376
  }, [measure, syncCollapsedInteractivity]);
5367
- useLayoutEffect2(() => {
5377
+ useLayoutEffect3(() => {
5368
5378
  syncDisclosurePresentation(collapsibleRef.current);
5369
5379
  syncCollapsedInteractivity();
5370
5380
  return restoreManagedInertDescendants;
@@ -5374,7 +5384,7 @@ function UserMessageBody({
5374
5384
  syncCollapsedInteractivity,
5375
5385
  syncDisclosurePresentation
5376
5386
  ]);
5377
- useLayoutEffect2(() => {
5387
+ useLayoutEffect3(() => {
5378
5388
  const restore = pendingRestoreRef.current;
5379
5389
  pendingRestoreRef.current = null;
5380
5390
  restore?.();
@@ -5750,11 +5760,13 @@ import { Collapsible as Collapsible2 } from "radix-ui";
5750
5760
  import {
5751
5761
  Component as Component3,
5752
5762
  Suspense as Suspense4,
5763
+ createContext as createContext11,
5753
5764
  lazy as lazy3,
5754
5765
  memo,
5755
5766
  useCallback as useCallback3,
5767
+ useContext as useContext12,
5756
5768
  useEffect as useEffect9,
5757
- useLayoutEffect as useLayoutEffect4,
5769
+ useLayoutEffect as useLayoutEffect5,
5758
5770
  useMemo as useMemo5,
5759
5771
  useRef as useRef9,
5760
5772
  useState as useState14
@@ -5840,7 +5852,7 @@ function timelineAnchorCorrection(scroller, anchors) {
5840
5852
  }
5841
5853
 
5842
5854
  // src/components/timeline-reading-progress.ts
5843
- import { useCallback as useCallback2, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef8, useState as useState13 } from "react";
5855
+ import { useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useMemo as useMemo3, useRef as useRef8, useState as useState13 } from "react";
5844
5856
  function useReadingProgress(projected, pinned, scroller) {
5845
5857
  const following = pinned && !timelineHasReader(scroller);
5846
5858
  const previous = useRef8([]);
@@ -5882,7 +5894,7 @@ function useReadingProgress(projected, pinned, scroller) {
5882
5894
  ...before.get(null) ?? []
5883
5895
  ];
5884
5896
  }, [projected, following, released]);
5885
- useLayoutEffect3(() => {
5897
+ useLayoutEffect4(() => {
5886
5898
  previous.current = groups;
5887
5899
  if (following && released.size) setReleased(/* @__PURE__ */ new Set());
5888
5900
  }, [groups, following, released]);
@@ -6386,6 +6398,10 @@ var PRIMARY_ACTION_CLASS = "inline-flex w-full shrink-0 items-center justify-cen
6386
6398
  var MESSAGE_BUBBLE_CLASS = "w-fit max-w-full min-w-0 rounded-og-lg rounded-br-og-xs border border-og-border bg-og-surface-2 px-4 py-2.5 text-og-md leading-6 text-og-fg";
6387
6399
  var WAITING_PILL_CLASS = "border-og-status-waiting/35 bg-og-status-waiting/10 text-og-status-waiting";
6388
6400
  var LOADING_CHIP_CLASS = "pointer-events-none inline-flex items-center rounded-full border border-og-border bg-og-surface-3/90 px-3 py-1 text-og-control font-medium shadow-og-md backdrop-blur";
6401
+ var LIVE_NOTE_FOLD_MS = 220;
6402
+ var LIVE_NOTE_GAP_PX = 20;
6403
+ var LIVE_NOTE_RESERVE_MS = 700;
6404
+ var LiveNoteFoldContext = createContext11(null);
6389
6405
  function invokeOlderLoad(load, noProgress, attempt, preserveTail = false) {
6390
6406
  try {
6391
6407
  const result = invokeOlderHistoryLoaderWithReceiptCapture(
@@ -6630,7 +6646,7 @@ function MessageTimeline({
6630
6646
  () => groupTimeline(resolvedItems, { readableTurns }),
6631
6647
  [resolvedItems, readableTurns]
6632
6648
  );
6633
- useLayoutEffect4(() => stopSettlement, [projectedGroups, stopSettlement]);
6649
+ useLayoutEffect5(() => stopSettlement, [projectedGroups, stopSettlement]);
6634
6650
  const annotationSources = useMemo5(() => {
6635
6651
  const sources = /* @__PURE__ */ new Map();
6636
6652
  for (const item of resolvedItems) {
@@ -6690,6 +6706,149 @@ function MessageTimeline({
6690
6706
  const pendingReaderLeaveRef = useRef9(false);
6691
6707
  const leaveFallbackRafRef = useRef9(null);
6692
6708
  const foldMemoryRef = useRef9(/* @__PURE__ */ new Map());
6709
+ const [openLiveFolds, setOpenLiveFolds] = useState14(() => /* @__PURE__ */ new Set());
6710
+ const openLiveFoldsRef = useRef9(openLiveFolds);
6711
+ const liveNoteIdsByWorkRef = useRef9(/* @__PURE__ */ new Map());
6712
+ const liveFoldMotionRef = useRef9(null);
6713
+ const liveFoldReserveRef = useRef9(null);
6714
+ const writeScrollTopRef = useRef9(() => {
6715
+ });
6716
+ const reportLiveFold = useCallback3((workId, open) => {
6717
+ const current = openLiveFoldsRef.current;
6718
+ if (current.has(workId) === open) return;
6719
+ const next = new Set(current);
6720
+ if (open) next.add(workId);
6721
+ else next.delete(workId);
6722
+ openLiveFoldsRef.current = next;
6723
+ liveFoldMotionRef.current?.finish();
6724
+ const scroller = scrollRef.current;
6725
+ const rows = (liveNoteIdsByWorkRef.current.get(workId) ?? []).flatMap((id) => {
6726
+ const row = scroller?.querySelector(
6727
+ `[data-og-live-note-id="${cssEscapeAttribute(id)}"]`
6728
+ );
6729
+ return row ? [row] : [];
6730
+ });
6731
+ if (!scroller || rows.length === 0) {
6732
+ setOpenLiveFolds(next);
6733
+ return;
6734
+ }
6735
+ const header = scroller.querySelector(
6736
+ `[data-og-work-id="${cssEscapeAttribute(workId)}"] [data-og-work-header="outer"]`
6737
+ );
6738
+ const viewTop = scroller.getBoundingClientRect().top;
6739
+ const headerTop = header?.getBoundingClientRect().top;
6740
+ if (!open && header && headerTop !== void 0 && (headerTop < viewTop || headerTop > viewTop + scroller.clientHeight)) {
6741
+ setOpenLiveFolds(next);
6742
+ requestFrame(
6743
+ () => requestFrame(() => {
6744
+ const row = header.closest("[data-og-timeline-group-anchor]");
6745
+ if (!row?.isConnected) return;
6746
+ const box = row.getBoundingClientRect();
6747
+ const top = scroller.getBoundingClientRect().top;
6748
+ const bottom = top + scroller.clientHeight;
6749
+ if (box.bottom > bottom || box.top < top)
6750
+ writeScrollTopRef.current(scroller, scroller.scrollTop + box.bottom - bottom + 24);
6751
+ scheduleQuestionNavRef.current();
6752
+ })
6753
+ );
6754
+ return;
6755
+ }
6756
+ const readerTop = lastScrollTopRef.current;
6757
+ const reserve = readerTop > 0.5 ? scroller.clientHeight : 0;
6758
+ const loan = {};
6759
+ if (reserve > 0) {
6760
+ liveFoldReserveRef.current = loan;
6761
+ scroller.style.paddingBottom = `calc(1.5rem + ${reserve}px)`;
6762
+ if (Math.abs(scroller.scrollTop - readerTop) > 0.5)
6763
+ writeScrollTopRef.current(scroller, readerTop);
6764
+ }
6765
+ const releaseReserve = (deadline) => {
6766
+ if (reserve === 0 || liveFoldReserveRef.current !== loan) return;
6767
+ const needed = scroller.scrollTop + scroller.clientHeight - (scroller.scrollHeight - reserve);
6768
+ if (needed > 0.5 && performance.now() < deadline && scroller.isConnected) {
6769
+ requestFrame(() => releaseReserve(deadline));
6770
+ return;
6771
+ }
6772
+ liveFoldReserveRef.current = null;
6773
+ scroller.style.removeProperty("padding-bottom");
6774
+ };
6775
+ const workRow = header?.closest("[data-og-timeline-group-anchor]") ?? null;
6776
+ const rowStart = workRow?.getBoundingClientRect().top;
6777
+ const viewBottom = viewTop + scroller.clientHeight;
6778
+ let landing = open && rowStart !== void 0 ? Math.max(rows[0].getBoundingClientRect().top, viewTop) : null;
6779
+ const heights = rows.map((row) => open ? row.offsetHeight : 0);
6780
+ const apply = (progress) => {
6781
+ const shown = open ? 1 - progress : progress;
6782
+ rows.forEach((note, index) => {
6783
+ note.style.marginTop = `${-LIVE_NOTE_GAP_PX}px`;
6784
+ note.style.paddingTop = `${LIVE_NOTE_GAP_PX * shown}px`;
6785
+ note.style.height = `${(heights[index] + LIVE_NOTE_GAP_PX) * shown}px`;
6786
+ note.style.opacity = String(shown);
6787
+ });
6788
+ if (workRow && rowStart !== void 0 && landing !== null) {
6789
+ const drift = workRow.getBoundingClientRect().top - (rowStart + (landing - rowStart) * progress);
6790
+ if (Math.abs(drift) > 0.5) writeScrollTopRef.current(scroller, scroller.scrollTop + drift);
6791
+ }
6792
+ };
6793
+ for (const row of rows) {
6794
+ row.style.boxSizing = "border-box";
6795
+ row.style.overflow = "hidden";
6796
+ row.style.overflowAnchor = "none";
6797
+ }
6798
+ scroller.style.overflowAnchor = "none";
6799
+ apply(0);
6800
+ const fold = {
6801
+ frame: null,
6802
+ finish: () => {
6803
+ if (fold.frame != null) cancelFrame(fold.frame);
6804
+ for (const row of rows) {
6805
+ for (const property of [
6806
+ "height",
6807
+ "margin-top",
6808
+ "padding-top",
6809
+ "opacity",
6810
+ "overflow",
6811
+ "overflow-anchor",
6812
+ "box-sizing"
6813
+ ])
6814
+ row.style.removeProperty(property);
6815
+ }
6816
+ scroller.style.removeProperty("overflow-anchor");
6817
+ releaseReserve(performance.now() + LIVE_NOTE_RESERVE_MS);
6818
+ scheduleQuestionNavRef.current();
6819
+ if (liveFoldMotionRef.current === fold) liveFoldMotionRef.current = null;
6820
+ }
6821
+ };
6822
+ liveFoldMotionRef.current = fold;
6823
+ const duration = prefersReducedMotion() ? 0 : LIVE_NOTE_FOLD_MS;
6824
+ let began = null;
6825
+ const step = (now) => {
6826
+ fold.frame = null;
6827
+ if (!rows.every((row) => row.isConnected)) return fold.finish();
6828
+ if (!open && began === null) {
6829
+ rows.forEach((note, index) => heights[index] = note.scrollHeight);
6830
+ if (workRow && rowStart !== void 0) {
6831
+ const returning = heights.reduce((sum, height) => sum + height + LIVE_NOTE_GAP_PX, 0);
6832
+ const closedRow = 2 * (header?.getBoundingClientRect().height ?? 0);
6833
+ const lowest = viewBottom - closedRow - 24;
6834
+ landing = Math.min(rowStart + returning, Math.max(lowest, rowStart));
6835
+ }
6836
+ }
6837
+ began ??= now;
6838
+ const linear = duration === 0 ? 1 : Math.min(1, (now - began) / duration);
6839
+ apply(1 - (1 - linear) ** 3);
6840
+ if (linear < 1) fold.frame = requestFrame(step);
6841
+ else fold.finish();
6842
+ };
6843
+ fold.frame = requestFrame(step);
6844
+ setOpenLiveFolds(next);
6845
+ }, []);
6846
+ useEffect9(
6847
+ () => () => {
6848
+ liveFoldMotionRef.current?.finish();
6849
+ },
6850
+ []
6851
+ );
6693
6852
  const userMessageDisclosureMemoryRef = useRef9(/* @__PURE__ */ new Map());
6694
6853
  const seenActivityIdsRef = useRef9(/* @__PURE__ */ new Set());
6695
6854
  const firstItemGroupKeyRef = useRef9(null);
@@ -6700,6 +6859,19 @@ function MessageTimeline({
6700
6859
  const firstKeyChangedForBulk = previousBulkFirstKeyRef.current !== void 0 && previousBulkFirstKeyRef.current !== firstGroupKey;
6701
6860
  const bulkRender = allGroups.length > 0 && (bulkActive || firstKeyChangedForBulk);
6702
6861
  const groups = useStableTimelineGroupKeys(allGroups, !bulkRender);
6862
+ const [liveNoteFolds, liveNoteIdsByWork] = useMemo5(() => {
6863
+ const folds = /* @__PURE__ */ new Map();
6864
+ const byWork = /* @__PURE__ */ new Map();
6865
+ for (const { group } of groups) {
6866
+ if (group.kind !== "activity" || !group.work?.liveNoteIds) continue;
6867
+ byWork.set(group.id, group.work.liveNoteIds);
6868
+ for (const id of group.work.liveNoteIds) folds.set(id, openLiveFolds.has(group.id));
6869
+ }
6870
+ return [folds, byWork];
6871
+ }, [groups, openLiveFolds]);
6872
+ useLayoutEffect5(() => {
6873
+ liveNoteIdsByWorkRef.current = liveNoteIdsByWork;
6874
+ }, [liveNoteIdsByWork]);
6703
6875
  const turnsWithOutput = useMemo5(
6704
6876
  () => new Set(
6705
6877
  resolvedItems.flatMap(
@@ -6758,6 +6930,7 @@ function MessageTimeline({
6758
6930
  programmaticScrollRef.current -= 1;
6759
6931
  }
6760
6932
  }, []);
6933
+ writeScrollTopRef.current = writeScrollTop;
6761
6934
  const cancelLeaveFallback = useCallback3(() => {
6762
6935
  if (leaveFallbackRafRef.current != null) {
6763
6936
  cancelFrame(leaveFallbackRafRef.current);
@@ -7194,7 +7367,7 @@ function MessageTimeline({
7194
7367
  driveFollowRef.current = driveFollow;
7195
7368
  useEffect9(() => stopFollow, [stopFollow]);
7196
7369
  useEffect9(() => () => cancelLeaveFallback(), [cancelLeaveFallback]);
7197
- useLayoutEffect4(() => {
7370
+ useLayoutEffect5(() => {
7198
7371
  const node = scrollRef.current;
7199
7372
  if (!node) {
7200
7373
  return;
@@ -7348,7 +7521,7 @@ function MessageTimeline({
7348
7521
  rearmOlderPrefetchAfterLeavingTop(node);
7349
7522
  requestOlderIfUnderfilled(node);
7350
7523
  });
7351
- useLayoutEffect4(() => {
7524
+ useLayoutEffect5(() => {
7352
7525
  if (revealed || !allGroups.length) {
7353
7526
  return;
7354
7527
  }
@@ -7382,7 +7555,7 @@ function MessageTimeline({
7382
7555
  }
7383
7556
  };
7384
7557
  }, [revealed, allGroups.length, autoFollow, snapToBottom]);
7385
- useLayoutEffect4(() => {
7558
+ useLayoutEffect5(() => {
7386
7559
  if (allGroups.length > 0) {
7387
7560
  return;
7388
7561
  }
@@ -7418,7 +7591,7 @@ function MessageTimeline({
7418
7591
  requestOlderIfUnderfilled(node);
7419
7592
  }
7420
7593
  });
7421
- useLayoutEffect4(() => {
7594
+ useLayoutEffect5(() => {
7422
7595
  previousBulkFirstKeyRef.current = firstGroupKey;
7423
7596
  if (!bulkRender) {
7424
7597
  return;
@@ -7556,7 +7729,7 @@ function MessageTimeline({
7556
7729
  applyPinned(true);
7557
7730
  }
7558
7731
  }, [hasNewer, autoFollow, applyPinned, snapToBottom, stopFollow]);
7559
- useLayoutEffect4(() => {
7732
+ useLayoutEffect5(() => {
7560
7733
  const node = scrollRef.current;
7561
7734
  if (node && !pinnedRef.current) setAwayFromTip(!isNearBottom(node));
7562
7735
  });
@@ -7694,7 +7867,7 @@ function MessageTimeline({
7694
7867
  {
7695
7868
  render: renderAllowanceExhausted,
7696
7869
  labels: allowanceExhaustedLabels,
7697
- children: /* @__PURE__ */ jsx18(LightboxProvider, { children: /* @__PURE__ */ jsx18(FoldMemoryProvider, { value: foldMemoryRef.current, children: /* @__PURE__ */ jsx18(SeenActivityIdsProvider, { value: seenActivityIdsRef.current, children: /* @__PURE__ */ jsx18(TimelineComputeLabelProvider, { value: computeLabel ?? null, children: /* @__PURE__ */ jsx18(EntranceAnimationProvider, { value: false, children: /* @__PURE__ */ jsx18(TooltipProvider, { delayDuration: 400, children: /* @__PURE__ */ jsx18(TimelineAnnotationSourceRootContext.Provider, { value: scrollRef, children: /* @__PURE__ */ jsxs13(
7870
+ children: /* @__PURE__ */ jsx18(LightboxProvider, { children: /* @__PURE__ */ jsx18(FoldMemoryProvider, { value: foldMemoryRef.current, children: /* @__PURE__ */ jsx18(LiveNoteFoldContext.Provider, { value: reportLiveFold, children: /* @__PURE__ */ jsx18(SeenActivityIdsProvider, { value: seenActivityIdsRef.current, children: /* @__PURE__ */ jsx18(TimelineComputeLabelProvider, { value: computeLabel ?? null, children: /* @__PURE__ */ jsx18(EntranceAnimationProvider, { value: false, children: /* @__PURE__ */ jsx18(TooltipProvider, { delayDuration: 400, children: /* @__PURE__ */ jsx18(TimelineAnnotationSourceRootContext.Provider, { value: scrollRef, children: /* @__PURE__ */ jsxs13(
7698
7871
  "div",
7699
7872
  {
7700
7873
  className: cn("og-root relative flex min-h-0 flex-col", className),
@@ -7881,6 +8054,7 @@ function MessageTimeline({
7881
8054
  ),
7882
8055
  entranceEnabled,
7883
8056
  liveEntranceEnabled: group.kind === "activity" ? !bulkRender : void 0,
8057
+ noteFolded: group.kind === "item" ? liveNoteFolds.get(group.item.id) : void 0,
7884
8058
  context: timelineGroupEntryContext
7885
8059
  }
7886
8060
  )
@@ -8036,7 +8210,7 @@ function MessageTimeline({
8036
8210
  )
8037
8211
  ]
8038
8212
  }
8039
- ) }) }) }) }) }) }) })
8213
+ ) }) }) }) }) }) }) }) })
8040
8214
  }
8041
8215
  );
8042
8216
  return /* @__PURE__ */ jsx18(OpenGeniLinkProvider, { resolveLink, children: timeline });
@@ -8054,7 +8228,9 @@ function useStableTimelineGroupKeys(allGroups, entranceEnabled) {
8054
8228
  const previousByItemId = /* @__PURE__ */ new Map();
8055
8229
  for (const previous of previousRef.current) {
8056
8230
  for (const itemId of timelineGroupItemIds(previous.group)) {
8057
- previousByItemId.set(itemId, previous);
8231
+ if (previous.group.kind === "item" || !previousByItemId.has(itemId)) {
8232
+ previousByItemId.set(itemId, previous);
8233
+ }
8058
8234
  }
8059
8235
  }
8060
8236
  const usedKeys = /* @__PURE__ */ new Set();
@@ -8088,7 +8264,7 @@ function useStableTimelineGroupKeys(allGroups, entranceEnabled) {
8088
8264
  };
8089
8265
  });
8090
8266
  }, [allGroups, entranceEnabled]);
8091
- useLayoutEffect4(() => {
8267
+ useLayoutEffect5(() => {
8092
8268
  previousRef.current = keyedGroups;
8093
8269
  }, [keyedGroups]);
8094
8270
  return keyedGroups;
@@ -8151,6 +8327,7 @@ var TimelineGroupEntry = memo(function TimelineGroupEntry2({
8151
8327
  startupDismissed,
8152
8328
  entranceEnabled,
8153
8329
  liveEntranceEnabled,
8330
+ noteFolded,
8154
8331
  context
8155
8332
  }) {
8156
8333
  const reducedMotion = useReducedMotion3();
@@ -8174,6 +8351,11 @@ var TimelineGroupEntry = memo(function TimelineGroupEntry2({
8174
8351
  "data-og-group-key": groupKey,
8175
8352
  "data-og-prompt": group.kind === "item" && group.item.kind === "user-message" ? "" : void 0,
8176
8353
  tabIndex: group.kind === "item" && group.item.kind === "user-message" ? -1 : void 0,
8354
+ "data-og-live-note": noteFolded === void 0 ? void 0 : noteFolded ? "folded" : "shown",
8355
+ "data-og-live-note-id": noteFolded !== void 0 && group.kind === "item" ? group.item.id : void 0,
8356
+ "aria-hidden": noteFolded || void 0,
8357
+ inert: noteFolded || void 0,
8358
+ className: noteFolded ? "-mt-5 h-0 overflow-hidden opacity-0 [overflow-anchor:none]" : void 0,
8177
8359
  children: /* @__PURE__ */ jsx18(EntranceAnimationProvider, { value: entranceEnabled, liveValue: liveEntranceEnabled, children: /* @__PURE__ */ jsx18(TimelineGroupRenderBoundary, { resetKeys: [group, behavior], children: /* @__PURE__ */ jsx18(UserMessageDisclosureProvider, { value: userMessageDisclosureContext, children: group.kind === "item" ? /* @__PURE__ */ jsx18("div", { children: content }) : /* @__PURE__ */ jsx18(AnimatePresence3, { initial: false, children: /* @__PURE__ */ jsx18(
8178
8360
  motion3.div,
8179
8361
  {
@@ -8214,11 +8396,12 @@ var TimelineGroupView = memo(function TimelineGroupView2({
8214
8396
  const enter = useEntranceAnimation();
8215
8397
  const settleChrome = useTurnSettleOpen();
8216
8398
  const previousSingleActivity = useRef9(void 0);
8217
- useLayoutEffect4(() => {
8399
+ useLayoutEffect5(() => {
8218
8400
  const work = group.kind === "activity" ? group.items.filter((item) => item.kind !== "startup-phase") : [];
8219
8401
  previousSingleActivity.current = work.length === 1 ? work[0] : void 0;
8220
8402
  }, [group]);
8221
8403
  const foldMemory = useFoldMemory();
8404
+ const reportLiveFold = useContext12(LiveNoteFoldContext);
8222
8405
  const containsPresentedImage = timelineGroupContainsPresentedImage(group);
8223
8406
  const hasRememberedImageFold = group.kind === "activity" && containsPresentedImage && foldMemory?.has(group.id);
8224
8407
  const activityShouldFold = group.kind === "activity" && !containsPresentedImage && !!(group.outcome || foldLiveCluster && clusterIsSettled(group));
@@ -8267,37 +8450,42 @@ var TimelineGroupView = memo(function TimelineGroupView2({
8267
8450
  }
8268
8451
  )
8269
8452
  };
8270
- return /* @__PURE__ */ jsx18(
8271
- TurnSummary,
8272
- {
8273
- items: group.items,
8274
- status,
8275
- outcome: group.outcome,
8276
- failureText: group.failureText,
8277
- foldKey: group.id,
8278
- defaultOpen: containsPresentedImage || group.outcome === "failed" || phases.some((item) => item.status === "failed" || item.status === "cancelled") ? true : void 0,
8279
- facets: turnSummary?.facets,
8280
- contextCompactionCount: compactedLandmarkCount(group.work.details),
8281
- children: /* @__PURE__ */ jsx18(TurnRailFrame, { compact: true, children: renderFoldedGroups(
8282
- group.work.details,
8283
- {
8284
- renderMessageActions,
8285
- renderMessageText,
8286
- onOpenSession,
8287
- onMemoryClick,
8288
- onReconnect,
8289
- renderAuthNeeded,
8290
- resolveProviderLogo,
8291
- toolRegistry,
8292
- loadRetainedScreenshot,
8293
- loadRetainedArtifact,
8294
- loadVideoArtifactPlayback,
8295
- turnSummary
8296
- },
8297
- true
8298
- ) })
8299
- },
8300
- "work"
8453
+ return (
8454
+ // Marks this work row for the live-note fold (list keys can be carried
8455
+ // over from an earlier row, so they are not the work id).
8456
+ /* @__PURE__ */ jsx18("div", { className: "contents", "data-og-work-id": group.id, children: /* @__PURE__ */ jsx18(
8457
+ TurnSummary,
8458
+ {
8459
+ items: group.items,
8460
+ status,
8461
+ outcome: group.outcome,
8462
+ failureText: group.failureText,
8463
+ foldKey: group.id,
8464
+ defaultOpen: containsPresentedImage || group.outcome === "failed" || phases.some((item) => item.status === "failed" || item.status === "cancelled") ? true : void 0,
8465
+ facets: turnSummary?.facets,
8466
+ contextCompactionCount: compactedLandmarkCount(group.work.details),
8467
+ onOpenStateChange: group.work.liveNoteIds?.length && reportLiveFold ? (open) => reportLiveFold(group.id, open) : void 0,
8468
+ children: /* @__PURE__ */ jsx18(TurnRailFrame, { compact: true, children: renderFoldedGroups(
8469
+ group.work.details,
8470
+ {
8471
+ renderMessageActions,
8472
+ renderMessageText,
8473
+ onOpenSession,
8474
+ onMemoryClick,
8475
+ onReconnect,
8476
+ renderAuthNeeded,
8477
+ resolveProviderLogo,
8478
+ toolRegistry,
8479
+ loadRetainedScreenshot,
8480
+ loadRetainedArtifact,
8481
+ loadVideoArtifactPlayback,
8482
+ turnSummary
8483
+ },
8484
+ true
8485
+ ) })
8486
+ },
8487
+ "work"
8488
+ ) })
8301
8489
  );
8302
8490
  }
8303
8491
  if (!startupDetails && !insideTurn && !group.outcome && group.items.every(
@@ -8531,7 +8719,7 @@ function useLiveSettleFold(folded) {
8531
8719
  if (!previousFoldedRef.current && folded) {
8532
8720
  latchedRef.current = true;
8533
8721
  }
8534
- useLayoutEffect4(() => {
8722
+ useLayoutEffect5(() => {
8535
8723
  previousFoldedRef.current = folded;
8536
8724
  });
8537
8725
  return latchedRef.current;
@@ -11213,14 +11401,68 @@ import {
11213
11401
  lazy as lazy5,
11214
11402
  Suspense as Suspense6,
11215
11403
  useCallback as useCallback5,
11216
- useEffect as useEffect12,
11217
- useMemo as useMemo7,
11404
+ useEffect as useEffect13,
11405
+ useMemo as useMemo8,
11218
11406
  useRef as useRef11,
11219
- useState as useState17
11407
+ useState as useState18
11220
11408
  } from "react";
11221
11409
 
11410
+ // src/components/session-proxy-scope.tsx
11411
+ import { OpenGeniBrowserClient } from "@opengeni/sdk/browser";
11412
+ import { useEffect as useEffect11, useMemo as useMemo7, useState as useState16 } from "react";
11413
+ import { jsx as jsx22 } from "react/jsx-runtime";
11414
+ function SessionProxyScope({
11415
+ baseUrl,
11416
+ workspaceId,
11417
+ children
11418
+ }) {
11419
+ const client = useMemo7(
11420
+ () => new OpenGeniBrowserClient({ baseUrl, apiContract: "compatible" }),
11421
+ [baseUrl]
11422
+ );
11423
+ const [state, setState] = useState16(
11424
+ workspaceId ? { status: "ready", workspaceId } : { status: "loading" }
11425
+ );
11426
+ useEffect11(() => {
11427
+ if (workspaceId) {
11428
+ setState({ status: "ready", workspaceId });
11429
+ return;
11430
+ }
11431
+ let active = true;
11432
+ setState({ status: "loading" });
11433
+ client.getClientConfig().then(
11434
+ (config) => {
11435
+ if (!active) return;
11436
+ setState(
11437
+ config.workspaceId ? { status: "ready", workspaceId: config.workspaceId } : {
11438
+ status: "error",
11439
+ message: "This server does not report its workspace. Update @opengeni/sdk on the server, or pass workspaceId."
11440
+ }
11441
+ );
11442
+ },
11443
+ (error) => {
11444
+ if (!active) return;
11445
+ setState({
11446
+ status: "error",
11447
+ message: error instanceof Error ? error.message : "Could not load the conversation."
11448
+ });
11449
+ }
11450
+ );
11451
+ return () => {
11452
+ active = false;
11453
+ };
11454
+ }, [client, workspaceId]);
11455
+ if (state.status === "error") {
11456
+ return /* @__PURE__ */ jsx22("div", { role: "alert", className: "og-root p-3 text-og-sm text-og-danger", "data-og-proxy-error": "", children: state.message });
11457
+ }
11458
+ if (state.status === "loading") {
11459
+ return /* @__PURE__ */ jsx22("div", { className: "og-root", "aria-busy": "true", "data-og-proxy-loading": "" });
11460
+ }
11461
+ return /* @__PURE__ */ jsx22(OpenGeniProvider, { client, workspaceId: state.workspaceId, children });
11462
+ }
11463
+
11222
11464
  // src/lib/host-theme.ts
11223
- import { useLayoutEffect as useLayoutEffect5, useEffect as useEffect11, useState as useState16 } from "react";
11465
+ import { useLayoutEffect as useLayoutEffect6, useEffect as useEffect12, useState as useState17 } from "react";
11224
11466
  var HOST_THEME_ROOT_ATTRIBUTE = "data-og-host-theme";
11225
11467
  var HOST_THEME_ATTRIBUTES = [
11226
11468
  "data-theme",
@@ -11423,7 +11665,7 @@ function resolveHostTheme(element) {
11423
11665
  return "light";
11424
11666
  }
11425
11667
  function normalizeToken(value) {
11426
- return value.trim().toLowerCase().replace(/\s+/g, " ");
11668
+ return value.trim().toLowerCase().replace(/\s+/g, " ").replace(/#([\da-f])([\da-f])([\da-f])(?![\da-f])/g, "#$1$1$2$2$3$3").replace(/(^|[\s(,/])0+(\.\d)/g, "$1$2").replace(/(\.\d*?)0+(?=[\s),/%]|$)/g, "$1").replace(/\.(?=[\s),/%]|$)/g, "");
11427
11669
  }
11428
11670
  function hostTokenOverrides(element) {
11429
11671
  const parent = element.parentElement;
@@ -11448,7 +11690,7 @@ function hostSurfaceStyle(theme, background) {
11448
11690
  }
11449
11691
  return style;
11450
11692
  }
11451
- var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect11 : useLayoutEffect5;
11693
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect12 : useLayoutEffect6;
11452
11694
  function designedTheme(overrides) {
11453
11695
  for (const token of ["--og-color-fg", "--og-color-bg", "--og-color-canvas"]) {
11454
11696
  const value = overrides[token];
@@ -11498,7 +11740,7 @@ function resolveHostThemeState(element, preference, surface) {
11498
11740
  function useHostTheme(ref, options) {
11499
11741
  const preference = options.theme ?? "auto";
11500
11742
  const surface = options.surface ?? "host";
11501
- const [state, setState] = useState16({ theme: preference === "auto" ? void 0 : preference, inherited: false, style: null });
11743
+ const [state, setState] = useState17({ theme: preference === "auto" ? void 0 : preference, inherited: false, style: null });
11502
11744
  useIsomorphicLayoutEffect(() => {
11503
11745
  const element = ref.current;
11504
11746
  if (!element || typeof window === "undefined") return;
@@ -11560,14 +11802,19 @@ function useHostTheme(ref, options) {
11560
11802
  }
11561
11803
 
11562
11804
  // src/components/session-conversation.tsx
11563
- import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
11805
+ import { Fragment as Fragment9, jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
11564
11806
  var DEFAULT_CONVERSATION_LABELS = {
11565
11807
  retry: "Retry",
11566
11808
  tryAgain: "Try again"
11567
11809
  };
11568
- function SessionConversation(props) {
11569
- const [attempt, setAttempt] = useState17(0);
11570
- return /* @__PURE__ */ jsx22(
11810
+ function SessionConversation({ baseUrl, ...props }) {
11811
+ if (baseUrl === void 0) return /* @__PURE__ */ jsx23(RetryingConversation, { ...props });
11812
+ const { client: _client, workspaceId, ...rest } = props;
11813
+ return /* @__PURE__ */ jsx23(SessionProxyScope, { baseUrl, workspaceId, children: /* @__PURE__ */ jsx23(RetryingConversation, { ...rest }) });
11814
+ }
11815
+ function RetryingConversation(props) {
11816
+ const [attempt, setAttempt] = useState18(0);
11817
+ return /* @__PURE__ */ jsx23(
11571
11818
  Conversation,
11572
11819
  {
11573
11820
  ...props,
@@ -11616,7 +11863,7 @@ function Conversation({
11616
11863
  const queue = useTurnQueue(sessionId, options);
11617
11864
  const human = useHumanInputRequests(sessionId, options);
11618
11865
  const control = useSessionControl(sessionId, scope);
11619
- const approvals = useMemo7(() => projectPendingApprovals(feed.events), [feed.events]);
11866
+ const approvals = useMemo8(() => projectPendingApprovals(feed.events), [feed.events]);
11620
11867
  const files = useFileAttachments(scope);
11621
11868
  const uploadsEnabled = attachmentsRequested && config.uploads;
11622
11869
  const status = feed.sessionStatus ?? detail.session?.status;
@@ -11646,7 +11893,7 @@ function Conversation({
11646
11893
  sessionId
11647
11894
  );
11648
11895
  const inheritedLinks = useOpenGeniLinkResolver();
11649
- const defaultLinks = useMemo7(
11896
+ const defaultLinks = useMemo8(
11650
11897
  () => sessionLinkResolver({
11651
11898
  client: context.client,
11652
11899
  workspaceId: context.workspaceId,
@@ -11658,14 +11905,14 @@ function Conversation({
11658
11905
  const onOpenArtifactRef = useRef11(onOpenArtifact);
11659
11906
  onOpenArtifactRef.current = onOpenArtifact;
11660
11907
  const opensArtifacts = onOpenArtifact !== void 0;
11661
- const viewerLinks = useMemo7(
11908
+ const viewerLinks = useMemo8(
11662
11909
  () => opensArtifacts ? viewerLinkResolver({
11663
11910
  workspaceId: context.workspaceId,
11664
11911
  open: (target) => onOpenArtifactRef.current?.(target)
11665
11912
  }) : null,
11666
11913
  [context.workspaceId, opensArtifacts]
11667
11914
  );
11668
- const links = useMemo7(
11915
+ const links = useMemo8(
11669
11916
  () => chainLinkResolvers(resolveLink, viewerLinks, inheritedLinks, defaultLinks) ?? void 0,
11670
11917
  [resolveLink, viewerLinks, inheritedLinks, defaultLinks]
11671
11918
  );
@@ -11698,8 +11945,8 @@ function Conversation({
11698
11945
  className: "mx-auto flex w-full max-w-3xl shrink-0 items-center gap-3 rounded-og-md border border-og-status-failed/30 bg-og-status-failed/10 px-3 py-2 text-og-sm text-og-fg",
11699
11946
  "data-og-conversation-error": "",
11700
11947
  children: [
11701
- /* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1", children: formatError(error) }),
11702
- /* @__PURE__ */ jsx22(
11948
+ /* @__PURE__ */ jsx23("span", { className: "min-w-0 flex-1", children: formatError(error) }),
11949
+ /* @__PURE__ */ jsx23(
11703
11950
  "button",
11704
11951
  {
11705
11952
  type: "button",
@@ -11718,8 +11965,8 @@ function Conversation({
11718
11965
  className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-3 px-6 text-center",
11719
11966
  "data-og-conversation-error": "",
11720
11967
  children: [
11721
- /* @__PURE__ */ jsx22("p", { className: "max-w-sm text-og-base text-og-fg-muted", children: formatError(feed.error) }),
11722
- /* @__PURE__ */ jsx22(
11968
+ /* @__PURE__ */ jsx23("p", { className: "max-w-sm text-og-base text-og-fg-muted", children: formatError(feed.error) }),
11969
+ /* @__PURE__ */ jsx23(
11723
11970
  "button",
11724
11971
  {
11725
11972
  type: "button",
@@ -11730,7 +11977,7 @@ function Conversation({
11730
11977
  )
11731
11978
  ]
11732
11979
  }
11733
- ) : /* @__PURE__ */ jsx22(
11980
+ ) : /* @__PURE__ */ jsx23(
11734
11981
  MessageTimeline,
11735
11982
  {
11736
11983
  renderMessageText,
@@ -11760,14 +12007,14 @@ function Conversation({
11760
12007
  questionNavMinViewportHeight: 320
11761
12008
  }
11762
12009
  ),
11763
- importedArchive ? /* @__PURE__ */ jsx22("p", { className: "shrink-0 px-4 py-2 text-center text-sm text-og-muted", role: "status", children: "Archived conversation \xB7 Read only" }) : /* @__PURE__ */ jsxs17(Fragment9, { children: [
12010
+ importedArchive ? /* @__PURE__ */ jsx23("p", { className: "shrink-0 px-4 py-2 text-center text-sm text-og-muted", role: "status", children: "Archived conversation \xB7 Read only" }) : /* @__PURE__ */ jsxs17(Fragment9, { children: [
11764
12011
  /* @__PURE__ */ jsxs17(
11765
12012
  "div",
11766
12013
  {
11767
12014
  className: "relative z-20 min-h-0 max-h-[40%] shrink-0 overflow-y-auto empty:hidden",
11768
12015
  "data-og-conversation-inputs": "",
11769
12016
  children: [
11770
- approvals.length > 0 && !terminal ? /* @__PURE__ */ jsx22(
12017
+ approvals.length > 0 && !terminal ? /* @__PURE__ */ jsx23(
11771
12018
  ApprovalSurface,
11772
12019
  {
11773
12020
  className: "mx-auto max-w-3xl",
@@ -11782,7 +12029,7 @@ function Conversation({
11782
12029
  error: control.error
11783
12030
  }
11784
12031
  ) : null,
11785
- /* @__PURE__ */ jsx22(
12032
+ /* @__PURE__ */ jsx23(
11786
12033
  HumanInputSurface,
11787
12034
  {
11788
12035
  className: "mx-auto max-w-3xl",
@@ -11797,7 +12044,7 @@ function Conversation({
11797
12044
  decisionButtons: true
11798
12045
  }
11799
12046
  ),
11800
- terminal ? /* @__PURE__ */ jsx22(SessionChrome, { queue, sessionStatus: status, readOnly: true }) : /* @__PURE__ */ jsx22(
12047
+ terminal ? /* @__PURE__ */ jsx23(SessionChrome, { queue, sessionStatus: status, readOnly: true }) : /* @__PURE__ */ jsx23(
11801
12048
  SessionChrome,
11802
12049
  {
11803
12050
  queue,
@@ -11809,12 +12056,12 @@ function Conversation({
11809
12056
  ]
11810
12057
  }
11811
12058
  ),
11812
- /* @__PURE__ */ jsx22(
12059
+ /* @__PURE__ */ jsx23(
11813
12060
  "div",
11814
12061
  {
11815
12062
  className: "relative z-20 mx-auto w-full max-w-3xl shrink-0",
11816
12063
  "data-og-conversation-composer": "",
11817
- children: /* @__PURE__ */ jsx22(
12064
+ children: /* @__PURE__ */ jsx23(
11818
12065
  ChatComposer,
11819
12066
  {
11820
12067
  runControl: "stop",
@@ -11823,7 +12070,7 @@ function Conversation({
11823
12070
  composer,
11824
12071
  attachments: uploadsEnabled ? files : void 0,
11825
12072
  disabled: terminal || composerProps?.disabled,
11826
- controlsStart: composerProps?.controlsStart ?? (showModelPicker && composer.policy && /* @__PURE__ */ jsx22(
12073
+ controlsStart: composerProps?.controlsStart ?? (showModelPicker && composer.policy && /* @__PURE__ */ jsx23(
11827
12074
  ModelPolicyPicker,
11828
12075
  {
11829
12076
  groupPresentation: modelPickerProps?.groupPresentation,
@@ -11859,7 +12106,7 @@ var LazyChatInteractiveBlock = lazy5(
11859
12106
  }))
11860
12107
  );
11861
12108
  function useDefaultInteractiveBlock(client, workspaceId, sessionId) {
11862
- const scoped = useMemo7(() => {
12109
+ const scoped = useMemo8(() => {
11863
12110
  let resolved = null;
11864
12111
  const get = () => {
11865
12112
  const candidate = client;
@@ -11877,17 +12124,17 @@ function useDefaultInteractiveBlock(client, workspaceId, sessionId) {
11877
12124
  };
11878
12125
  }, [client, sessionId]);
11879
12126
  return useCallback5(
11880
- (block) => /* @__PURE__ */ jsx22(Suspense6, { fallback: /* @__PURE__ */ jsx22("span", { role: "status", children: "Loading preview\u2026" }), children: /* @__PURE__ */ jsx22(LazyChatInteractiveBlock, { workspaceId, client: scoped, ...block }) }),
12127
+ (block) => /* @__PURE__ */ jsx23(Suspense6, { fallback: /* @__PURE__ */ jsx23("span", { role: "status", children: "Loading preview\u2026" }), children: /* @__PURE__ */ jsx23(LazyChatInteractiveBlock, { workspaceId, client: scoped, ...block }) }),
11881
12128
  [scoped, workspaceId]
11882
12129
  );
11883
12130
  }
11884
12131
  function useClientConfigFlags(client) {
11885
- const [flags, setFlags] = useState17({
12132
+ const [flags, setFlags] = useState18({
11886
12133
  uploads: false,
11887
12134
  modelSelection: false,
11888
12135
  sandboxFiles: false
11889
12136
  });
11890
- useEffect12(() => {
12137
+ useEffect13(() => {
11891
12138
  let live = true;
11892
12139
  client.getClientConfig().then(
11893
12140
  (config) => {
@@ -11910,7 +12157,7 @@ function useClientConfigFlags(client) {
11910
12157
  }
11911
12158
 
11912
12159
  // src/hooks/use-workspace-sessions.ts
11913
- import { useCallback as useCallback6, useEffect as useEffect13, useRef as useRef12 } from "react";
12160
+ import { useCallback as useCallback6, useEffect as useEffect14, useRef as useRef12 } from "react";
11914
12161
  function useWorkspaceSessions(options = {}) {
11915
12162
  const { client, workspaceId } = useOpenGeni(options);
11916
12163
  const projection = options.projection;
@@ -11946,7 +12193,7 @@ function useWorkspaceSessions(options = {}) {
11946
12193
  ].join("\0");
11947
12194
  const previousQueryKey = useRef12(queryKey);
11948
12195
  const queryKeyTransition = previousQueryKey.current !== queryKey;
11949
- useEffect13(() => {
12196
+ useEffect14(() => {
11950
12197
  previousQueryKey.current = queryKey;
11951
12198
  }, [queryKey]);
11952
12199
  const load = useCallback6(
@@ -12031,8 +12278,8 @@ function useWorkspaceSessions(options = {}) {
12031
12278
  // src/components/session-list.tsx
12032
12279
  import { deriveSessionDisplayTitle } from "@opengeni/sdk";
12033
12280
  import { ArchiveIcon, PencilIcon as PencilIcon2, PlusIcon } from "lucide-react";
12034
- import { useEffect as useEffect14, useRef as useRef13, useState as useState18 } from "react";
12035
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
12281
+ import { useEffect as useEffect15, useRef as useRef13, useState as useState19 } from "react";
12282
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
12036
12283
  var DEFAULT_LABELS = {
12037
12284
  heading: "Chats",
12038
12285
  newChat: "New chat",
@@ -12061,7 +12308,7 @@ function SessionList({
12061
12308
  const labels = { ...DEFAULT_LABELS, ...labelOverrides };
12062
12309
  const scope = { client, workspaceId };
12063
12310
  const context = useOpenGeni(scope);
12064
- const [limit, setLimit] = useState18(pageSize);
12311
+ const [limit, setLimit] = useState19(pageSize);
12065
12312
  const list = useWorkspaceSessions({
12066
12313
  ...scope,
12067
12314
  parentSessionId: null,
@@ -12071,14 +12318,14 @@ function SessionList({
12071
12318
  });
12072
12319
  const refresh = list.refresh;
12073
12320
  const firstRefreshKey = useRef13(refreshKey);
12074
- useEffect14(() => {
12321
+ useEffect15(() => {
12075
12322
  if (Object.is(refreshKey, firstRefreshKey.current)) return;
12076
12323
  firstRefreshKey.current = refreshKey;
12077
12324
  void refresh();
12078
12325
  }, [refresh, refreshKey]);
12079
- const [editing, setEditing] = useState18(null);
12080
- const [busy, setBusy] = useState18(null);
12081
- const [error, setError] = useState18(null);
12326
+ const [editing, setEditing] = useState19(null);
12327
+ const [busy, setBusy] = useState19(null);
12328
+ const [error, setError] = useState19(null);
12082
12329
  const formatError = useErrorMessage();
12083
12330
  const archiveClient = context.client;
12084
12331
  const canArchive = archive && typeof archiveClient.updateSessionArchive === "function";
@@ -12121,7 +12368,7 @@ function SessionList({
12121
12368
  "data-og-session-list": "",
12122
12369
  children: [
12123
12370
  /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-2 px-2 pb-1 pt-2", children: [
12124
- /* @__PURE__ */ jsx23("h2", { className: "text-og-sm font-semibold text-og-fg-muted", children: labels.heading }),
12371
+ /* @__PURE__ */ jsx24("h2", { className: "text-og-sm font-semibold text-og-fg-muted", children: labels.heading }),
12125
12372
  onNewChat ? /* @__PURE__ */ jsxs18(
12126
12373
  "button",
12127
12374
  {
@@ -12130,22 +12377,22 @@ function SessionList({
12130
12377
  className: "inline-flex items-center gap-1 rounded-md px-2 py-1 text-og-control text-og-fg hover:bg-og-surface-2",
12131
12378
  "data-og-new-chat": "",
12132
12379
  children: [
12133
- /* @__PURE__ */ jsx23(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
12380
+ /* @__PURE__ */ jsx24(PlusIcon, { className: "size-3.5", "aria-hidden": true }),
12134
12381
  labels.newChat
12135
12382
  ]
12136
12383
  }
12137
12384
  ) : null
12138
12385
  ] }),
12139
- error || list.error ? /* @__PURE__ */ jsx23("p", { role: "alert", className: "px-2 text-og-xs text-og-status-failed", children: formatError(error ? error.cause : list.error) }) : null,
12386
+ error || list.error ? /* @__PURE__ */ jsx24("p", { role: "alert", className: "px-2 text-og-xs text-og-status-failed", children: formatError(error ? error.cause : list.error) }) : null,
12140
12387
  /* @__PURE__ */ jsxs18("ul", { className: "flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto px-1 pb-2", children: [
12141
- list.loading && sessions.length === 0 ? /* @__PURE__ */ jsx23("li", { className: "px-2 py-2 text-og-xs text-og-fg-subtle", children: labels.loading }) : null,
12142
- !list.loading && !list.error && sessions.length === 0 ? /* @__PURE__ */ jsx23("li", { className: "px-2 py-2 text-og-xs text-og-fg-subtle", children: labels.empty }) : null,
12388
+ list.loading && sessions.length === 0 ? /* @__PURE__ */ jsx24("li", { className: "px-2 py-2 text-og-xs text-og-fg-subtle", children: labels.loading }) : null,
12389
+ !list.loading && !list.error && sessions.length === 0 ? /* @__PURE__ */ jsx24("li", { className: "px-2 py-2 text-og-xs text-og-fg-subtle", children: labels.empty }) : null,
12143
12390
  sessions.map((session) => {
12144
12391
  const selected = session.id === selectedSessionId;
12145
12392
  const title = deriveSessionDisplayTitle(session);
12146
12393
  if (editing?.id === session.id) {
12147
- return /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsxs18("form", { onSubmit: saveTitle, className: "flex items-center gap-1 px-1 py-1", children: [
12148
- /* @__PURE__ */ jsx23(
12394
+ return /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsxs18("form", { onSubmit: saveTitle, className: "flex items-center gap-1 px-1 py-1", children: [
12395
+ /* @__PURE__ */ jsx24(
12149
12396
  "input",
12150
12397
  {
12151
12398
  "aria-label": labels.rename,
@@ -12159,7 +12406,7 @@ function SessionList({
12159
12406
  className: "min-w-0 flex-1 rounded-md border border-og-border bg-og-bg px-2 py-1 text-og-sm text-og-fg"
12160
12407
  }
12161
12408
  ),
12162
- /* @__PURE__ */ jsx23(
12409
+ /* @__PURE__ */ jsx24(
12163
12410
  "button",
12164
12411
  {
12165
12412
  type: "submit",
@@ -12183,36 +12430,36 @@ function SessionList({
12183
12430
  ),
12184
12431
  "data-og-session-row": "",
12185
12432
  children: [
12186
- /* @__PURE__ */ jsx23("span", { className: "w-full truncate pr-12 text-og-sm text-og-fg", children: title }),
12187
- /* @__PURE__ */ jsx23("span", { className: "text-og-xs text-og-fg-subtle", children: formatRelativeTime(session.updatedAt) })
12433
+ /* @__PURE__ */ jsx24("span", { className: "w-full truncate pr-12 text-og-sm text-og-fg", children: title }),
12434
+ /* @__PURE__ */ jsx24("span", { className: "text-og-xs text-og-fg-subtle", children: formatRelativeTime(session.updatedAt) })
12188
12435
  ]
12189
12436
  }
12190
12437
  ),
12191
12438
  /* @__PURE__ */ jsxs18("span", { className: "absolute right-1 top-1.5 hidden gap-0.5 group-focus-within:flex group-hover:flex", children: [
12192
- rename ? /* @__PURE__ */ jsx23(
12439
+ rename ? /* @__PURE__ */ jsx24(
12193
12440
  "button",
12194
12441
  {
12195
12442
  type: "button",
12196
12443
  "aria-label": `${labels.rename}: ${title}`,
12197
12444
  onClick: () => setEditing({ id: session.id, title: session.title ?? title }),
12198
12445
  className: "rounded p-1 text-og-fg-subtle hover:bg-og-surface-3 hover:text-og-fg",
12199
- children: /* @__PURE__ */ jsx23(PencilIcon2, { className: "size-3.5", "aria-hidden": true })
12446
+ children: /* @__PURE__ */ jsx24(PencilIcon2, { className: "size-3.5", "aria-hidden": true })
12200
12447
  }
12201
12448
  ) : null,
12202
- canArchive ? /* @__PURE__ */ jsx23(
12449
+ canArchive ? /* @__PURE__ */ jsx24(
12203
12450
  "button",
12204
12451
  {
12205
12452
  type: "button",
12206
12453
  "aria-label": `${labels.archive}: ${title}`,
12207
12454
  onClick: () => archiveSession(session),
12208
12455
  className: "rounded p-1 text-og-fg-subtle hover:bg-og-surface-3 hover:text-og-fg",
12209
- children: /* @__PURE__ */ jsx23(ArchiveIcon, { className: "size-3.5", "aria-hidden": true })
12456
+ children: /* @__PURE__ */ jsx24(ArchiveIcon, { className: "size-3.5", "aria-hidden": true })
12210
12457
  }
12211
12458
  ) : null
12212
12459
  ] })
12213
12460
  ] }, session.id);
12214
12461
  }),
12215
- list.nextCursor ? /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsx23(
12462
+ list.nextCursor ? /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsx24(
12216
12463
  "button",
12217
12464
  {
12218
12465
  type: "button",
@@ -12229,8 +12476,8 @@ function SessionList({
12229
12476
 
12230
12477
  // src/components/open-geni-chat.tsx
12231
12478
  import { ArrowUpIcon as ArrowUpIcon3, LoaderCircleIcon, MenuIcon, XIcon as XIcon3 } from "lucide-react";
12232
- import { useCallback as useCallback7, useRef as useRef14, useState as useState19 } from "react";
12233
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
12479
+ import { useCallback as useCallback7, useRef as useRef14, useState as useState20 } from "react";
12480
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
12234
12481
  var DEFAULT_LABELS2 = {
12235
12482
  openChats: "Open chats",
12236
12483
  closeChats: "Close chats",
@@ -12239,7 +12486,12 @@ var DEFAULT_LABELS2 = {
12239
12486
  send: "Send",
12240
12487
  newChatUnavailable: "New chats are not enabled for this product."
12241
12488
  };
12242
- function OpenGeniChat({
12489
+ function OpenGeniChat({ baseUrl, ...props }) {
12490
+ if (baseUrl === void 0) return /* @__PURE__ */ jsx25(Chat, { ...props });
12491
+ const { client: _client, workspaceId, ...rest } = props;
12492
+ return /* @__PURE__ */ jsx25(SessionProxyScope, { baseUrl, workspaceId, children: /* @__PURE__ */ jsx25(Chat, { ...rest }) });
12493
+ }
12494
+ function Chat({
12243
12495
  client,
12244
12496
  workspaceId,
12245
12497
  sessionId: controlledSessionId,
@@ -12258,10 +12510,10 @@ function OpenGeniChat({
12258
12510
  const labels = { ...DEFAULT_LABELS2, ...labelOverrides };
12259
12511
  const scope = { client, workspaceId };
12260
12512
  const context = useOpenGeni(scope);
12261
- const [uncontrolled, setUncontrolled] = useState19(defaultSessionId);
12513
+ const [uncontrolled, setUncontrolled] = useState20(defaultSessionId);
12262
12514
  const selected = controlledSessionId !== void 0 ? controlledSessionId : uncontrolled;
12263
- const [drawerOpen, setDrawerOpen] = useState19(false);
12264
- const [listRevision, setListRevision] = useState19(0);
12515
+ const [drawerOpen, setDrawerOpen] = useState20(false);
12516
+ const [listRevision, setListRevision] = useState20(0);
12265
12517
  const root = useRef14(null);
12266
12518
  const hostTheme = useHostTheme(root, { theme, surface });
12267
12519
  const select = useCallback7(
@@ -12285,7 +12537,7 @@ function OpenGeniChat({
12285
12537
  },
12286
12538
  [context.client, context.workspaceId, createSession, labels.newChatUnavailable]
12287
12539
  );
12288
- const list = /* @__PURE__ */ jsx24(
12540
+ const list = /* @__PURE__ */ jsx25(
12289
12541
  SessionList,
12290
12542
  {
12291
12543
  ...scope,
@@ -12314,7 +12566,7 @@ function OpenGeniChat({
12314
12566
  "data-og-host-theme": "",
12315
12567
  "data-og-chat": "",
12316
12568
  children: [
12317
- /* @__PURE__ */ jsx24(
12569
+ /* @__PURE__ */ jsx25(
12318
12570
  "aside",
12319
12571
  {
12320
12572
  className: "og-chat-sidebar min-h-0 w-64 shrink-0 flex-col border-r border-og-border",
@@ -12324,19 +12576,19 @@ function OpenGeniChat({
12324
12576
  ),
12325
12577
  drawerOpen ? /* @__PURE__ */ jsxs19("div", { className: "og-chat-drawer absolute inset-0 z-30 flex", "data-og-chat-drawer": "", children: [
12326
12578
  /* @__PURE__ */ jsxs19("div", { className: "flex h-full w-[min(20rem,85%)] flex-col border-r border-og-border bg-og-bg shadow-og-lg", children: [
12327
- /* @__PURE__ */ jsx24("div", { className: "flex justify-end p-1", children: /* @__PURE__ */ jsx24(
12579
+ /* @__PURE__ */ jsx25("div", { className: "flex justify-end p-1", children: /* @__PURE__ */ jsx25(
12328
12580
  "button",
12329
12581
  {
12330
12582
  type: "button",
12331
12583
  "aria-label": labels.closeChats,
12332
12584
  onClick: () => setDrawerOpen(false),
12333
12585
  className: "rounded p-1.5 text-og-fg-muted hover:bg-og-surface-2",
12334
- children: /* @__PURE__ */ jsx24(XIcon3, { className: "size-4", "aria-hidden": true })
12586
+ children: /* @__PURE__ */ jsx25(XIcon3, { className: "size-4", "aria-hidden": true })
12335
12587
  }
12336
12588
  ) }),
12337
- /* @__PURE__ */ jsx24("div", { className: "min-h-0 flex-1", children: list })
12589
+ /* @__PURE__ */ jsx25("div", { className: "min-h-0 flex-1", children: list })
12338
12590
  ] }),
12339
- /* @__PURE__ */ jsx24(
12591
+ /* @__PURE__ */ jsx25(
12340
12592
  "button",
12341
12593
  {
12342
12594
  type: "button",
@@ -12348,7 +12600,7 @@ function OpenGeniChat({
12348
12600
  ] }) : null,
12349
12601
  /* @__PURE__ */ jsxs19("main", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [
12350
12602
  /* @__PURE__ */ jsxs19("div", { className: "og-chat-menu flex items-center gap-2 px-2 py-1", children: [
12351
- /* @__PURE__ */ jsx24(
12603
+ /* @__PURE__ */ jsx25(
12352
12604
  "button",
12353
12605
  {
12354
12606
  type: "button",
@@ -12357,12 +12609,12 @@ function OpenGeniChat({
12357
12609
  onClick: () => setDrawerOpen(true),
12358
12610
  className: "rounded p-1.5 text-og-fg-muted hover:bg-og-surface-2",
12359
12611
  "data-og-chat-menu": "",
12360
- children: /* @__PURE__ */ jsx24(MenuIcon, { className: "size-4", "aria-hidden": true })
12612
+ children: /* @__PURE__ */ jsx25(MenuIcon, { className: "size-4", "aria-hidden": true })
12361
12613
  }
12362
12614
  ),
12363
- /* @__PURE__ */ jsx24("span", { className: "text-og-sm font-semibold text-og-fg-muted", children: labels.heading })
12615
+ /* @__PURE__ */ jsx25("span", { className: "text-og-sm font-semibold text-og-fg-muted", children: labels.heading })
12364
12616
  ] }),
12365
- /* @__PURE__ */ jsx24("div", { className: "og-chat-main min-h-0 flex-1 px-3 pb-3 pt-1", children: selected ? /* @__PURE__ */ jsx24(
12617
+ /* @__PURE__ */ jsx25("div", { className: "og-chat-main min-h-0 flex-1 px-3 pb-3 pt-1", children: selected ? /* @__PURE__ */ jsx25(
12366
12618
  SessionConversation,
12367
12619
  {
12368
12620
  ...conversationProps,
@@ -12370,7 +12622,7 @@ function OpenGeniChat({
12370
12622
  sessionId: selected,
12371
12623
  height: "100%"
12372
12624
  }
12373
- ) : /* @__PURE__ */ jsx24(
12625
+ ) : /* @__PURE__ */ jsx25(
12374
12626
  NewChat,
12375
12627
  {
12376
12628
  labels,
@@ -12391,9 +12643,9 @@ function NewChat({
12391
12643
  create,
12392
12644
  onCreated
12393
12645
  }) {
12394
- const [text, setText] = useState19("");
12395
- const [sending, setSending] = useState19(false);
12396
- const [error, setError] = useState19(null);
12646
+ const [text, setText] = useState20("");
12647
+ const [sending, setSending] = useState20(false);
12648
+ const [error, setError] = useState20(null);
12397
12649
  const formatError = useErrorMessage();
12398
12650
  const idempotencyKey = useRef14(crypto.randomUUID());
12399
12651
  const submit = async (event) => {
@@ -12420,8 +12672,8 @@ function NewChat({
12420
12672
  className: "mx-auto box-border flex h-full w-full max-w-3xl flex-col gap-4 p-3",
12421
12673
  "data-og-new-chat-composer": "",
12422
12674
  children: [
12423
- /* @__PURE__ */ jsx24("div", { "aria-hidden": true, className: "min-h-0 flex-[2]" }),
12424
- labels.newChatTitle ? /* @__PURE__ */ jsx24("p", { className: "text-center text-og-md font-medium text-og-fg", children: labels.newChatTitle }) : null,
12675
+ /* @__PURE__ */ jsx25("div", { "aria-hidden": true, className: "min-h-0 flex-[2]" }),
12676
+ labels.newChatTitle ? /* @__PURE__ */ jsx25("p", { className: "text-center text-og-md font-medium text-og-fg", children: labels.newChatTitle }) : null,
12425
12677
  /* @__PURE__ */ jsxs19(
12426
12678
  "div",
12427
12679
  {
@@ -12431,7 +12683,7 @@ function NewChat({
12431
12683
  "focus-within:border-og-accent/50 focus-within:shadow-og-glow"
12432
12684
  ),
12433
12685
  children: [
12434
- /* @__PURE__ */ jsx24(
12686
+ /* @__PURE__ */ jsx25(
12435
12687
  "textarea",
12436
12688
  {
12437
12689
  value: text,
@@ -12449,7 +12701,7 @@ function NewChat({
12449
12701
  className: "min-h-12 flex-1 resize-none bg-transparent py-1 text-og-composer text-og-fg outline-hidden placeholder:text-og-fg-subtle md:text-og-composer-wide"
12450
12702
  }
12451
12703
  ),
12452
- /* @__PURE__ */ jsx24(
12704
+ /* @__PURE__ */ jsx25(
12453
12705
  "button",
12454
12706
  {
12455
12707
  type: "submit",
@@ -12461,17 +12713,17 @@ function NewChat({
12461
12713
  "transition-[background-color,transform,opacity] duration-150 ease-og-spring",
12462
12714
  "hover:bg-og-primary-hover active:scale-95 disabled:cursor-not-allowed disabled:opacity-50"
12463
12715
  ),
12464
- children: sending ? /* @__PURE__ */ jsx24(LoaderCircleIcon, { className: "size-4 animate-og-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx24(ArrowUpIcon3, { className: "size-4", "aria-hidden": true })
12716
+ children: sending ? /* @__PURE__ */ jsx25(LoaderCircleIcon, { className: "size-4 animate-og-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx25(ArrowUpIcon3, { className: "size-4", "aria-hidden": true })
12465
12717
  }
12466
12718
  )
12467
12719
  ]
12468
12720
  }
12469
12721
  ),
12470
- error ? /* @__PURE__ */ jsx24("p", { role: "alert", className: "text-center text-og-sm text-og-status-failed", children: formatError(
12722
+ error ? /* @__PURE__ */ jsx25("p", { role: "alert", className: "text-center text-og-sm text-og-status-failed", children: formatError(
12471
12723
  error.cause,
12472
12724
  error.cause instanceof Error && error.cause.message === labels.newChatUnavailable ? labels.newChatUnavailable : void 0
12473
12725
  ) }) : null,
12474
- /* @__PURE__ */ jsx24("div", { "aria-hidden": true, className: "min-h-0 flex-[3]" })
12726
+ /* @__PURE__ */ jsx25("div", { "aria-hidden": true, className: "min-h-0 flex-[3]" })
12475
12727
  ]
12476
12728
  }
12477
12729
  );
@@ -12479,15 +12731,15 @@ function NewChat({
12479
12731
 
12480
12732
  // src/components/session-commands-panel.tsx
12481
12733
  import { ChevronRightIcon as ChevronRightIcon3, Loader2Icon as Loader2Icon3, SquareIcon } from "lucide-react";
12482
- import { useState as useState20 } from "react";
12483
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
12734
+ import { useState as useState21 } from "react";
12735
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
12484
12736
  function SessionCommandsPanel({
12485
12737
  commands: state,
12486
12738
  readOnly = false
12487
12739
  }) {
12488
12740
  const formatError = useErrorMessage();
12489
- const [pending, setPending] = useState20(null);
12490
- const [error, setError] = useState20(null);
12741
+ const [pending, setPending] = useState21(null);
12742
+ const [error, setError] = useState21(null);
12491
12743
  const active = state.commands.filter(
12492
12744
  (command) => command.state === "running" || command.state === "stopping"
12493
12745
  );
@@ -12503,10 +12755,10 @@ function SessionCommandsPanel({
12503
12755
  }
12504
12756
  };
12505
12757
  return /* @__PURE__ */ jsxs20("div", { className: "space-y-2 text-og-xs", "data-og-session-commands": "", children: [
12506
- state.loading && active.length === 0 ? /* @__PURE__ */ jsx25("p", { role: "status", className: "text-og-fg-muted", children: "Loading commands\u2026" }) : null,
12758
+ state.loading && active.length === 0 ? /* @__PURE__ */ jsx26("p", { role: "status", className: "text-og-fg-muted", children: "Loading commands\u2026" }) : null,
12507
12759
  state.error ? /* @__PURE__ */ jsxs20("div", { role: "alert", className: "flex items-center justify-between gap-2 text-og-danger", children: [
12508
- /* @__PURE__ */ jsx25("span", { children: "Commands unavailable." }),
12509
- /* @__PURE__ */ jsx25(
12760
+ /* @__PURE__ */ jsx26("span", { children: "Commands unavailable." }),
12761
+ /* @__PURE__ */ jsx26(
12510
12762
  "button",
12511
12763
  {
12512
12764
  type: "button",
@@ -12516,8 +12768,8 @@ function SessionCommandsPanel({
12516
12768
  }
12517
12769
  )
12518
12770
  ] }) : null,
12519
- !state.loading && !state.error && active.length === 0 ? /* @__PURE__ */ jsx25("p", { role: "status", className: "text-og-fg-muted", children: "No background commands running." }) : null,
12520
- active.length > 0 ? /* @__PURE__ */ jsx25("ul", { className: "max-h-64 overflow-y-auto overscroll-contain divide-y divide-og-border/40", children: active.map((command) => /* @__PURE__ */ jsxs20("li", { className: "flex items-start gap-3 py-2 first:pt-0 last:pb-0", children: [
12771
+ !state.loading && !state.error && active.length === 0 ? /* @__PURE__ */ jsx26("p", { role: "status", className: "text-og-fg-muted", children: "No background commands running." }) : null,
12772
+ active.length > 0 ? /* @__PURE__ */ jsx26("ul", { className: "max-h-64 overflow-y-auto overscroll-contain divide-y divide-og-border/40", children: active.map((command) => /* @__PURE__ */ jsxs20("li", { className: "flex items-start gap-3 py-2 first:pt-0 last:pb-0", children: [
12521
12773
  /* @__PURE__ */ jsxs20("div", { className: "min-w-0 flex-1", children: [
12522
12774
  /* @__PURE__ */ jsxs20("details", { className: "group/command", children: [
12523
12775
  /* @__PURE__ */ jsxs20(
@@ -12526,8 +12778,8 @@ function SessionCommandsPanel({
12526
12778
  className: "flex cursor-pointer list-none items-center gap-1.5 rounded-og-sm font-mono text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/40",
12527
12779
  title: "Expand command",
12528
12780
  children: [
12529
- /* @__PURE__ */ jsx25(ChevronRightIcon3, { className: "size-3 shrink-0 text-og-fg-subtle transition-transform group-open/command:rotate-90" }),
12530
- /* @__PURE__ */ jsx25(
12781
+ /* @__PURE__ */ jsx26(ChevronRightIcon3, { className: "size-3 shrink-0 text-og-fg-subtle transition-transform group-open/command:rotate-90" }),
12782
+ /* @__PURE__ */ jsx26(
12531
12783
  "span",
12532
12784
  {
12533
12785
  className: "min-w-0 truncate",
@@ -12539,7 +12791,7 @@ function SessionCommandsPanel({
12539
12791
  }
12540
12792
  ),
12541
12793
  /* @__PURE__ */ jsxs20("div", { className: "mt-2 space-y-1", children: [
12542
- /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap break-all font-mono text-og-fg-muted", children: command.commandText ?? (command.commandPreview || "Background command") }),
12794
+ /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap break-all font-mono text-og-fg-muted", children: command.commandText ?? (command.commandPreview || "Background command") }),
12543
12795
  /* @__PURE__ */ jsxs20(
12544
12796
  "time",
12545
12797
  {
@@ -12554,7 +12806,7 @@ function SessionCommandsPanel({
12554
12806
  )
12555
12807
  ] })
12556
12808
  ] }),
12557
- /* @__PURE__ */ jsx25("p", { className: "mt-1 text-og-fg-subtle", children: command.observationStatus === "unavailable" ? command.state === "stopping" ? "Stop requested \xB7 status unavailable" : "Command status unavailable" : command.state === "stopping" ? "Stopping\u2026" : "Running" })
12809
+ /* @__PURE__ */ jsx26("p", { className: "mt-1 text-og-fg-subtle", children: command.observationStatus === "unavailable" ? command.state === "stopping" ? "Stop requested \xB7 status unavailable" : "Command status unavailable" : command.state === "stopping" ? "Stopping\u2026" : "Running" })
12558
12810
  ] }),
12559
12811
  !readOnly ? /* @__PURE__ */ jsxs20(
12560
12812
  "button",
@@ -12565,18 +12817,18 @@ function SessionCommandsPanel({
12565
12817
  onClick: () => void stop(command.id),
12566
12818
  className: "inline-flex min-h-7 shrink-0 items-center gap-1 rounded-og-sm px-2 text-og-fg-muted outline-hidden hover:bg-og-surface-3/70 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent/40 disabled:opacity-50 pointer-coarse:min-h-11",
12567
12819
  children: [
12568
- pending === command.id || command.state === "stopping" ? /* @__PURE__ */ jsx25(Loader2Icon3, { className: "size-3 animate-og-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx25(SquareIcon, { className: "size-3" }),
12820
+ pending === command.id || command.state === "stopping" ? /* @__PURE__ */ jsx26(Loader2Icon3, { className: "size-3 animate-og-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx26(SquareIcon, { className: "size-3" }),
12569
12821
  "Stop"
12570
12822
  ]
12571
12823
  }
12572
12824
  ) : null
12573
12825
  ] }, command.id)) }) : null,
12574
- error ? /* @__PURE__ */ jsx25("p", { role: "alert", className: "text-og-danger", children: error }) : null
12826
+ error ? /* @__PURE__ */ jsx26("p", { role: "alert", className: "text-og-danger", children: error }) : null
12575
12827
  ] });
12576
12828
  }
12577
12829
 
12578
12830
  // src/hooks/use-session-background-commands.ts
12579
- import { useCallback as useCallback8, useEffect as useEffect15, useRef as useRef15 } from "react";
12831
+ import { useCallback as useCallback8, useEffect as useEffect16, useRef as useRef15 } from "react";
12580
12832
  function useSessionBackgroundCommands(sessionId, options = {}) {
12581
12833
  const { client, workspaceId } = useOpenGeni(options);
12582
12834
  const enabled = (options.enabled ?? true) && Boolean(sessionId);
@@ -12584,7 +12836,7 @@ function useSessionBackgroundCommands(sessionId, options = {}) {
12584
12836
  async (signal) => {
12585
12837
  if (!sessionId) return { commands: [] };
12586
12838
  if (!client.listSessionBackgroundCommands) {
12587
- throw new Error("The configured OpenGeni client does not support background commands");
12839
+ throw new Error("The configured Opengeni client does not support background commands");
12588
12840
  }
12589
12841
  return await client.listSessionBackgroundCommands(workspaceId, sessionId, { signal });
12590
12842
  },
@@ -12596,7 +12848,7 @@ function useSessionBackgroundCommands(sessionId, options = {}) {
12596
12848
  });
12597
12849
  const refresh = state.refresh;
12598
12850
  const generation = useRef15(0);
12599
- useEffect15(() => {
12851
+ useEffect16(() => {
12600
12852
  generation.current += 1;
12601
12853
  return () => {
12602
12854
  generation.current += 1;
@@ -12606,7 +12858,7 @@ function useSessionBackgroundCommands(sessionId, options = {}) {
12606
12858
  async (commandId) => {
12607
12859
  if (!sessionId) return;
12608
12860
  if (!client.cancelSessionBackgroundCommand) {
12609
- throw new Error("The configured OpenGeni client does not support background commands");
12861
+ throw new Error("The configured Opengeni client does not support background commands");
12610
12862
  }
12611
12863
  const ticket = generation.current;
12612
12864
  await client.cancelSessionBackgroundCommand(workspaceId, sessionId, commandId);
@@ -12624,7 +12876,7 @@ function useSessionBackgroundCommands(sessionId, options = {}) {
12624
12876
  }
12625
12877
 
12626
12878
  // src/components/session-commands.tsx
12627
- import { jsx as jsx26 } from "react/jsx-runtime";
12879
+ import { jsx as jsx27 } from "react/jsx-runtime";
12628
12880
  function SessionCommands({
12629
12881
  sessionId,
12630
12882
  readOnly = false,
@@ -12634,11 +12886,11 @@ function SessionCommands({
12634
12886
  pollIntervalMs: 3e3,
12635
12887
  ...options
12636
12888
  });
12637
- return /* @__PURE__ */ jsx26(SessionCommandsPanel, { commands, readOnly });
12889
+ return /* @__PURE__ */ jsx27(SessionCommandsPanel, { commands, readOnly });
12638
12890
  }
12639
12891
 
12640
12892
  // src/timeline/startup-timings.tsx
12641
- import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
12893
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
12642
12894
  var LABELS = {
12643
12895
  queue: "Worker queue",
12644
12896
  sandbox: "Sandbox",
@@ -12651,7 +12903,7 @@ var LABELS = {
12651
12903
  };
12652
12904
  function StartupTimings({ phases }) {
12653
12905
  if (!phases.length)
12654
- return /* @__PURE__ */ jsx27("p", { className: "text-og-sm text-og-fg-subtle", children: "No startup timings recorded yet." });
12906
+ return /* @__PURE__ */ jsx28("p", { className: "text-og-sm text-og-fg-subtle", children: "No startup timings recorded yet." });
12655
12907
  const byTurn = /* @__PURE__ */ new Map();
12656
12908
  for (const phase of phases) {
12657
12909
  const group = byTurn.get(phase.turnId) ?? [];
@@ -12667,8 +12919,8 @@ function StartupTimings({ phases }) {
12667
12919
  )
12668
12920
  })).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
12669
12921
  return /* @__PURE__ */ jsxs21("div", { className: "space-y-3", children: [
12670
- /* @__PURE__ */ jsx27("p", { className: "text-og-xs text-og-fg-subtle", children: "Each turn has its own startup. Phases can overlap; durations are not additive." }),
12671
- turns.map((turn, index) => /* @__PURE__ */ jsx27(
12922
+ /* @__PURE__ */ jsx28("p", { className: "text-og-xs text-og-fg-subtle", children: "Each turn has its own startup. Phases can overlap; durations are not additive." }),
12923
+ turns.map((turn, index) => /* @__PURE__ */ jsx28(
12672
12924
  StartupTurn,
12673
12925
  {
12674
12926
  ...turn,
@@ -12687,51 +12939,51 @@ function StartupTurn({
12687
12939
  const status = phases.some((phase) => phase.status === "failed") ? "Failed" : phases.some((phase) => phase.status === "running") ? "In progress" : phases.some((phase) => phase.status === "cancelled") ? "Interrupted" : "Ready";
12688
12940
  return /* @__PURE__ */ jsxs21("details", { open: latest, className: "group border-b border-og-border pb-3", children: [
12689
12941
  /* @__PURE__ */ jsxs21("summary", { className: "cursor-pointer rounded py-3 text-og-sm text-og-fg-muted focus-visible:outline-2 focus-visible:outline-og-accent", children: [
12690
- /* @__PURE__ */ jsx27("span", { className: "font-medium", children: turnId === null ? "Unassigned events" : latest ? "Latest turn" : "Earlier turn" }),
12691
- /* @__PURE__ */ jsx27("span", { className: "ml-2 text-og-xs text-og-fg-subtle", children: new Date(startedAt).toLocaleTimeString([], {
12942
+ /* @__PURE__ */ jsx28("span", { className: "font-medium", children: turnId === null ? "Unassigned events" : latest ? "Latest turn" : "Earlier turn" }),
12943
+ /* @__PURE__ */ jsx28("span", { className: "ml-2 text-og-xs text-og-fg-subtle", children: new Date(startedAt).toLocaleTimeString([], {
12692
12944
  hour: "2-digit",
12693
12945
  minute: "2-digit",
12694
12946
  second: "2-digit"
12695
12947
  }) }),
12696
- /* @__PURE__ */ jsx27(
12948
+ /* @__PURE__ */ jsx28(
12697
12949
  "span",
12698
12950
  {
12699
12951
  className: status === "Failed" ? "ml-2 text-og-xs text-og-status-failed" : "ml-2 text-og-xs text-og-fg-subtle",
12700
12952
  children: status
12701
12953
  }
12702
12954
  ),
12703
- /* @__PURE__ */ jsx27("span", { className: "mt-1 block break-all pl-4 font-og-mono text-og-xs text-og-fg-subtle", children: turnId ?? "No turn ID recorded" })
12955
+ /* @__PURE__ */ jsx28("span", { className: "mt-1 block break-all pl-4 font-og-mono text-og-xs text-og-fg-subtle", children: turnId ?? "No turn ID recorded" })
12704
12956
  ] }),
12705
12957
  /* @__PURE__ */ jsxs21("div", { className: "pb-2", children: [
12706
12958
  /* @__PURE__ */ jsxs21("p", { className: "text-og-xs text-og-fg-subtle", children: [
12707
12959
  "Started ",
12708
- /* @__PURE__ */ jsx27("time", { dateTime: startedAt, children: new Date(startedAt).toLocaleString() })
12960
+ /* @__PURE__ */ jsx28("time", { dateTime: startedAt, children: new Date(startedAt).toLocaleString() })
12709
12961
  ] }),
12710
- /* @__PURE__ */ jsx27("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-left text-og-xs", children: [
12962
+ /* @__PURE__ */ jsx28("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-left text-og-xs", children: [
12711
12963
  /* @__PURE__ */ jsxs21("caption", { className: "sr-only", children: [
12712
12964
  "Startup phases for ",
12713
12965
  turnId ?? "unassigned events"
12714
12966
  ] }),
12715
- /* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsxs21("tr", { className: "border-b border-og-border text-og-fg-subtle", children: [
12716
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "py-2 font-medium", children: "Phase" }),
12717
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-3 py-2 font-medium", children: "Status" }),
12718
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "py-2 text-right font-medium", children: "Duration" })
12967
+ /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs21("tr", { className: "border-b border-og-border text-og-fg-subtle", children: [
12968
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "py-2 font-medium", children: "Phase" }),
12969
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-3 py-2 font-medium", children: "Status" }),
12970
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "py-2 text-right font-medium", children: "Duration" })
12719
12971
  ] }) }),
12720
- /* @__PURE__ */ jsx27("tbody", { children: phases.map((phase) => /* @__PURE__ */ jsxs21(
12972
+ /* @__PURE__ */ jsx28("tbody", { children: phases.map((phase) => /* @__PURE__ */ jsxs21(
12721
12973
  "tr",
12722
12974
  {
12723
12975
  className: "border-b border-og-border/40",
12724
12976
  title: `Turn: ${phase.turnId ?? "unknown"} \xB7 Started: ${phase.startedAt}`,
12725
12977
  children: [
12726
- /* @__PURE__ */ jsx27("th", { scope: "row", className: "py-2.5 font-normal text-og-fg-muted", children: LABELS[phase.phase] }),
12727
- /* @__PURE__ */ jsx27(
12978
+ /* @__PURE__ */ jsx28("th", { scope: "row", className: "py-2.5 font-normal text-og-fg-muted", children: LABELS[phase.phase] }),
12979
+ /* @__PURE__ */ jsx28(
12728
12980
  "td",
12729
12981
  {
12730
12982
  className: `px-3 py-2.5 ${phase.status === "failed" ? "text-og-status-failed" : "text-og-fg-subtle"}`,
12731
12983
  children: phase.status === "running" ? "In progress" : phase.status
12732
12984
  }
12733
12985
  ),
12734
- /* @__PURE__ */ jsx27("td", { className: "py-2.5 text-right font-og-mono tabular-nums text-og-fg-muted", children: phase.durationMs === null ? "\u2014" : phase.durationMs < 1e3 ? `${Math.round(phase.durationMs)} ms` : `${(phase.durationMs / 1e3).toFixed(1)} s` })
12986
+ /* @__PURE__ */ jsx28("td", { className: "py-2.5 text-right font-og-mono tabular-nums text-og-fg-muted", children: phase.durationMs === null ? "\u2014" : phase.durationMs < 1e3 ? `${Math.round(phase.durationMs)} ms` : `${(phase.durationMs / 1e3).toFixed(1)} s` })
12735
12987
  ]
12736
12988
  },
12737
12989
  phase.id
@@ -12800,4 +13052,4 @@ export {
12800
13052
  SessionCommands,
12801
13053
  StartupTimings
12802
13054
  };
12803
- //# sourceMappingURL=chunk-TMJRG4YC.js.map
13055
+ //# sourceMappingURL=chunk-VV5E43LD.js.map