@tutti-os/agent-gui 0.0.75 → 0.0.77

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.
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  AgentInteractivePromptSurface,
34
34
  approvalOptionDisplayLabel
35
- } from "./chunk-U6EDUTUO.js";
35
+ } from "./chunk-3B3KPQ4Y.js";
36
36
  import {
37
37
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
38
38
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -88,14 +88,14 @@ import {
88
88
  textPromptContent,
89
89
  toLocalShortDateTime,
90
90
  useProjectedAgentConversation
91
- } from "./chunk-7GSBP5CN.js";
91
+ } from "./chunk-WIRYWLAI.js";
92
92
  import {
93
93
  AgentMessageMarkdown,
94
94
  AgentTargetPresentationProvider,
95
95
  ZoomableImage,
96
96
  cn,
97
97
  resolveWorkspaceLinkAction
98
- } from "./chunk-3FYA2K4P.js";
98
+ } from "./chunk-5CLGEUWK.js";
99
99
  import {
100
100
  openAgentEnvPanel
101
101
  } from "./chunk-PSLAWU25.js";
@@ -15159,8 +15159,6 @@ function useAgentGUINodeController({
15159
15159
  const activeConversationCreatePending = Boolean(activeConversationId) && isCreatingConversation && startingConversationIdRef.current === activeConversationId;
15160
15160
  const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationCreatePending || activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
15161
15161
  useEffect4(() => {
15162
- const firstVersion = minFiniteMessageVersion(activeMessages);
15163
- const lastVersion = maxFiniteMessageVersion(activeMessages);
15164
15162
  const diagnosticKey = [
15165
15163
  activeConversationId ?? "",
15166
15164
  activeConversation?.status ?? "",
@@ -15182,10 +15180,9 @@ function useAgentGUINodeController({
15182
15180
  activeSubmitBlocked ? "submit-blocked" : "submit-open",
15183
15181
  pendingApproval?.requestId ?? "",
15184
15182
  promptRequestId(pendingInteractivePrompt) ?? "",
15185
- conversation?.rows.length ?? "",
15186
- conversation?.sourceDetail.turns.length ?? "",
15187
- firstVersion ?? "",
15188
- lastVersion ?? "",
15183
+ conversation?.activity.status ?? "",
15184
+ conversation?.pendingApproval?.requestId ?? "",
15185
+ promptRequestId(conversation?.pendingInteractivePrompt ?? null) ?? "",
15189
15186
  isCreatingConversation ? "creating" : "",
15190
15187
  isLoadingMessages ? "loading-messages" : "",
15191
15188
  isSubmitting ? "submitting" : "",
@@ -15224,7 +15221,6 @@ function useAgentGUINodeController({
15224
15221
  activeConversationId,
15225
15222
  activeHasPendingSubmittedTurn,
15226
15223
  activeLiveState,
15227
- activeMessages,
15228
15224
  activeRuntimeSession,
15229
15225
  activeSessionState,
15230
15226
  activeSubmitBlocked,
@@ -16310,10 +16306,6 @@ import {
16310
16306
  TooltipContent as TooltipContent4,
16311
16307
  TooltipProvider as TooltipProvider3,
16312
16308
  TooltipTrigger as TooltipTrigger4,
16313
- Select as Select3,
16314
- SelectContent as SelectContent3,
16315
- SelectItem as SelectItem3,
16316
- SelectTrigger as SelectTrigger3,
16317
16309
  NewWorkspaceLinedIcon as NewWorkspaceLinedIcon2,
16318
16310
  ConfirmationDialog,
16319
16311
  ContextMenu,
@@ -25739,6 +25731,7 @@ var AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX = 240;
25739
25731
  var AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX = 1;
25740
25732
  var AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE = 5;
25741
25733
  var AGENT_GUI_CONVERSATION_RAIL_LOADING_SKELETON_DELAY_MS = 300;
25734
+ var AGENT_GUI_CONVERSATION_RAIL_VISIBILITY_EPSILON_PX = 1;
25742
25735
  var AGENT_GUI_CONVERSATION_RAIL_PROJECTION_PROVIDER = "codex";
25743
25736
  var AGENT_GUI_TIMELINE_SCROLL_AREA_CONTENT_STYLE = {
25744
25737
  width: "100%",
@@ -25750,6 +25743,18 @@ var AGENT_GUI_TIMELINE_SCROLL_AREA_CONTENT_STYLE = {
25750
25743
  var EMPTY_WORKSPACE_APP_ICONS3 = [];
25751
25744
  var AGENT_GUI_CONFIRMATION_DIALOG_CLASS_NAME = "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]";
25752
25745
  var AGENT_GUI_CONFIRMATION_DIALOG_OVERLAY_CLASS_NAME = "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]";
25746
+ function isElementFullyVisibleWithin(element, viewport) {
25747
+ const elementRect = element.getBoundingClientRect();
25748
+ const viewportRect = viewport.getBoundingClientRect();
25749
+ return elementRect.top >= viewportRect.top - AGENT_GUI_CONVERSATION_RAIL_VISIBILITY_EPSILON_PX && elementRect.bottom <= viewportRect.bottom + AGENT_GUI_CONVERSATION_RAIL_VISIBILITY_EPSILON_PX;
25750
+ }
25751
+ function setBooleanStateIfChanged(stateRef, setState, nextState) {
25752
+ if (stateRef.current === nextState) {
25753
+ return;
25754
+ }
25755
+ stateRef.current = nextState;
25756
+ setState(nextState);
25757
+ }
25753
25758
  function resolveAgentGUIHeroIconUrl(provider) {
25754
25759
  const normalizedProvider = normalizeManagedAgentProvider(provider);
25755
25760
  return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
@@ -26977,6 +26982,8 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26977
26982
  const pendingRestoreScrollRef = useRef12(null);
26978
26983
  const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState14(true);
26979
26984
  const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState14(true);
26985
+ const isTimelineScrolledToTopRef = useRef12(true);
26986
+ const isTimelineScrolledToBottomRef = useRef12(true);
26980
26987
  const [
26981
26988
  bottomDockDismissedPromptRequestId,
26982
26989
  setBottomDockDismissedPromptRequestId
@@ -27783,8 +27790,16 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27783
27790
  timelineScrollAnchorRef.current = null;
27784
27791
  pendingPrependScrollAnchorRef.current = null;
27785
27792
  submittedPromptScrollConversationRef.current = null;
27786
- setIsTimelineScrolledToTop(true);
27787
- setIsTimelineScrolledToBottom(true);
27793
+ setBooleanStateIfChanged(
27794
+ isTimelineScrolledToTopRef,
27795
+ setIsTimelineScrolledToTop,
27796
+ true
27797
+ );
27798
+ setBooleanStateIfChanged(
27799
+ isTimelineScrolledToBottomRef,
27800
+ setIsTimelineScrolledToBottom,
27801
+ true
27802
+ );
27788
27803
  return;
27789
27804
  }
27790
27805
  const maxScrollTop = Math.max(
@@ -27859,10 +27874,14 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27859
27874
  scrollTop: nextScrollTop,
27860
27875
  clientHeight: timeline.clientHeight
27861
27876
  };
27862
- setIsTimelineScrolledToTop(
27877
+ setBooleanStateIfChanged(
27878
+ isTimelineScrolledToTopRef,
27879
+ setIsTimelineScrolledToTop,
27863
27880
  nextScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
27864
27881
  );
27865
- setIsTimelineScrolledToBottom(
27882
+ setBooleanStateIfChanged(
27883
+ isTimelineScrolledToBottomRef,
27884
+ setIsTimelineScrolledToBottom,
27866
27885
  maxScrollTop - nextScrollTop <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX
27867
27886
  );
27868
27887
  }, [
@@ -27930,10 +27949,16 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27930
27949
  scrollTop: maxScrollTop,
27931
27950
  clientHeight: timeline.clientHeight
27932
27951
  };
27933
- setIsTimelineScrolledToTop(
27952
+ setBooleanStateIfChanged(
27953
+ isTimelineScrolledToTopRef,
27954
+ setIsTimelineScrolledToTop,
27934
27955
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
27935
27956
  );
27936
- setIsTimelineScrolledToBottom(true);
27957
+ setBooleanStateIfChanged(
27958
+ isTimelineScrolledToBottomRef,
27959
+ setIsTimelineScrolledToBottom,
27960
+ true
27961
+ );
27937
27962
  });
27938
27963
  };
27939
27964
  syncBottomDockSpace();
@@ -27982,10 +28007,16 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27982
28007
  clientHeight: timeline.clientHeight
27983
28008
  };
27984
28009
  const atBottom = timeline.scrollHeight - scrollTop - timeline.clientHeight <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX;
27985
- setIsTimelineScrolledToTop(
28010
+ setBooleanStateIfChanged(
28011
+ isTimelineScrolledToTopRef,
28012
+ setIsTimelineScrolledToTop,
27986
28013
  scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
27987
28014
  );
27988
- setIsTimelineScrolledToBottom(atBottom);
28015
+ setBooleanStateIfChanged(
28016
+ isTimelineScrolledToBottomRef,
28017
+ setIsTimelineScrolledToBottom,
28018
+ atBottom
28019
+ );
27989
28020
  if (pendingRestoreScrollRef.current?.conversationId !== activeConversationId) {
27990
28021
  timelineScrollPositionsRef.current.set(activeConversationId, {
27991
28022
  scrollTop,
@@ -28001,9 +28032,17 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
28001
28032
  actions.loadOlderConversationMessages();
28002
28033
  }
28003
28034
  };
28004
- captureScrollAnchor();
28035
+ let initialCaptureFrameId = window.requestAnimationFrame(
28036
+ () => {
28037
+ initialCaptureFrameId = null;
28038
+ captureScrollAnchor();
28039
+ }
28040
+ );
28005
28041
  timeline.addEventListener("scroll", captureScrollAnchor, { passive: true });
28006
28042
  return () => {
28043
+ if (initialCaptureFrameId !== null) {
28044
+ window.cancelAnimationFrame(initialCaptureFrameId);
28045
+ }
28007
28046
  timeline.removeEventListener("scroll", captureScrollAnchor);
28008
28047
  };
28009
28048
  }, [
@@ -28029,10 +28068,16 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
28029
28068
  scrollTop: maxScrollTop,
28030
28069
  clientHeight: timeline.clientHeight
28031
28070
  };
28032
- setIsTimelineScrolledToTop(
28071
+ setBooleanStateIfChanged(
28072
+ isTimelineScrolledToTopRef,
28073
+ setIsTimelineScrolledToTop,
28033
28074
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
28034
28075
  );
28035
- setIsTimelineScrolledToBottom(true);
28076
+ setBooleanStateIfChanged(
28077
+ isTimelineScrolledToBottomRef,
28078
+ setIsTimelineScrolledToBottom,
28079
+ true
28080
+ );
28036
28081
  }, [viewModel.activeConversationId]);
28037
28082
  return /* @__PURE__ */ jsxs21("main", { className: AgentGUINode_styles_default.detail, children: [
28038
28083
  /* @__PURE__ */ jsx34(
@@ -28316,7 +28361,10 @@ var AgentGUIEmptyHeroPane = memo2(function AgentGUIEmptyHeroPane2({
28316
28361
  {
28317
28362
  activeProvider: provider,
28318
28363
  className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
28319
- icons: heroIconPresentations
28364
+ icons: heroIconPresentations,
28365
+ providerTargets,
28366
+ onProviderSelect,
28367
+ providerSelectLabel
28320
28368
  },
28321
28369
  heroIconAnimationKey
28322
28370
  ) : /* @__PURE__ */ jsx34(
@@ -28403,7 +28451,10 @@ var AgentGUIProviderReadinessGatePane = memo2(
28403
28451
  {
28404
28452
  activeProvider: provider,
28405
28453
  className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
28406
- icons: launchpadIconPresentations
28454
+ icons: launchpadIconPresentations,
28455
+ providerTargets,
28456
+ onProviderSelect,
28457
+ providerSelectLabel
28407
28458
  }
28408
28459
  ) : /* @__PURE__ */ jsx34(
28409
28460
  "img",
@@ -28529,18 +28580,25 @@ function providerGateAction(status) {
28529
28580
  function AgentGUIAllProviderGridIcon({
28530
28581
  activeProvider,
28531
28582
  className,
28532
- icons
28583
+ icons,
28584
+ providerTargets,
28585
+ onProviderSelect,
28586
+ providerSelectLabel
28533
28587
  }) {
28588
+ const interactive = onProviderSelect != null && (providerTargets?.length ?? 0) > 0;
28534
28589
  return /* @__PURE__ */ jsx34(
28535
28590
  "span",
28536
28591
  {
28537
- "aria-hidden": "true",
28592
+ "aria-hidden": interactive ? void 0 : "true",
28538
28593
  className: [AgentGUINode_styles_default.providerRailAvatar, className].filter(Boolean).join(" "),
28539
28594
  children: /* @__PURE__ */ jsx34(
28540
28595
  AgentGUILaunchpadIconGrid,
28541
28596
  {
28542
28597
  activeProvider,
28543
- icons
28598
+ icons,
28599
+ providerTargets,
28600
+ onProviderSelect,
28601
+ providerSelectLabel
28544
28602
  }
28545
28603
  )
28546
28604
  }
@@ -28560,36 +28618,82 @@ function AgentGUIUnifiedProviderIcon({
28560
28618
  }
28561
28619
  ) });
28562
28620
  }
28563
- function agentGUIHeroStripOpacity(distance) {
28564
- if (distance <= 0) {
28565
- return 1;
28566
- }
28567
- return Math.max(0.15, 1 - distance * 0.4);
28621
+ var AGENT_GUI_HERO_STRIP_INACTIVE_OPACITY = 0.4;
28622
+ function agentGUIHeroStripOpacity(isActive) {
28623
+ return isActive ? 1 : AGENT_GUI_HERO_STRIP_INACTIVE_OPACITY;
28624
+ }
28625
+ function agentGUILaunchpadProviderTarget(providerTargets, provider) {
28626
+ const normalized = normalizeManagedAgentProvider(provider);
28627
+ return providerTargets.find(
28628
+ (target) => target.disabled !== true && normalizeManagedAgentProvider(target.provider) === normalized
28629
+ ) ?? null;
28568
28630
  }
28569
28631
  function AgentGUILaunchpadIconGrid({
28570
28632
  activeProvider,
28571
- icons
28633
+ icons,
28634
+ providerTargets,
28635
+ onProviderSelect,
28636
+ providerSelectLabel
28572
28637
  }) {
28573
28638
  const normalizedActiveProvider = activeProvider ? normalizeManagedAgentProvider(activeProvider) : null;
28574
28639
  const activeIndex = normalizedActiveProvider === null ? -1 : icons.findIndex(
28575
28640
  (icon) => normalizeManagedAgentProvider(icon.provider) === normalizedActiveProvider
28576
28641
  );
28577
- const renderItem = (icon, distance, isActive) => /* @__PURE__ */ jsx34(
28642
+ const interactive = onProviderSelect != null && (providerTargets?.length ?? 0) > 0;
28643
+ const renderItem = (icon, isActive) => {
28644
+ const key = `${icon.provider}:${icon.iconUrl}`;
28645
+ const style = { opacity: agentGUIHeroStripOpacity(isActive) };
28646
+ const dataActive = normalizedActiveProvider === null ? void 0 : isActive;
28647
+ const target = interactive ? agentGUILaunchpadProviderTarget(providerTargets ?? [], icon.provider) : null;
28648
+ if (target && onProviderSelect) {
28649
+ const label = providerSelectLabel ? `${providerSelectLabel}: ${target.label}` : target.label;
28650
+ return /* @__PURE__ */ jsx34(
28651
+ "button",
28652
+ {
28653
+ type: "button",
28654
+ className: AgentGUINode_styles_default.providerRailLaunchpadItem,
28655
+ "data-provider-active": dataActive,
28656
+ "aria-label": label,
28657
+ "aria-pressed": isActive,
28658
+ title: target.label,
28659
+ style,
28660
+ onClick: () => onProviderSelect({
28661
+ provider: target.provider,
28662
+ providerTargetId: target.targetId
28663
+ }),
28664
+ children: /* @__PURE__ */ jsx34(
28665
+ AgentGUIProviderIconVisual,
28666
+ {
28667
+ ariaHidden: true,
28668
+ imageClassName: "",
28669
+ icon
28670
+ }
28671
+ )
28672
+ },
28673
+ key
28674
+ );
28675
+ }
28676
+ return /* @__PURE__ */ jsx34(
28677
+ "span",
28678
+ {
28679
+ className: AgentGUINode_styles_default.providerRailLaunchpadItem,
28680
+ "data-provider-active": dataActive,
28681
+ style,
28682
+ children: /* @__PURE__ */ jsx34(AgentGUIProviderIconVisual, { imageClassName: "", icon })
28683
+ },
28684
+ key
28685
+ );
28686
+ };
28687
+ return /* @__PURE__ */ jsx34(
28578
28688
  "span",
28579
28689
  {
28580
- className: AgentGUINode_styles_default.providerRailLaunchpadItem,
28581
- "data-provider-active": normalizedActiveProvider === null ? void 0 : isActive,
28582
- style: { opacity: agentGUIHeroStripOpacity(distance) },
28583
- children: /* @__PURE__ */ jsx34(AgentGUIProviderIconVisual, { imageClassName: "", icon })
28584
- },
28585
- `${icon.provider}:${icon.iconUrl}`
28690
+ "aria-hidden": interactive ? void 0 : "true",
28691
+ className: AgentGUINode_styles_default.providerRailLaunchpadIcon,
28692
+ children: icons.map(
28693
+ (icon, index) => renderItem(icon, activeIndex < 0 ? true : index === activeIndex)
28694
+ )
28695
+ }
28586
28696
  );
28587
- if (activeIndex < 0) {
28588
- return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map((icon) => renderItem(icon, 0, false)) });
28589
- }
28590
- return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map(
28591
- (icon, index) => renderItem(icon, Math.abs(index - activeIndex), index === activeIndex)
28592
- ) });
28593
28697
  }
28594
28698
  function AgentGUIProviderIconVisual({
28595
28699
  ariaHidden = false,
@@ -28628,13 +28732,13 @@ function EmptyHeroTitle({
28628
28732
  const providerName = label.slice(providerStart, providerEnd);
28629
28733
  return /* @__PURE__ */ jsxs21(Fragment9, { children: [
28630
28734
  label.slice(0, providerStart),
28631
- canSwitchProvider ? /* @__PURE__ */ jsxs21(
28632
- Select3,
28735
+ canSwitchProvider ? /* @__PURE__ */ jsx34(
28736
+ "select",
28633
28737
  {
28634
28738
  value: selectedProviderTargetId,
28635
- onValueChange: (nextTargetId) => {
28739
+ onChange: (event) => {
28636
28740
  const target = enabledProviderTargets.find(
28637
- (candidate) => candidate.targetId === nextTargetId
28741
+ (candidate) => candidate.targetId === event.currentTarget.value
28638
28742
  );
28639
28743
  if (!target) {
28640
28744
  return;
@@ -28644,48 +28748,17 @@ function EmptyHeroTitle({
28644
28748
  providerTargetId: target.targetId
28645
28749
  });
28646
28750
  },
28647
- children: [
28648
- /* @__PURE__ */ jsx34(
28649
- SelectTrigger3,
28650
- {
28651
- size: "sm",
28652
- "aria-label": providerSelectLabel,
28653
- title: providerSelectLabel,
28654
- className: AgentGUINode_styles_default.emptyHeroProviderSelect,
28655
- children: /* @__PURE__ */ jsx34("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName })
28656
- }
28657
- ),
28658
- /* @__PURE__ */ jsx34(
28659
- SelectContent3,
28660
- {
28661
- align: "center",
28662
- className: cn3(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
28663
- children: enabledProviderTargets.map((target) => /* @__PURE__ */ jsx34(
28664
- SelectItem3,
28665
- {
28666
- value: target.targetId,
28667
- className: cn3(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
28668
- children: /* @__PURE__ */ jsxs21("span", { className: "flex min-w-0 items-center gap-1.5", children: [
28669
- /* @__PURE__ */ jsx34(
28670
- "img",
28671
- {
28672
- alt: "",
28673
- "aria-hidden": "true",
28674
- className: "size-4 shrink-0 rounded-[4px]",
28675
- src: agentGUIProviderRailIconPresentation(
28676
- target.provider,
28677
- target.iconUrl
28678
- ).iconUrl
28679
- }
28680
- ),
28681
- /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: target.label })
28682
- ] })
28683
- },
28684
- `${target.provider}:${target.targetId}`
28685
- ))
28686
- }
28687
- )
28688
- ]
28751
+ "aria-label": providerSelectLabel,
28752
+ title: providerSelectLabel,
28753
+ className: AgentGUINode_styles_default.emptyHeroProviderSelect,
28754
+ children: enabledProviderTargets.map((target) => /* @__PURE__ */ jsx34(
28755
+ "option",
28756
+ {
28757
+ value: target.targetId,
28758
+ children: target.label
28759
+ },
28760
+ `${target.provider}:${target.targetId}`
28761
+ ))
28689
28762
  }
28690
28763
  ) : /* @__PURE__ */ jsx34("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName }),
28691
28764
  label.slice(providerEnd)
@@ -30579,6 +30652,7 @@ var AgentGUIConversationRailPane = memo2(
30579
30652
  /* @__PURE__ */ new Map()
30580
30653
  );
30581
30654
  const activeConversationScrollCompletedRef = useRef12(null);
30655
+ const activeConversationScrollFrameRef = useRef12(null);
30582
30656
  const previousActiveConversationIdRef = useRef12(null);
30583
30657
  const groupedConversationsRef = useRef12(null);
30584
30658
  const {
@@ -30700,6 +30774,10 @@ var AgentGUIConversationRailPane = memo2(
30700
30774
  if (!activeId) {
30701
30775
  previousActiveConversationIdRef.current = null;
30702
30776
  activeConversationScrollCompletedRef.current = null;
30777
+ if (activeConversationScrollFrameRef.current !== null) {
30778
+ window.cancelAnimationFrame(activeConversationScrollFrameRef.current);
30779
+ activeConversationScrollFrameRef.current = null;
30780
+ }
30703
30781
  return;
30704
30782
  }
30705
30783
  if (previousActiveConversationIdRef.current !== activeId) {
@@ -30713,8 +30791,35 @@ var AgentGUIConversationRailPane = memo2(
30713
30791
  if (!activeElement) {
30714
30792
  return;
30715
30793
  }
30716
- activeElement.scrollIntoView({ block: "nearest" });
30717
- activeConversationScrollCompletedRef.current = activeId;
30794
+ const viewport = conversationListRef.current ?? railElementRef.current;
30795
+ if (!viewport || isElementFullyVisibleWithin(activeElement, viewport)) {
30796
+ activeConversationScrollCompletedRef.current = activeId;
30797
+ return;
30798
+ }
30799
+ const animationFrameId = window.requestAnimationFrame(() => {
30800
+ activeConversationScrollFrameRef.current = null;
30801
+ if (previousActiveConversationIdRef.current !== activeId) {
30802
+ return;
30803
+ }
30804
+ const nextActiveElement = conversationItemElementsRef.current.get(activeId);
30805
+ if (!nextActiveElement) {
30806
+ return;
30807
+ }
30808
+ const nextViewport = conversationListRef.current ?? railElementRef.current;
30809
+ if (nextViewport && isElementFullyVisibleWithin(nextActiveElement, nextViewport)) {
30810
+ activeConversationScrollCompletedRef.current = activeId;
30811
+ return;
30812
+ }
30813
+ nextActiveElement.scrollIntoView({ block: "nearest" });
30814
+ activeConversationScrollCompletedRef.current = activeId;
30815
+ });
30816
+ activeConversationScrollFrameRef.current = animationFrameId;
30817
+ return () => {
30818
+ if (activeConversationScrollFrameRef.current === animationFrameId) {
30819
+ window.cancelAnimationFrame(animationFrameId);
30820
+ activeConversationScrollFrameRef.current = null;
30821
+ }
30822
+ };
30718
30823
  }, [activeConversationId, groupedConversationIdentityKey]);
30719
30824
  return /* @__PURE__ */ jsxs21(
30720
30825
  "aside",