@tutti-os/agent-gui 0.0.100 → 0.0.102

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 (30) hide show
  1. package/README.md +31 -0
  2. package/dist/{AgentGUI-DgBjACOL.d.ts → AgentGUI-BJ3As1gI.d.ts} +17 -36
  3. package/dist/agent-conversation/index.d.ts +1 -1
  4. package/dist/agent-conversation/index.js +2 -2
  5. package/dist/agent-gui.d.ts +3 -3
  6. package/dist/agent-gui.js +6 -6
  7. package/dist/agent-message-center/index.js +2 -2
  8. package/dist/{agentGuiNodeTypes-C-wBSM-Y.d.ts → agentGuiNodeTypes-BH3lz6gn.d.ts} +2 -1
  9. package/dist/app/renderer/agentactivity.css +2 -37
  10. package/dist/{chunk-BQJOYTW2.js → chunk-LHKBR77G.js} +474 -487
  11. package/dist/chunk-LHKBR77G.js.map +1 -0
  12. package/dist/{chunk-MES7BQWI.js → chunk-MJOQP2ED.js} +28 -97
  13. package/dist/chunk-MJOQP2ED.js.map +1 -0
  14. package/dist/{chunk-XFRY2WWB.js → chunk-TDVYZEUI.js} +2 -2
  15. package/dist/{chunk-FAE7CXZO.js → chunk-W4RYNKWO.js} +2 -2
  16. package/dist/{chunk-EUW6VPIK.js → chunk-YYE35EZ5.js} +8 -5
  17. package/dist/{chunk-EUW6VPIK.js.map → chunk-YYE35EZ5.js.map} +1 -1
  18. package/dist/{chunk-JWHPVETQ.js → chunk-ZPKPIHMZ.js} +44 -11
  19. package/dist/chunk-ZPKPIHMZ.js.map +1 -0
  20. package/dist/context-mention-palette/index.js +2 -2
  21. package/dist/index.d.ts +5 -5
  22. package/dist/index.js +6 -6
  23. package/dist/index.js.map +1 -1
  24. package/dist/mention-search.js +1 -1
  25. package/package.json +12 -12
  26. package/dist/chunk-BQJOYTW2.js.map +0 -1
  27. package/dist/chunk-JWHPVETQ.js.map +0 -1
  28. package/dist/chunk-MES7BQWI.js.map +0 -1
  29. /package/dist/{chunk-XFRY2WWB.js.map → chunk-TDVYZEUI.js.map} +0 -0
  30. /package/dist/{chunk-FAE7CXZO.js.map → chunk-W4RYNKWO.js.map} +0 -0
@@ -65,14 +65,14 @@ import {
65
65
  toLocalShortDateTime,
66
66
  updateAgentComposerDraft,
67
67
  useProjectedAgentConversation
68
- } from "./chunk-JWHPVETQ.js";
68
+ } from "./chunk-ZPKPIHMZ.js";
69
69
  import {
70
70
  openAgentEnvPanel
71
71
  } from "./chunk-7BXWPI4F.js";
72
72
  import {
73
73
  AgentFileMentionPalette,
74
74
  agentMentionItemKey
75
- } from "./chunk-FAE7CXZO.js";
75
+ } from "./chunk-W4RYNKWO.js";
76
76
  import {
77
77
  normalizeAgentGUIAgents,
78
78
  projectAgentGUIAgentsToInternalTargets
@@ -83,7 +83,7 @@ import {
83
83
  DEFAULT_AGENT_MENTION_FILTER,
84
84
  agentGuiScheduler,
85
85
  buildWorkspaceAgentActivityListViewModel
86
- } from "./chunk-EUW6VPIK.js";
86
+ } from "./chunk-YYE35EZ5.js";
87
87
  import {
88
88
  AGENT_RICH_TEXT_CARET_ANCHOR,
89
89
  createAgentSessionMarkdownLink,
@@ -103,7 +103,7 @@ import {
103
103
  dispatchAgentPlanPromptAction,
104
104
  latestPlanTurnId,
105
105
  planImplementationPromptFromPlanTurn
106
- } from "./chunk-XFRY2WWB.js";
106
+ } from "./chunk-TDVYZEUI.js";
107
107
  import {
108
108
  useEngineSelector
109
109
  } from "./chunk-2RQM7PJN.js";
@@ -115,7 +115,7 @@ import {
115
115
  resolveAgentTargetPresentation,
116
116
  resolveWorkspaceLinkAction,
117
117
  useAgentTargetPresentations
118
- } from "./chunk-MES7BQWI.js";
118
+ } from "./chunk-MJOQP2ED.js";
119
119
  import {
120
120
  resolveWorkspaceAgentSessionSortTimeUnixMs
121
121
  } from "./chunk-YMXYBG7U.js";
@@ -6825,6 +6825,7 @@ function useAgentGUIControllerRefs(input) {
6825
6825
  );
6826
6826
  const onShowMessageRef = useRef8(input.onShowMessage);
6827
6827
  const handledPrefillPromptSequenceRef = useRef8(null);
6828
+ const handledComposerAppendSequenceRef = useRef8(null);
6828
6829
  const loadDraftComposerOptionsRef = useRef8(() => {
6829
6830
  });
6830
6831
  const lastActiveModelByProviderRef = useRef8({});
@@ -6875,6 +6876,7 @@ function useAgentGUIControllerRefs(input) {
6875
6876
  draftByScopeKeyRef,
6876
6877
  draftSettingsBySessionIdRef,
6877
6878
  executePromptRef,
6879
+ handledComposerAppendSequenceRef,
6878
6880
  handledOpenSessionSequenceRef,
6879
6881
  handledPrefillPromptSequenceRef,
6880
6882
  isComposerHomeRef,
@@ -7555,16 +7557,53 @@ import {
7555
7557
  useCallback as useCallback12,
7556
7558
  useEffect as useEffect6
7557
7559
  } from "react";
7560
+
7561
+ // agent-gui/agentGuiNode/controller/useAgentGUIComposerAppendRequest.ts
7562
+ function appendAgentGUIComposerFiles(draft, incomingFiles) {
7563
+ const files = agentComposerDraftFiles(draft);
7564
+ const knownIds = new Set(files.map((file) => file.id));
7565
+ for (const file of incomingFiles) {
7566
+ if (!knownIds.has(file.id)) {
7567
+ knownIds.add(file.id);
7568
+ files.push({ ...file });
7569
+ }
7570
+ }
7571
+ return updateAgentComposerDraft(draft, { files });
7572
+ }
7573
+ function resolveAgentGUIComposerAppendRequest(input) {
7574
+ const {
7575
+ activeConversationId,
7576
+ draftByScopeKey,
7577
+ handledSequence,
7578
+ request = null
7579
+ } = input;
7580
+ if (!request || handledSequence === request.sequence) {
7581
+ return null;
7582
+ }
7583
+ const draftKey = resolveAgentComposerDraftScopeKey({
7584
+ agentSessionId: activeConversationId
7585
+ });
7586
+ const currentDraft = draftByScopeKey[draftKey] ?? emptyAgentComposerDraft();
7587
+ return {
7588
+ draftKey,
7589
+ nextDraft: appendAgentGUIComposerFiles(currentDraft, request.files),
7590
+ sequence: request.sequence
7591
+ };
7592
+ }
7593
+
7594
+ // agent-gui/agentGuiNode/controller/useAgentGUIConversationHome.ts
7558
7595
  function useAgentGUIConversationHome({
7559
7596
  activeConversationIdRef,
7560
7597
  activePendingActivation,
7561
7598
  agentActivityRuntime,
7562
7599
  composerTargetDataFromProviderTarget: composerTargetDataFromProviderTarget2,
7600
+ composerAppendRequest,
7563
7601
  conversationFilterRef,
7564
7602
  currentProvider,
7565
7603
  dataRef,
7566
7604
  defaultAgentTargetId,
7567
7605
  handledPrefillPromptSequenceRef,
7606
+ handledComposerAppendSequenceRef,
7568
7607
  isComposerHomeRef,
7569
7608
  isExplicitAgentGUIAgentTarget: isExplicitAgentGUIAgentTarget2,
7570
7609
  loadDraftComposerOptions,
@@ -7680,7 +7719,27 @@ function useAgentGUIConversationHome({
7680
7719
  ]
7681
7720
  );
7682
7721
  useEffect6(() => {
7683
- if (previewMode || !prefillPromptRequest || handledPrefillPromptSequenceRef.current === prefillPromptRequest.sequence) {
7722
+ if (previewMode) {
7723
+ return;
7724
+ }
7725
+ const resolvedAppendRequest = resolveAgentGUIComposerAppendRequest({
7726
+ activeConversationId: activeConversationIdRef.current,
7727
+ draftByScopeKey: draftByScopeKeyRef.current,
7728
+ handledSequence: handledComposerAppendSequenceRef.current,
7729
+ request: composerAppendRequest
7730
+ });
7731
+ if (resolvedAppendRequest) {
7732
+ handledComposerAppendSequenceRef.current = resolvedAppendRequest.sequence;
7733
+ draftByScopeKeyRef.current = {
7734
+ ...draftByScopeKeyRef.current,
7735
+ [resolvedAppendRequest.draftKey]: resolvedAppendRequest.nextDraft
7736
+ };
7737
+ setDraftByScopeKey((current) => ({
7738
+ ...current,
7739
+ [resolvedAppendRequest.draftKey]: resolvedAppendRequest.nextDraft
7740
+ }));
7741
+ }
7742
+ if (!prefillPromptRequest || handledPrefillPromptSequenceRef.current === prefillPromptRequest.sequence) {
7684
7743
  return;
7685
7744
  }
7686
7745
  handledPrefillPromptSequenceRef.current = prefillPromptRequest.sequence;
@@ -7751,9 +7810,11 @@ function useAgentGUIConversationHome({
7751
7810
  }, [
7752
7811
  dataRef,
7753
7812
  draftByScopeKeyRef,
7813
+ composerAppendRequest,
7754
7814
  defaultAgentTargetId,
7755
7815
  enterHome,
7756
7816
  handledPrefillPromptSequenceRef,
7817
+ handledComposerAppendSequenceRef,
7757
7818
  loadDraftComposerOptions,
7758
7819
  normalizedExplicitProviderTargets,
7759
7820
  normalizedProviderTargets,
@@ -10606,6 +10667,63 @@ function useAgentGUISessionPresentation(input) {
10606
10667
  };
10607
10668
  }
10608
10669
 
10670
+ // agent-gui/agentGuiNode/model/agentGuiProviderReadiness.ts
10671
+ function resolveAgentGUIProviderReadinessGateForView(input) {
10672
+ if (input.activeConversationId !== null) {
10673
+ return null;
10674
+ }
10675
+ return input.providerReadinessGates?.[input.selectedProvider] ?? null;
10676
+ }
10677
+ function isAgentGUIProviderReady(gate) {
10678
+ return gate === null;
10679
+ }
10680
+ function resolveAgentGUIProviderReadinessContent(status, labels, options = {}) {
10681
+ switch (status) {
10682
+ case "checking":
10683
+ return {
10684
+ title: labels.providerGateCheckingTitle,
10685
+ description: options.showAllProviders === true ? labels.providerGateCheckingAgentsDescription : labels.providerGateCheckingDescription
10686
+ };
10687
+ case "not_installed":
10688
+ return {
10689
+ title: labels.providerGateInstallTitle,
10690
+ description: labels.providerGateInstallDescription,
10691
+ actionLabel: labels.providerGateInstallAction
10692
+ };
10693
+ case "auth_required":
10694
+ return {
10695
+ title: labels.providerGateLoginTitle,
10696
+ description: labels.providerGateLoginDescription,
10697
+ actionLabel: labels.providerGateLoginAction
10698
+ };
10699
+ case "coming_soon":
10700
+ return {
10701
+ title: labels.providerGateComingSoonTitle,
10702
+ description: labels.providerGateComingSoonDescription,
10703
+ actionLabel: labels.providerGateComingSoonAction
10704
+ };
10705
+ case "unavailable":
10706
+ return {
10707
+ title: labels.providerGateUnavailableTitle,
10708
+ description: labels.providerGateUnavailableDescription,
10709
+ actionLabel: labels.providerGateRetryAction
10710
+ };
10711
+ }
10712
+ }
10713
+ function resolveAgentGUIProviderReadinessAction(status) {
10714
+ switch (status) {
10715
+ case "not_installed":
10716
+ return "install";
10717
+ case "auth_required":
10718
+ return "login";
10719
+ case "unavailable":
10720
+ return "refresh";
10721
+ case "coming_soon":
10722
+ case "checking":
10723
+ return null;
10724
+ }
10725
+ }
10726
+
10609
10727
  // agent-gui/agentGuiNode/controller/useAgentGUIViewAssembly.ts
10610
10728
  function useAgentGUIViewAssembly(input) {
10611
10729
  const { activeConversation, visibleConversations } = useAgentGUIConversationPresentation(input);
@@ -10652,7 +10770,11 @@ function useAgentGUIViewAssembly(input) {
10652
10770
  updateSelectedProjectPath: input.updateSelectedProjectPath
10653
10771
  });
10654
10772
  const viewData = input.activeConversationId === null ? input.selectedComposerTargetData.data : input.data;
10655
- const providerReadinessGate = input.activeConversationId === null ? input.providerReadinessGates?.[input.effectiveSelectedProviderTarget.provider] ?? null : null;
10773
+ const providerReadinessGate = resolveAgentGUIProviderReadinessGateForView({
10774
+ activeConversationId: input.activeConversationId,
10775
+ providerReadinessGates: input.providerReadinessGates,
10776
+ selectedProvider: input.effectiveSelectedProviderTarget.provider
10777
+ });
10656
10778
  const viewModel = useAgentGUIViewModel({
10657
10779
  shell: {
10658
10780
  workspaceId: input.workspaceId,
@@ -11506,6 +11628,7 @@ function useAgentGUINodeController({
11506
11628
  comingSoonProviders,
11507
11629
  providerReadinessGates = null,
11508
11630
  defaultAgentTargetId = null,
11631
+ composerAppendRequest = null,
11509
11632
  openSessionRequest = null,
11510
11633
  prefillPromptRequest = null,
11511
11634
  previewMode = false,
@@ -11923,6 +12046,7 @@ function useAgentGUINodeController({
11923
12046
  agentActivityRuntime,
11924
12047
  agentHostApi,
11925
12048
  composerTargetDataFromProviderTarget,
12049
+ composerAppendRequest,
11926
12050
  composerSupportPermissionModeChangeDeferred: composerSupport.permissionModeChangeDeferred,
11927
12051
  currentProvider: data.provider,
11928
12052
  currentUserId,
@@ -11947,7 +12071,7 @@ function useAgentGUINodeController({
11947
12071
  });
11948
12072
  const isLoadingMessages = localState.isLoadingMessages || sessionEngineState.activeSessionDetailLoading;
11949
12073
  const detailAvailability = activeConversationId === null ? "ready" : sessionEngineState.activeEngineSessionDeleted ? "not_found" : isLoadingMessages ? "loading" : sessionEngineState.activeSessionReconcileError || localState.detailError ? "error" : "ready";
11950
- return useAgentGUIViewAssembly({
12074
+ const viewAssembly = useAgentGUIViewAssembly({
11951
12075
  ...providerCatalogSelection,
11952
12076
  ...localState,
11953
12077
  ...conversationList,
@@ -11998,6 +12122,7 @@ function useAgentGUINodeController({
11998
12122
  workspaceId,
11999
12123
  workspacePath
12000
12124
  });
12125
+ return viewAssembly;
12001
12126
  }
12002
12127
 
12003
12128
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
@@ -12005,8 +12130,8 @@ import {
12005
12130
  useCallback as useCallback48,
12006
12131
  useEffect as useEffect37,
12007
12132
  useMemo as useMemo37,
12008
- useRef as useRef41,
12009
- useState as useState34
12133
+ useRef as useRef42,
12134
+ useState as useState35
12010
12135
  } from "react";
12011
12136
  import { TooltipProvider as TooltipProvider5 } from "@tutti-os/ui-system";
12012
12137
 
@@ -12156,10 +12281,6 @@ var styles = {
12156
12281
  conversationUnreadLamp: "agent-gui-node__conversation-unread-lamp",
12157
12282
  detailHeader: "agent-gui-node__detail-header",
12158
12283
  detailHeaderPathInfo: "agent-gui-node__detail-header-path-info",
12159
- providerSetupNotice: "agent-gui-node__provider-setup-notice",
12160
- providerSetupNoticeIcon: "agent-gui-node__provider-setup-notice-icon",
12161
- providerSetupNoticeText: "agent-gui-node__provider-setup-notice-text",
12162
- providerSetupNoticeAction: "agent-gui-node__provider-setup-notice-action",
12163
12284
  detailHeaderTitle: "agent-gui-node__detail-header-title",
12164
12285
  detailHeaderTitleGroup: "agent-gui-node__detail-header-title-group",
12165
12286
  detail: "agent-gui-node__detail",
@@ -24318,11 +24439,15 @@ var AgentGUIProviderReadinessGatePane = memo3(
24318
24439
  const pendingAction = gate.pendingAction ?? null;
24319
24440
  const isPending = pendingAction !== null;
24320
24441
  const showAllProvidersChecking = showAllProviders && gate.status === "checking";
24321
- const content = providerGateContent(gate.status, labels, {
24322
- showAllProviders: showAllProvidersChecking
24323
- });
24442
+ const content = resolveAgentGUIProviderReadinessContent(
24443
+ gate.status,
24444
+ labels,
24445
+ {
24446
+ showAllProviders: showAllProvidersChecking
24447
+ }
24448
+ );
24324
24449
  const titleLabel = gate.status === "not_installed" || gate.status === "auth_required" ? emptyLabel : content.title;
24325
- const action = providerGateAction(gate.status);
24450
+ const action = resolveAgentGUIProviderReadinessAction(gate.status);
24326
24451
  const pendingLabel = pendingAction === "install" ? labels.providerGatePendingInstall : pendingAction === "login" ? labels.providerGatePendingLogin : pendingAction === "refresh" ? labels.providerGatePendingRefresh : null;
24327
24452
  return /* @__PURE__ */ jsx39("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs28(
24328
24453
  "div",
@@ -24410,52 +24535,6 @@ var AgentGUIProviderReadinessGatePane = memo3(
24410
24535
  ) });
24411
24536
  }
24412
24537
  );
24413
- function providerGateContent(status, labels, options = {}) {
24414
- switch (status) {
24415
- case "checking":
24416
- return {
24417
- title: labels.providerGateCheckingTitle,
24418
- description: options.showAllProviders === true ? labels.providerGateCheckingAgentsDescription : labels.providerGateCheckingDescription
24419
- };
24420
- case "not_installed":
24421
- return {
24422
- title: labels.providerGateInstallTitle,
24423
- description: labels.providerGateInstallDescription,
24424
- actionLabel: labels.providerGateInstallAction
24425
- };
24426
- case "auth_required":
24427
- return {
24428
- title: labels.providerGateLoginTitle,
24429
- description: labels.providerGateLoginDescription,
24430
- actionLabel: labels.providerGateLoginAction
24431
- };
24432
- case "coming_soon":
24433
- return {
24434
- title: labels.providerGateComingSoonTitle,
24435
- description: labels.providerGateComingSoonDescription,
24436
- actionLabel: labels.providerGateComingSoonAction
24437
- };
24438
- case "unavailable":
24439
- return {
24440
- title: labels.providerGateUnavailableTitle,
24441
- description: labels.providerGateUnavailableDescription,
24442
- actionLabel: labels.providerGateRetryAction
24443
- };
24444
- }
24445
- }
24446
- function providerGateAction(status) {
24447
- switch (status) {
24448
- case "not_installed":
24449
- return "install";
24450
- case "auth_required":
24451
- return "login";
24452
- case "unavailable":
24453
- return "refresh";
24454
- case "coming_soon":
24455
- case "checking":
24456
- return null;
24457
- }
24458
- }
24459
24538
  function AgentGUIUnifiedProviderIcon({
24460
24539
  presentation
24461
24540
  }) {
@@ -28598,10 +28677,9 @@ import {
28598
28677
  useCallback as useCallback45,
28599
28678
  useEffect as useEffect34,
28600
28679
  useMemo as useMemo35,
28601
- useRef as useRef36,
28602
- useState as useState31
28680
+ useRef as useRef37,
28681
+ useState as useState32
28603
28682
  } from "react";
28604
- import { cn as cn7, toastVariants } from "@tutti-os/ui-system";
28605
28683
  import { ScrollArea as ScrollArea2 } from "@tutti-os/ui-system/components";
28606
28684
 
28607
28685
  // agent-gui/agentGuiNode/view/agentGUIDetailModelHelpers.ts
@@ -29247,6 +29325,7 @@ import {
29247
29325
  useCallback as useCallback44,
29248
29326
  useEffect as useEffect33,
29249
29327
  useLayoutEffect as useLayoutEffect7,
29328
+ useRef as useRef36,
29250
29329
  useState as useState30
29251
29330
  } from "react";
29252
29331
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
@@ -29259,26 +29338,29 @@ function useAgentGUIDetailScroll(input) {
29259
29338
  bottomDockStoreRevision,
29260
29339
  conversation,
29261
29340
  pendingPrependScrollAnchorRef,
29262
- pendingRestoreScrollRef,
29263
29341
  showTimelineSkeleton,
29264
29342
  submittedPromptScrollConversationRef,
29343
+ timelineConversationId,
29265
29344
  timelineRef,
29266
29345
  timelineScrollAnchorRef,
29267
- timelineScrollPositionsRef,
29268
29346
  viewModel
29269
29347
  } = input;
29270
29348
  const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState30(true);
29271
29349
  const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState30(true);
29350
+ const bottomLockOwnerRef = useRef36(null);
29351
+ const userScrollAwayIntentConversationRef = useRef36(null);
29272
29352
  useLayoutEffect7(() => {
29273
29353
  const timeline = timelineRef.current;
29274
29354
  if (!timeline) {
29275
29355
  return;
29276
29356
  }
29277
- const activeConversationId = viewModel.rail.activeConversationId;
29357
+ const activeConversationId = timelineConversationId;
29278
29358
  if (!activeConversationId) {
29279
29359
  timelineScrollAnchorRef.current = null;
29360
+ bottomLockOwnerRef.current = null;
29280
29361
  pendingPrependScrollAnchorRef.current = null;
29281
29362
  submittedPromptScrollConversationRef.current = null;
29363
+ userScrollAwayIntentConversationRef.current = null;
29282
29364
  setIsTimelineScrolledToTop(true);
29283
29365
  setIsTimelineScrolledToBottom(true);
29284
29366
  return;
@@ -29291,40 +29373,19 @@ function useAgentGUIDetailScroll(input) {
29291
29373
  const prependAnchor = pendingPrependScrollAnchorRef.current;
29292
29374
  const shouldScrollSubmittedPromptToBottom = submittedPromptScrollConversationRef.current === activeConversationId;
29293
29375
  let nextScrollTop = timeline.scrollTop;
29294
- const savedScrollPosition = shouldScrollSubmittedPromptToBottom ? void 0 : timelineScrollPositionsRef.current.get(activeConversationId);
29295
- if (!anchor || anchor.conversationId !== activeConversationId || shouldScrollSubmittedPromptToBottom) {
29296
- if (savedScrollPosition && !savedScrollPosition.atBottom && !showTimelineSkeleton) {
29297
- nextScrollTop = Math.min(maxScrollTop, savedScrollPosition.scrollTop);
29298
- timeline.scrollTop = nextScrollTop;
29299
- pendingRestoreScrollRef.current = null;
29300
- } else if (savedScrollPosition && !savedScrollPosition.atBottom) {
29301
- pendingRestoreScrollRef.current = {
29302
- conversationId: activeConversationId,
29303
- scrollTop: savedScrollPosition.scrollTop
29304
- };
29305
- setTimelineScrollTopInstantly(timeline, maxScrollTop);
29306
- nextScrollTop = maxScrollTop;
29307
- } else {
29308
- setTimelineScrollTopInstantly(timeline, maxScrollTop);
29309
- nextScrollTop = maxScrollTop;
29310
- pendingRestoreScrollRef.current = null;
29311
- }
29376
+ const conversationChanged = !anchor || anchor.conversationId !== activeConversationId;
29377
+ if (conversationChanged || shouldScrollSubmittedPromptToBottom) {
29378
+ bottomLockOwnerRef.current = activeConversationId;
29379
+ userScrollAwayIntentConversationRef.current = null;
29380
+ }
29381
+ const shouldKeepBottomLocked = bottomLockOwnerRef.current === activeConversationId;
29382
+ if (conversationChanged || shouldScrollSubmittedPromptToBottom || shouldKeepBottomLocked) {
29383
+ setTimelineScrollTopInstantly(timeline, maxScrollTop);
29384
+ nextScrollTop = maxScrollTop;
29312
29385
  submittedPromptScrollConversationRef.current = null;
29313
29386
  if (shouldScrollSubmittedPromptToBottom) {
29314
29387
  pendingPrependScrollAnchorRef.current = null;
29315
29388
  }
29316
- } else if (pendingRestoreScrollRef.current?.conversationId === activeConversationId) {
29317
- if (showTimelineSkeleton) {
29318
- setTimelineScrollTopInstantly(timeline, maxScrollTop);
29319
- nextScrollTop = maxScrollTop;
29320
- } else {
29321
- nextScrollTop = Math.min(
29322
- maxScrollTop,
29323
- pendingRestoreScrollRef.current.scrollTop
29324
- );
29325
- timeline.scrollTop = nextScrollTop;
29326
- pendingRestoreScrollRef.current = null;
29327
- }
29328
29389
  } else if (prependAnchor?.conversationId === activeConversationId) {
29329
29390
  const nextScrollHeight = timeline.scrollHeight;
29330
29391
  const delta = nextScrollHeight - prependAnchor.scrollHeight;
@@ -29364,13 +29425,13 @@ function useAgentGUIDetailScroll(input) {
29364
29425
  }, [
29365
29426
  conversation,
29366
29427
  showTimelineSkeleton,
29367
- viewModel.rail.activeConversationId,
29428
+ timelineConversationId,
29368
29429
  viewModel.detail.isLoadingOlderMessages
29369
29430
  ]);
29370
29431
  useLayoutEffect7(() => {
29371
29432
  const timeline = timelineRef.current;
29372
29433
  const bottomDock = bottomDockRef.current;
29373
- const activeConversationId = viewModel.rail.activeConversationId;
29434
+ const activeConversationId = timelineConversationId;
29374
29435
  if (!timeline || !bottomDock || !activeConversationId) {
29375
29436
  return;
29376
29437
  }
@@ -29405,12 +29466,16 @@ function useAgentGUIDetailScroll(input) {
29405
29466
  };
29406
29467
  const syncBottomDockSpace = () => {
29407
29468
  syncBottomDockSafeArea();
29469
+ if (activeConversationId !== viewModel.rail.activeConversationId) {
29470
+ return;
29471
+ }
29408
29472
  const anchor = timelineScrollAnchorRef.current;
29473
+ const bottomLocked = bottomLockOwnerRef.current === activeConversationId;
29409
29474
  if (!anchor || anchor.conversationId !== activeConversationId) {
29410
29475
  return;
29411
29476
  }
29412
29477
  const distanceFromBottom = anchor.scrollHeight - anchor.scrollTop - anchor.clientHeight;
29413
- if (distanceFromBottom > AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX) {
29478
+ if (!bottomLocked && distanceFromBottom > AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX) {
29414
29479
  return;
29415
29480
  }
29416
29481
  if (animationFrameId !== null) {
@@ -29418,6 +29483,15 @@ function useAgentGUIDetailScroll(input) {
29418
29483
  }
29419
29484
  animationFrameId = window.requestAnimationFrame(() => {
29420
29485
  animationFrameId = null;
29486
+ const latestAnchor = timelineScrollAnchorRef.current;
29487
+ if (!latestAnchor || latestAnchor.conversationId !== activeConversationId) {
29488
+ return;
29489
+ }
29490
+ const latestDistanceFromBottom = latestAnchor.scrollHeight - latestAnchor.scrollTop - latestAnchor.clientHeight;
29491
+ const latestBottomLocked = bottomLockOwnerRef.current === activeConversationId;
29492
+ if (!latestBottomLocked && latestDistanceFromBottom > AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX) {
29493
+ return;
29494
+ }
29421
29495
  const maxScrollTop = Math.max(
29422
29496
  0,
29423
29497
  timeline.scrollHeight - timeline.clientHeight
@@ -29465,15 +29539,37 @@ function useAgentGUIDetailScroll(input) {
29465
29539
  }
29466
29540
  observer.disconnect();
29467
29541
  };
29468
- }, [bottomDockStoreRevision, viewModel.rail.activeConversationId]);
29542
+ }, [
29543
+ bottomDockStoreRevision,
29544
+ timelineConversationId,
29545
+ viewModel.rail.activeConversationId
29546
+ ]);
29469
29547
  useEffect33(() => {
29470
29548
  const timeline = timelineRef.current;
29471
- const activeConversationId = viewModel.rail.activeConversationId;
29549
+ const activeConversationId = timelineConversationId;
29472
29550
  if (!timeline || !activeConversationId) {
29473
29551
  return;
29474
29552
  }
29475
29553
  const captureScrollAnchor = () => {
29476
- const scrollTop = timeline.scrollTop;
29554
+ let scrollTop = timeline.scrollTop;
29555
+ const previousAnchor = timelineScrollAnchorRef.current;
29556
+ const geometryChanged = previousAnchor?.conversationId !== activeConversationId || previousAnchor.scrollHeight !== timeline.scrollHeight || previousAnchor.clientHeight !== timeline.clientHeight;
29557
+ const inferredUserScrollAway = previousAnchor?.conversationId === activeConversationId && !geometryChanged && scrollTop < previousAnchor.scrollTop - 1;
29558
+ const explicitUserScrollAway = userScrollAwayIntentConversationRef.current === activeConversationId;
29559
+ if (explicitUserScrollAway || inferredUserScrollAway) {
29560
+ bottomLockOwnerRef.current = null;
29561
+ userScrollAwayIntentConversationRef.current = null;
29562
+ }
29563
+ if (geometryChanged && bottomLockOwnerRef.current === activeConversationId) {
29564
+ const maxScrollTop = Math.max(
29565
+ 0,
29566
+ timeline.scrollHeight - timeline.clientHeight
29567
+ );
29568
+ if (maxScrollTop - scrollTop > AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX) {
29569
+ setTimelineScrollTopInstantly(timeline, maxScrollTop);
29570
+ scrollTop = maxScrollTop;
29571
+ }
29572
+ }
29477
29573
  timelineScrollAnchorRef.current = {
29478
29574
  conversationId: activeConversationId,
29479
29575
  scrollHeight: timeline.scrollHeight,
@@ -29481,17 +29577,15 @@ function useAgentGUIDetailScroll(input) {
29481
29577
  clientHeight: timeline.clientHeight
29482
29578
  };
29483
29579
  const atBottom = timeline.scrollHeight - scrollTop - timeline.clientHeight <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX;
29580
+ if (atBottom) {
29581
+ bottomLockOwnerRef.current = activeConversationId;
29582
+ }
29583
+ const effectiveAtBottom = atBottom || bottomLockOwnerRef.current === activeConversationId;
29484
29584
  setIsTimelineScrolledToTop(
29485
29585
  scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
29486
29586
  );
29487
- setIsTimelineScrolledToBottom(atBottom);
29488
- if (pendingRestoreScrollRef.current?.conversationId !== activeConversationId) {
29489
- timelineScrollPositionsRef.current.set(activeConversationId, {
29490
- scrollTop,
29491
- atBottom
29492
- });
29493
- }
29494
- if (viewModel.detail.hasOlderMessages && !viewModel.detail.isLoadingOlderMessages && scrollTop <= AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX) {
29587
+ setIsTimelineScrolledToBottom(effectiveAtBottom);
29588
+ if (activeConversationId === viewModel.rail.activeConversationId && viewModel.detail.hasOlderMessages && !viewModel.detail.isLoadingOlderMessages && scrollTop <= AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX) {
29495
29589
  pendingPrependScrollAnchorRef.current = {
29496
29590
  conversationId: activeConversationId,
29497
29591
  scrollHeight: timeline.scrollHeight,
@@ -29500,27 +29594,47 @@ function useAgentGUIDetailScroll(input) {
29500
29594
  actions.loadOlderConversationMessages();
29501
29595
  }
29502
29596
  };
29597
+ const captureWheelIntent = (event) => {
29598
+ if (event.deltaY < 0) {
29599
+ userScrollAwayIntentConversationRef.current = activeConversationId;
29600
+ }
29601
+ };
29602
+ const captureKeyboardIntent = (event) => {
29603
+ if (event.key === "ArrowUp" || event.key === "Home" || event.key === "PageUp") {
29604
+ userScrollAwayIntentConversationRef.current = activeConversationId;
29605
+ }
29606
+ };
29503
29607
  captureScrollAnchor();
29504
29608
  timeline.addEventListener("scroll", captureScrollAnchor, { passive: true });
29609
+ timeline.addEventListener("wheel", captureWheelIntent, { passive: true });
29610
+ timeline.addEventListener("keydown", captureKeyboardIntent);
29505
29611
  return () => {
29506
29612
  timeline.removeEventListener("scroll", captureScrollAnchor);
29613
+ timeline.removeEventListener("wheel", captureWheelIntent);
29614
+ timeline.removeEventListener("keydown", captureKeyboardIntent);
29507
29615
  };
29508
29616
  }, [
29509
29617
  actions,
29618
+ timelineConversationId,
29510
29619
  viewModel.rail.activeConversationId,
29511
29620
  viewModel.detail.hasOlderMessages,
29512
29621
  viewModel.detail.isLoadingOlderMessages
29513
29622
  ]);
29514
29623
  const scrollTimelineToBottom = useCallback44(() => {
29515
29624
  const timeline = timelineRef.current;
29516
- const activeConversationId = viewModel.rail.activeConversationId;
29625
+ const activeConversationId = timelineConversationId;
29517
29626
  if (!timeline || !activeConversationId) {
29518
29627
  return;
29519
29628
  }
29629
+ if (activeConversationId !== viewModel.rail.activeConversationId) {
29630
+ return;
29631
+ }
29520
29632
  const maxScrollTop = Math.max(
29521
29633
  0,
29522
29634
  timeline.scrollHeight - timeline.clientHeight
29523
29635
  );
29636
+ bottomLockOwnerRef.current = activeConversationId;
29637
+ userScrollAwayIntentConversationRef.current = null;
29524
29638
  setTimelineScrollTopWithUserTransition(timeline, maxScrollTop);
29525
29639
  timelineScrollAnchorRef.current = {
29526
29640
  conversationId: activeConversationId,
@@ -29532,7 +29646,7 @@ function useAgentGUIDetailScroll(input) {
29532
29646
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
29533
29647
  );
29534
29648
  setIsTimelineScrolledToBottom(true);
29535
- }, [viewModel.rail.activeConversationId]);
29649
+ }, [timelineConversationId, viewModel.rail.activeConversationId]);
29536
29650
  return {
29537
29651
  isTimelineScrolledToBottom,
29538
29652
  isTimelineScrolledToTop,
@@ -29560,12 +29674,51 @@ function UnavailableChatIcon(props) {
29560
29674
  );
29561
29675
  }
29562
29676
 
29677
+ // agent-gui/agentGuiNode/view/useAgentGUITimelineTransition.ts
29678
+ import { useLayoutEffect as useLayoutEffect8, useState as useState31 } from "react";
29679
+ var AGENT_GUI_TIMELINE_SKELETON_DELAY_MS = 300;
29680
+ function useAgentGUITimelineTransition(input) {
29681
+ const activeConversationId = input.activeConversationId;
29682
+ const [committedTimeline, setCommittedTimeline] = useState31(() => ({
29683
+ conversation: input.conversation,
29684
+ conversationId: activeConversationId
29685
+ }));
29686
+ const [revealedSkeletonConversationId, setRevealedSkeletonConversationId] = useState31(null);
29687
+ const transitionPending = activeConversationId !== null && input.availability === "loading" && (!input.conversation || input.conversation.rows.length === 0);
29688
+ useLayoutEffect8(() => {
29689
+ if (!transitionPending || activeConversationId === null) {
29690
+ setCommittedTimeline(
29691
+ (current) => current?.conversation === input.conversation && current.conversationId === activeConversationId ? current : {
29692
+ conversation: input.conversation,
29693
+ conversationId: activeConversationId
29694
+ }
29695
+ );
29696
+ setRevealedSkeletonConversationId(
29697
+ (current) => current === null ? current : null
29698
+ );
29699
+ return;
29700
+ }
29701
+ const timeoutId = window.setTimeout(() => {
29702
+ setRevealedSkeletonConversationId(activeConversationId);
29703
+ }, AGENT_GUI_TIMELINE_SKELETON_DELAY_MS);
29704
+ return () => window.clearTimeout(timeoutId);
29705
+ }, [activeConversationId, input.conversation, transitionPending]);
29706
+ const showTimelineSkeleton = transitionPending && revealedSkeletonConversationId === activeConversationId;
29707
+ const retainedTimeline = transitionPending ? committedTimeline : null;
29708
+ const retainsPreviousTimeline = !showTimelineSkeleton && retainedTimeline?.conversation !== null && retainedTimeline?.conversation !== void 0;
29709
+ return {
29710
+ conversation: transitionPending ? retainedTimeline?.conversation ?? null : input.conversation,
29711
+ showTimelineSkeleton,
29712
+ timelineConversationId: retainsPreviousTimeline ? retainedTimeline?.conversationId ?? activeConversationId : activeConversationId,
29713
+ transitionPending
29714
+ };
29715
+ }
29716
+
29563
29717
  // agent-gui/agentGuiNode/view/useAgentGUIDetailModel.tsx
29564
29718
  import { Fragment as Fragment15, jsx as jsx56, jsxs as jsxs40 } from "react/jsx-runtime";
29565
29719
  function useAgentGUIDetailModel(input) {
29566
29720
  const {
29567
29721
  bottomDockDismissedPromptRequestId,
29568
- isAgentProviderReady,
29569
29722
  labels,
29570
29723
  slashStatusLimits,
29571
29724
  slashStatusLimitsLoading,
@@ -29577,7 +29730,17 @@ function useAgentGUIDetailModel(input) {
29577
29730
  detail: viewModel.detail.conversationDetail,
29578
29731
  avoidGroupingEdits: viewModel.detail.avoidGroupingEdits
29579
29732
  });
29580
- const conversation = viewModel.detail.availability === "not_found" ? null : projectedConversation;
29733
+ const targetConversation = viewModel.detail.availability === "not_found" ? null : projectedConversation;
29734
+ const {
29735
+ conversation,
29736
+ showTimelineSkeleton,
29737
+ timelineConversationId,
29738
+ transitionPending: timelineTransitionPending
29739
+ } = useAgentGUITimelineTransition({
29740
+ activeConversationId: viewModel.rail.activeConversationId,
29741
+ availability: viewModel.detail.availability,
29742
+ conversation: targetConversation
29743
+ });
29581
29744
  const hasActiveConversation = viewModel.rail.activeConversationId !== null;
29582
29745
  const selectedAgentTargetComingSoon = viewModel.rail.selectedAgentTarget?.disabled === true;
29583
29746
  const emptyProviderReadinessGate = !hasActiveConversation ? selectedAgentTargetComingSoon ? { status: "coming_soon" } : viewModel.readiness.providerReadinessGate : null;
@@ -29649,7 +29812,6 @@ function useAgentGUIDetailModel(input) {
29649
29812
  const shouldLiftActivePromptAboveInlineNotice = inlineNoticeChrome !== null;
29650
29813
  const bottomDockLiftedPrompt = !activePromptIsPlanDecision && shouldLiftActivePromptAboveInlineNotice && activePromptIsVisible ? activePrompt : null;
29651
29814
  const composerActivePrompt = activePromptIsPlanDecision || shouldLiftActivePromptAboveInlineNotice ? null : activePrompt;
29652
- const showTimelineSkeleton = viewModel.detail.availability === "loading" && (!conversation || conversation.rows.length === 0);
29653
29815
  const showUnavailableChatEmpty = hasActiveConversation && viewModel.detail.availability === "not_found";
29654
29816
  const activeDetailStatus = resolveConversationDetailStatus(
29655
29817
  viewModel.detail.conversationDetail
@@ -29657,7 +29819,7 @@ function useAgentGUIDetailModel(input) {
29657
29819
  const derivedBusyStatus = resolveActiveConversationBusyStatus({
29658
29820
  conversationStatus: viewModel.rail.activeConversation?.status,
29659
29821
  detailStatus: activeDetailStatus,
29660
- conversation
29822
+ conversation: targetConversation
29661
29823
  });
29662
29824
  const activeConversationTurnBusy = viewModel.composer.isSubmitting || viewModel.readiness.activeConversationBusy || derivedBusyStatus !== null;
29663
29825
  const isComposerSending = viewModel.composer.isSubmitting || activeConversationTurnBusy || !hasActiveConversation && viewModel.composer.isCreatingConversation;
@@ -29665,12 +29827,11 @@ function useAgentGUIDetailModel(input) {
29665
29827
  conversationUserId: viewModel.rail.activeConversation?.userId,
29666
29828
  currentUserId: viewModel.shell.currentUserId
29667
29829
  });
29668
- const canQueueWhileBusy = viewModel.composer.canQueueWhileBusy && isAgentProviderReady && !isCollaboratorConversation;
29669
- const composerDisabledReason = isCollaboratorConversation ? labels.collaboratorSessionReadOnlyPlaceholder : isAgentProviderReady ? null : labels.installRequiredPlaceholder;
29670
- const showProviderSetupNotice = !emptyProviderReadinessGate && !isAgentProviderReady && !isCollaboratorConversation;
29830
+ const canQueueWhileBusy = viewModel.composer.canQueueWhileBusy && !isCollaboratorConversation;
29831
+ const composerDisabledReason = isCollaboratorConversation ? labels.collaboratorSessionReadOnlyPlaceholder : null;
29671
29832
  const hasNonRetryableRecoveryFailure = sessionChrome.recovery?.kind === "failed" && sessionChrome.recovery.canRetry === false || sessionChrome.recovery?.kind === "resume-unavailable";
29672
- const submitDisabled = hasNonRetryableRecoveryFailure || isCollaboratorConversation || !isAgentProviderReady || !viewModel.composer.canSubmit && !canQueueWhileBusy;
29673
- const composerDisabled = hasNonRetryableRecoveryFailure || isCollaboratorConversation || !isAgentProviderReady || !canQueueWhileBusy && (viewModel.interaction.pendingApproval !== null || viewModel.interaction.pendingInteractivePrompt !== null || viewModel.composer.isSubmitting || viewModel.composer.isInterrupting || viewModel.composer.isCreatingConversation);
29833
+ const submitDisabled = hasNonRetryableRecoveryFailure || isCollaboratorConversation || !viewModel.composer.canSubmit && !canQueueWhileBusy;
29834
+ const composerDisabled = hasNonRetryableRecoveryFailure || isCollaboratorConversation || !canQueueWhileBusy && (viewModel.interaction.pendingApproval !== null || viewModel.interaction.pendingInteractivePrompt !== null || viewModel.composer.isSubmitting || viewModel.composer.isInterrupting || viewModel.composer.isCreatingConversation);
29674
29835
  const showStopButton = !viewModel.composer.isSubmitting && viewModel.readiness.activeLiveState !== "failed" && sessionChrome.auth === null && (activeConversationTurnBusy || viewModel.interaction.pendingApproval !== null || viewModel.interaction.pendingInteractivePrompt !== null || viewModel.composer.isInterrupting);
29675
29836
  const conversationFlowLabels = useMemo34(
29676
29837
  () => ({
@@ -30057,12 +30218,13 @@ function useAgentGUIDetailModel(input) {
30057
30218
  isComposerSending,
30058
30219
  selectedAgentTargetComingSoon,
30059
30220
  sessionChrome,
30060
- showProviderSetupNotice,
30061
30221
  showStopButton,
30062
30222
  showTimelineSkeleton,
30063
30223
  showUnavailableChatEmpty,
30064
30224
  slashStatus,
30065
- submitDisabled
30225
+ submitDisabled,
30226
+ timelineConversationId,
30227
+ timelineInteractionLocked: timelineTransitionPending
30066
30228
  };
30067
30229
  }
30068
30230
 
@@ -30130,7 +30292,6 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30130
30292
  previewMode,
30131
30293
  workspaceReferencePickerOpen,
30132
30294
  composerFocusRequestSequence,
30133
- isAgentProviderReady,
30134
30295
  slashStatusLimits,
30135
30296
  slashStatusLimitsLoading,
30136
30297
  slashStatusLimitsUnavailable,
@@ -30150,17 +30311,15 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30150
30311
  renderProviderUnavailableState
30151
30312
  }) {
30152
30313
  "use memo";
30153
- const timelineRef = useRef36(null);
30154
- const bottomDockRef = useRef36(null);
30155
- const timelineScrollAnchorRef = useRef36(null);
30156
- const submittedPromptScrollConversationRef = useRef36(null);
30157
- const pendingPrependScrollAnchorRef = useRef36(null);
30158
- const timelineScrollPositionsRef = useRef36(/* @__PURE__ */ new Map());
30159
- const pendingRestoreScrollRef = useRef36(null);
30314
+ const timelineRef = useRef37(null);
30315
+ const bottomDockRef = useRef37(null);
30316
+ const timelineScrollAnchorRef = useRef37(null);
30317
+ const submittedPromptScrollConversationRef = useRef37(null);
30318
+ const pendingPrependScrollAnchorRef = useRef37(null);
30160
30319
  const [
30161
30320
  bottomDockDismissedPromptRequestId,
30162
30321
  setBottomDockDismissedPromptRequestId
30163
- ] = useState31(null);
30322
+ ] = useState32(null);
30164
30323
  const {
30165
30324
  activePromptRequestId,
30166
30325
  bottomDockLiftedPrompt,
@@ -30182,15 +30341,15 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30182
30341
  isComposerSending,
30183
30342
  selectedAgentTargetComingSoon,
30184
30343
  sessionChrome,
30185
- showProviderSetupNotice,
30186
30344
  showStopButton,
30187
30345
  showTimelineSkeleton,
30188
30346
  showUnavailableChatEmpty,
30189
30347
  slashStatus,
30190
- submitDisabled
30348
+ submitDisabled,
30349
+ timelineConversationId,
30350
+ timelineInteractionLocked
30191
30351
  } = useAgentGUIDetailModel({
30192
30352
  bottomDockDismissedPromptRequestId,
30193
- isAgentProviderReady,
30194
30353
  labels,
30195
30354
  slashStatusLimits,
30196
30355
  slashStatusLimitsLoading,
@@ -30364,9 +30523,9 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30364
30523
  handoffAgentTargets: composerHandoffProviderTargets,
30365
30524
  providerSelectReadonly: !canSwitchComposerProvider || viewModel.rail.activeConversationId !== null,
30366
30525
  onProviderSelect: canSwitchComposerProvider && viewModel.rail.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
30367
- disabled: composerDisabled,
30526
+ disabled: composerDisabled || timelineInteractionLocked,
30368
30527
  disabledReason: composerDisabledReason,
30369
- submitDisabled,
30528
+ submitDisabled: submitDisabled || timelineInteractionLocked,
30370
30529
  composerSettings: viewModel.composer.composerSettings,
30371
30530
  queueStatus: viewModel.composer.queueStatus,
30372
30531
  queuedPrompts: viewModel.composer.queuedPrompts,
@@ -30429,6 +30588,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30429
30588
  composerLabels,
30430
30589
  composerProviderTargets,
30431
30590
  composerSelectedProviderTarget,
30591
+ timelineInteractionLocked,
30432
30592
  handleInterruptCurrentTurn,
30433
30593
  isActive,
30434
30594
  isComposerSending,
@@ -30528,150 +30688,125 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30528
30688
  bottomDockStoreRevision,
30529
30689
  conversation,
30530
30690
  pendingPrependScrollAnchorRef,
30531
- pendingRestoreScrollRef,
30532
30691
  showTimelineSkeleton,
30533
30692
  submittedPromptScrollConversationRef,
30693
+ timelineConversationId,
30534
30694
  timelineRef,
30535
30695
  timelineScrollAnchorRef,
30536
- timelineScrollPositionsRef,
30537
30696
  viewModel
30538
30697
  });
30539
- return /* @__PURE__ */ jsxs41("main", { className: AgentGUINode_styles_default.detail, children: [
30540
- /* @__PURE__ */ jsx57(
30541
- AgentGUIDetailHeader,
30542
- {
30543
- activeConversation: viewModel.rail.activeConversation,
30544
- hidden: hideDetailHeader,
30545
- labels,
30546
- uiLanguage,
30547
- previewMode
30548
- }
30549
- ),
30550
- showProviderSetupNotice ? /* @__PURE__ */ jsxs41(
30551
- "div",
30552
- {
30553
- className: cn7(
30554
- toastVariants({ variant: "default" }),
30555
- AgentGUINode_styles_default.providerSetupNotice
30698
+ return /* @__PURE__ */ jsxs41(
30699
+ "main",
30700
+ {
30701
+ className: AgentGUINode_styles_default.detail,
30702
+ "aria-busy": timelineInteractionLocked || void 0,
30703
+ inert: timelineInteractionLocked,
30704
+ children: [
30705
+ /* @__PURE__ */ jsx57(
30706
+ AgentGUIDetailHeader,
30707
+ {
30708
+ activeConversation: viewModel.rail.activeConversation,
30709
+ hidden: hideDetailHeader,
30710
+ labels,
30711
+ uiLanguage,
30712
+ previewMode
30713
+ }
30556
30714
  ),
30557
- "data-slot": "toast",
30558
- "data-testid": "agent-gui-provider-setup-notice",
30559
- role: "status",
30560
- children: [
30561
- /* @__PURE__ */ jsx57("span", { className: "inline-flex max-w-full items-center justify-center gap-[6px] text-center text-[13px] font-normal leading-normal", children: /* @__PURE__ */ jsx57("span", { className: "min-w-0 break-words", children: labels.installRequiredPlaceholder }) }),
30562
- /* @__PURE__ */ jsx57(
30563
- "button",
30564
- {
30565
- type: "button",
30566
- className: cn7(
30567
- AgentGUINode_styles_default.providerSetupNoticeAction,
30568
- "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]"
30715
+ /* @__PURE__ */ jsx57(
30716
+ ScrollArea2,
30717
+ {
30718
+ scrollbarMode: "native",
30719
+ className: "flex h-full min-h-0 flex-1 flex-col [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
30720
+ viewportRef: timelineRef,
30721
+ viewportTestId: "agent-gui-timeline",
30722
+ viewportClassName: `${AgentGUINode_styles_default.timeline} ${hasActiveConversation ? AgentGUINode_styles_default.timelineWithComposer : AgentGUINode_styles_default.timelineCentered} ${!isTimelineScrolledToTop ? AgentGUINode_styles_default.timelineScrolledFromTop : ""} ${showUnavailableChatEmpty ? AgentGUINode_styles_default.timelineUnavailableChatEmpty : ""}`.trim(),
30723
+ viewportContentStyle: AGENT_GUI_TIMELINE_SCROLL_AREA_CONTENT_STYLE,
30724
+ children: !hasActiveConversation ? shouldRenderProviderUnavailableState && disabledProviderTarget ? /* @__PURE__ */ jsx57(Fragment16, { children: renderProviderUnavailableState?.({
30725
+ provider: disabledProviderTarget.provider,
30726
+ providerLabel: labels.emptyProviderForProvider?.(
30727
+ disabledProviderTarget.provider
30728
+ ) ?? resolveAgentGuiWorkbenchProviderLabel(
30729
+ disabledProviderTarget.provider
30569
30730
  ),
30570
- "data-testid": "agent-gui-provider-setup-notice-action",
30571
- onPointerDown: (event) => event.stopPropagation(),
30572
- onClick: () => openAgentEnvPanel({
30573
- provider: viewModel.shell.data.provider,
30574
- focus: "detect"
30575
- }),
30576
- children: labels.installRequiredAction
30577
- }
30578
- )
30579
- ]
30580
- }
30581
- ) : null,
30582
- /* @__PURE__ */ jsx57(
30583
- ScrollArea2,
30584
- {
30585
- scrollbarMode: "native",
30586
- className: "flex h-full min-h-0 flex-1 flex-col [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
30587
- viewportRef: timelineRef,
30588
- viewportTestId: "agent-gui-timeline",
30589
- viewportClassName: `${AgentGUINode_styles_default.timeline} ${hasActiveConversation ? AgentGUINode_styles_default.timelineWithComposer : AgentGUINode_styles_default.timelineCentered} ${!isTimelineScrolledToTop ? AgentGUINode_styles_default.timelineScrolledFromTop : ""} ${showUnavailableChatEmpty ? AgentGUINode_styles_default.timelineUnavailableChatEmpty : ""}`.trim(),
30590
- viewportContentStyle: AGENT_GUI_TIMELINE_SCROLL_AREA_CONTENT_STYLE,
30591
- children: !hasActiveConversation ? shouldRenderProviderUnavailableState && disabledProviderTarget ? /* @__PURE__ */ jsx57(Fragment16, { children: renderProviderUnavailableState?.({
30592
- provider: disabledProviderTarget.provider,
30593
- providerLabel: labels.emptyProviderForProvider?.(
30594
- disabledProviderTarget.provider
30595
- ) ?? resolveAgentGuiWorkbenchProviderLabel(
30596
- disabledProviderTarget.provider
30597
- ),
30598
- target: disabledProviderTarget,
30599
- iconUrl: resolveAgentGUIHeroIconUrl2(
30600
- disabledProviderTarget.provider
30601
- ),
30602
- unavailableReason: disabledProviderTarget.unavailableReason ?? null
30603
- }) }) : /* @__PURE__ */ jsx57(
30604
- AgentGUIEmptyHomePane,
30731
+ target: disabledProviderTarget,
30732
+ iconUrl: resolveAgentGUIHeroIconUrl2(
30733
+ disabledProviderTarget.provider
30734
+ ),
30735
+ unavailableReason: disabledProviderTarget.unavailableReason ?? null
30736
+ }) }) : /* @__PURE__ */ jsx57(
30737
+ AgentGUIEmptyHomePane,
30738
+ {
30739
+ provider: emptyHeroProvider,
30740
+ providerReadinessGate: emptyProviderReadinessGate,
30741
+ showAllProviders: viewModel.rail.conversationFilter.kind === "all",
30742
+ agentTargets: composerProviderTargets,
30743
+ selectedAgentTarget: composerSelectedProviderTarget,
30744
+ onProviderSelect: canSwitchComposerProvider && viewModel.rail.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
30745
+ inlineNoticeChrome,
30746
+ isRespondingApproval: viewModel.interaction.isRespondingApproval,
30747
+ onSubmitApprovalOption: submitApprovalOption,
30748
+ onRetryActivation: retryActivation,
30749
+ onAuthLogin: authLogin,
30750
+ onContinueInNewConversation: continueInNewConversation,
30751
+ chromeLabels,
30752
+ composerProps: emptyHeroComposerProps,
30753
+ labels,
30754
+ suggestions: labels.homeSuggestions ?? EMPTY_HOME_SUGGESTIONS,
30755
+ suggestionsCloseLabel: labels.homeSuggestionsClose,
30756
+ onSelectSuggestion: handleSelectHomeSuggestion,
30757
+ onSelectSuggestionAction: handleHomeSuggestionAction
30758
+ }
30759
+ ) : /* @__PURE__ */ jsx57(
30760
+ AgentGUIConversationTimelinePane,
30761
+ {
30762
+ conversation,
30763
+ isLoading: showTimelineSkeleton,
30764
+ isLoadingOlderMessages: viewModel.detail.isLoadingOlderMessages,
30765
+ loadingLabel: labels.loadingConversation,
30766
+ empty: conversationFlowEmpty,
30767
+ onLinkAction: stableLinkAction,
30768
+ onAuthLogin: authLogin,
30769
+ availableSkills: viewModel.composer.availableSkills,
30770
+ workspaceAppIcons,
30771
+ previewMode,
30772
+ labels: conversationFlowLabels
30773
+ }
30774
+ )
30775
+ }
30776
+ ),
30777
+ hasActiveConversation ? /* @__PURE__ */ jsx57(
30778
+ AgentGUIBottomDockPane,
30605
30779
  {
30606
- provider: emptyHeroProvider,
30607
- providerReadinessGate: emptyProviderReadinessGate,
30608
- showAllProviders: viewModel.rail.conversationFilter.kind === "all",
30609
- agentTargets: composerProviderTargets,
30610
- selectedAgentTarget: composerSelectedProviderTarget,
30611
- onProviderSelect: canSwitchComposerProvider && viewModel.rail.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
30780
+ bottomDockRef,
30781
+ showScrollToBottom: !isTimelineScrolledToBottom,
30782
+ scrollToBottomLabel: labels.scrollToBottom,
30783
+ onScrollToBottom: scrollTimelineToBottom,
30784
+ bottomDockLiftedPrompt,
30785
+ bottomDockReplacementPrompt,
30786
+ composerProps: bottomDockComposerProps,
30612
30787
  inlineNoticeChrome,
30613
30788
  isRespondingApproval: viewModel.interaction.isRespondingApproval,
30789
+ sessionChrome,
30790
+ keyboardShortcutsEnabled: isActive,
30791
+ chromeLabels,
30792
+ goalBannerLabels,
30793
+ promptLabels: interactivePromptLabels,
30614
30794
  onSubmitApprovalOption: submitApprovalOption,
30615
30795
  onRetryActivation: retryActivation,
30616
30796
  onAuthLogin: authLogin,
30617
30797
  onContinueInNewConversation: continueInNewConversation,
30618
- chromeLabels,
30619
- composerProps: emptyHeroComposerProps,
30620
- labels,
30621
- suggestions: labels.homeSuggestions ?? EMPTY_HOME_SUGGESTIONS,
30622
- suggestionsCloseLabel: labels.homeSuggestionsClose,
30623
- onSelectSuggestion: handleSelectHomeSuggestion,
30624
- onSelectSuggestionAction: handleHomeSuggestionAction
30625
- }
30626
- ) : /* @__PURE__ */ jsx57(
30627
- AgentGUIConversationTimelinePane,
30628
- {
30629
- conversation,
30630
- isLoading: showTimelineSkeleton,
30631
- isLoadingOlderMessages: viewModel.detail.isLoadingOlderMessages,
30632
- loadingLabel: labels.loadingConversation,
30633
- empty: conversationFlowEmpty,
30634
- onLinkAction: stableLinkAction,
30635
- onAuthLogin: authLogin,
30636
- availableSkills: viewModel.composer.availableSkills,
30637
- workspaceAppIcons,
30638
- previewMode,
30639
- labels: conversationFlowLabels
30798
+ onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt,
30799
+ onGoalControl: goalControl,
30800
+ goalPauseSupported: viewModel.composer.goalPauseSupported
30640
30801
  }
30641
- )
30642
- }
30643
- ),
30644
- hasActiveConversation ? /* @__PURE__ */ jsx57(
30645
- AgentGUIBottomDockPane,
30646
- {
30647
- bottomDockRef,
30648
- showScrollToBottom: !isTimelineScrolledToBottom,
30649
- scrollToBottomLabel: labels.scrollToBottom,
30650
- onScrollToBottom: scrollTimelineToBottom,
30651
- bottomDockLiftedPrompt,
30652
- bottomDockReplacementPrompt,
30653
- composerProps: bottomDockComposerProps,
30654
- inlineNoticeChrome,
30655
- isRespondingApproval: viewModel.interaction.isRespondingApproval,
30656
- sessionChrome,
30657
- keyboardShortcutsEnabled: isActive,
30658
- chromeLabels,
30659
- goalBannerLabels,
30660
- promptLabels: interactivePromptLabels,
30661
- onSubmitApprovalOption: submitApprovalOption,
30662
- onRetryActivation: retryActivation,
30663
- onAuthLogin: authLogin,
30664
- onContinueInNewConversation: continueInNewConversation,
30665
- onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt,
30666
- onGoalControl: goalControl,
30667
- goalPauseSupported: viewModel.composer.goalPauseSupported
30668
- }
30669
- ) : null
30670
- ] });
30802
+ ) : null
30803
+ ]
30804
+ }
30805
+ );
30671
30806
  });
30672
30807
 
30673
30808
  // agent-gui/agentGuiNode/view/AgentGUIRenameConversationDialog.tsx
30674
- import { memo as memo13, useCallback as useCallback46, useEffect as useEffect35, useRef as useRef37, useState as useState32 } from "react";
30809
+ import { memo as memo13, useCallback as useCallback46, useEffect as useEffect35, useRef as useRef38, useState as useState33 } from "react";
30675
30810
  import { ConfirmationDialog as ConfirmationDialog2 } from "@tutti-os/ui-system";
30676
30811
  import { jsx as jsx58, jsxs as jsxs42 } from "react/jsx-runtime";
30677
30812
  var AgentGUIRenameConversationDialog = memo13(
@@ -30683,11 +30818,11 @@ var AgentGUIRenameConversationDialog = memo13(
30683
30818
  onRename
30684
30819
  }) {
30685
30820
  "use memo";
30686
- const [title, setTitle] = useState32("");
30687
- const [isSaving, setIsSaving] = useState32(false);
30688
- const isSavingRef = useRef37(false);
30689
- const armedPointerActionRef = useRef37(null);
30690
- const inputRef = useRef37(null);
30821
+ const [title, setTitle] = useState33("");
30822
+ const [isSaving, setIsSaving] = useState33(false);
30823
+ const isSavingRef = useRef38(false);
30824
+ const armedPointerActionRef = useRef38(null);
30825
+ const inputRef = useRef38(null);
30691
30826
  const trimmedTitle = title.trim();
30692
30827
  useEffect35(() => {
30693
30828
  if (!open || !conversation) {
@@ -30915,7 +31050,7 @@ function AgentGUIReferencePickerSurface({
30915
31050
  }
30916
31051
 
30917
31052
  // agent-gui/agentGuiNode/view/useAgentGUIWorkspaceReferencePicker.ts
30918
- import { useCallback as useCallback47, useMemo as useMemo36, useRef as useRef38, useState as useState33 } from "react";
31053
+ import { useCallback as useCallback47, useMemo as useMemo36, useRef as useRef39, useState as useState34 } from "react";
30919
31054
  import { createRichTextMentionHref } from "@tutti-os/ui-rich-text/core";
30920
31055
  function useAgentGUIWorkspaceReferencePicker(input) {
30921
31056
  const {
@@ -30928,9 +31063,9 @@ function useAgentGUIWorkspaceReferencePicker(input) {
30928
31063
  workspaceFileReferenceAdapter,
30929
31064
  workspaceFileReferenceCopy
30930
31065
  } = input;
30931
- const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState33(false);
30932
- const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState33(null);
30933
- const workspaceReferencePickerResolverRef = useRef38(null);
31066
+ const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState34(false);
31067
+ const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState34(null);
31068
+ const workspaceReferencePickerResolverRef = useRef39(null);
30934
31069
  const emptyReferencePickResult = useMemo36(
30935
31070
  () => ({ files: [], mentionItems: [] }),
30936
31071
  []
@@ -31045,7 +31180,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
31045
31180
  }
31046
31181
 
31047
31182
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
31048
- import { useRef as useRef40 } from "react";
31183
+ import { useRef as useRef41 } from "react";
31049
31184
 
31050
31185
  // agent-gui/agentGuiNode/engagement/projectAgentGUIEngagementContext.ts
31051
31186
  function projectAgentGUIEngagementContext(viewModel, composerReady) {
@@ -31077,7 +31212,7 @@ function createAgentGUIEngagementContextKey(input) {
31077
31212
  }
31078
31213
 
31079
31214
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
31080
- import { useEffect as useEffect36, useRef as useRef39 } from "react";
31215
+ import { useEffect as useEffect36, useRef as useRef40 } from "react";
31081
31216
 
31082
31217
  // agent-gui/agentGuiNode/engagement/AgentGUIPanelEngagementController.ts
31083
31218
  var AGENT_GUI_PANEL_EXPOSURE_DWELL_MS = 1e3;
@@ -31231,10 +31366,10 @@ function documentIsVisible() {
31231
31366
 
31232
31367
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
31233
31368
  function useAgentGUIPanelEngagement(input) {
31234
- const inputRef = useRef39(input);
31235
- const controllerRef = useRef39(null);
31236
- const intersectionRatioRef = useRef39(0);
31237
- const engagementRef = useRef39(null);
31369
+ const inputRef = useRef40(input);
31370
+ const controllerRef = useRef40(null);
31371
+ const intersectionRatioRef = useRef40(0);
31372
+ const engagementRef = useRef40(null);
31238
31373
  inputRef.current = input;
31239
31374
  if (!engagementRef.current) {
31240
31375
  engagementRef.current = {
@@ -31274,7 +31409,7 @@ function useAgentGUIPanelEngagement(input) {
31274
31409
 
31275
31410
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
31276
31411
  function useAgentGUINodeEngagement(input) {
31277
- const layoutElementRef = useRef40(null);
31412
+ const layoutElementRef = useRef41(null);
31278
31413
  const projected = projectAgentGUIEngagementContext(
31279
31414
  input.viewModel,
31280
31415
  input.composerReady
@@ -31310,7 +31445,6 @@ function AgentGUINodeView({
31310
31445
  onEngagementEvent,
31311
31446
  composerFocusRequestSequence = null,
31312
31447
  newConversationRequestSequence = null,
31313
- isAgentProviderReady,
31314
31448
  slashStatusLimits = [],
31315
31449
  slashStatusLimitsLoading = false,
31316
31450
  slashStatusLimitsUnavailable = false,
@@ -31352,6 +31486,9 @@ function AgentGUINodeView({
31352
31486
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS4
31353
31487
  }) {
31354
31488
  "use memo";
31489
+ const isAgentProviderReady = isAgentGUIProviderReady(
31490
+ viewModel.readiness.providerReadinessGate
31491
+ );
31355
31492
  const { composerEngagement, layoutElementRef } = useAgentGUINodeEngagement({
31356
31493
  composerReady: isAgentProviderReady,
31357
31494
  isActive,
@@ -31360,17 +31497,17 @@ function AgentGUINodeView({
31360
31497
  previewMode,
31361
31498
  viewModel
31362
31499
  });
31363
- const [providerManagerOpen, setProviderManagerOpen] = useState34(false);
31364
- const railResizeInteractionRef = useRef41(null);
31365
- const [isRailResizing, setIsRailResizing] = useState34(false);
31366
- const [railResizeWidthPx, setRailResizeWidthPx] = useState34(
31500
+ const [providerManagerOpen, setProviderManagerOpen] = useState35(false);
31501
+ const railResizeInteractionRef = useRef42(null);
31502
+ const [isRailResizing, setIsRailResizing] = useState35(false);
31503
+ const [railResizeWidthPx, setRailResizeWidthPx] = useState35(
31367
31504
  null
31368
31505
  );
31369
31506
  const [
31370
31507
  localComposerFocusRequestSequence,
31371
31508
  setLocalComposerFocusRequestSequence
31372
- ] = useState34(0);
31373
- const handledNewConversationRequestSequenceRef = useRef41(
31509
+ ] = useState35(0);
31510
+ const handledNewConversationRequestSequenceRef = useRef42(
31374
31511
  newConversationRequestSequence
31375
31512
  );
31376
31513
  const {
@@ -31621,8 +31758,8 @@ function AgentGUINodeView({
31621
31758
  const openAgentSettings = useCallback48(() => {
31622
31759
  openWorkspaceSettingsPanel({ section: "agent" });
31623
31760
  }, []);
31624
- const [renameConversationTarget, setRenameConversationTarget] = useState34(null);
31625
- const [renameConversationDialogOpen, setRenameConversationDialogOpen] = useState34(false);
31761
+ const [renameConversationTarget, setRenameConversationTarget] = useState35(null);
31762
+ const [renameConversationDialogOpen, setRenameConversationDialogOpen] = useState35(false);
31626
31763
  const requestRenameConversation = useCallback48(
31627
31764
  (conversation) => {
31628
31765
  setRenameConversationTarget(conversation);
@@ -31878,7 +32015,6 @@ function AgentGUINodeView({
31878
32015
  isActive,
31879
32016
  workspaceReferencePickerOpen,
31880
32017
  composerFocusRequestSequence: detailComposerFocusRequestSequence,
31881
- isAgentProviderReady,
31882
32018
  slashStatusLimits,
31883
32019
  slashStatusLimitsLoading,
31884
32020
  slashStatusLimitsUnavailable,
@@ -32114,9 +32250,9 @@ import { Info as Info3 } from "lucide-react";
32114
32250
  import {
32115
32251
  useCallback as useCallback49,
32116
32252
  useEffect as useEffect38,
32117
- useLayoutEffect as useLayoutEffect8,
32118
- useRef as useRef42,
32119
- useState as useState35
32253
+ useLayoutEffect as useLayoutEffect9,
32254
+ useRef as useRef43,
32255
+ useState as useState36
32120
32256
  } from "react";
32121
32257
  import { createPortal as createPortal5 } from "react-dom";
32122
32258
  import { Fragment as Fragment17, jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
@@ -32153,10 +32289,10 @@ function AgentProbeInfoPopover({
32153
32289
  onOpen
32154
32290
  }) {
32155
32291
  "use memo";
32156
- const anchorRef = useRef42(null);
32157
- const popoverRef = useRef42(null);
32158
- const [isOpen, setIsOpen] = useState35(false);
32159
- const [popoverStyle, setPopoverStyle] = useState35(null);
32292
+ const anchorRef = useRef43(null);
32293
+ const popoverRef = useRef43(null);
32294
+ const [isOpen, setIsOpen] = useState36(false);
32295
+ const [popoverStyle, setPopoverStyle] = useState36(null);
32160
32296
  const openPopover = useCallback49(() => {
32161
32297
  if (!isOpen) {
32162
32298
  onOpen?.();
@@ -32202,7 +32338,7 @@ function AgentProbeInfoPopover({
32202
32338
  }
32203
32339
  updatePopoverPosition();
32204
32340
  }, [isOpen, lines, updatePopoverPosition]);
32205
- useLayoutEffect8(() => {
32341
+ useLayoutEffect9(() => {
32206
32342
  if (!isOpen) {
32207
32343
  return;
32208
32344
  }
@@ -32278,161 +32414,29 @@ function AgentProbeInfoPopover({
32278
32414
  );
32279
32415
  }
32280
32416
 
32281
- // shared/utils/managedToolchainAgents.ts
32282
- var AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS = [
32283
- {
32284
- id: "claude-code",
32285
- // i18n-check-ignore: Provider brand name.
32286
- label: "Claude Code",
32287
- toolIds: ["claude-code-cli"],
32288
- agentIds: ["claude-code"],
32289
- runtimeManaged: true,
32290
- helperProvider: "claude",
32291
- aliases: ["claude code", "claude"]
32292
- },
32293
- {
32294
- id: "codex",
32295
- label: migratedProviderDisplayName("codex"),
32296
- toolIds: ["codex-cli"],
32297
- agentIds: ["codex"],
32298
- runtimeManaged: true,
32299
- helperProvider: "codex"
32300
- },
32301
- {
32302
- id: "cursor",
32303
- // i18n-check-ignore: Provider brand name.
32304
- label: "Cursor",
32305
- toolIds: ["cursor-cli"],
32306
- agentIds: ["cursor"],
32307
- runtimeManaged: true,
32308
- helperProvider: "cursor",
32309
- aliases: ["cursor cli", "cursor agent", "cursor-agent"]
32310
- },
32311
- {
32312
- id: "tutti",
32313
- // i18n-check-ignore: Provider brand name.
32314
- label: "Tutti",
32315
- actionAgentId: "nexight",
32316
- toolIds: ["nexight-cli"],
32317
- agentIds: ["nexight", "tutti"],
32318
- runtimeManaged: false,
32319
- helperProvider: "nexight"
32320
- },
32321
- {
32322
- id: "hermes",
32323
- // i18n-check-ignore: Provider brand name.
32324
- label: "Hermes",
32325
- toolIds: ["hermes-cli"],
32326
- agentIds: ["hermes"],
32327
- runtimeManaged: true,
32328
- helperProvider: "hermes",
32329
- aliases: ["hermes agent"]
32330
- },
32331
- {
32332
- id: "openclaw",
32333
- // i18n-check-ignore: Provider brand name.
32334
- label: "OpenClaw",
32335
- toolIds: ["openclaw-cli"],
32336
- agentIds: ["openclaw"],
32337
- runtimeManaged: true,
32338
- helperProvider: "openclaw",
32339
- aliases: ["open claw"]
32340
- },
32341
- {
32342
- id: "opencode",
32343
- label: migratedProviderDisplayName("opencode"),
32344
- toolIds: ["opencode-cli"],
32345
- agentIds: ["opencode"],
32346
- runtimeManaged: true,
32347
- helperProvider: "opencode",
32348
- aliases: migratedProviderAliases("opencode")
32349
- }
32350
- ];
32351
- function migratedProviderDisplayName(providerId) {
32352
- const identity = resolveMigratedAgentGUIProviderIdentity(providerId);
32353
- if (!identity) {
32354
- throw new Error(`Missing migrated provider identity for ${providerId}`);
32355
- }
32356
- return identity.displayName;
32357
- }
32358
- function migratedProviderAliases(providerId) {
32359
- const identity = resolveMigratedAgentGUIProviderIdentity(providerId);
32360
- if (!identity) {
32361
- throw new Error(`Missing migrated provider identity for ${providerId}`);
32362
- }
32363
- return [...identity.aliases];
32364
- }
32365
- var WORKSPACE_DESKTOP_MANAGED_AGENT_DOCK_PROVIDER_ORDER = AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS.map(
32366
- (agent) => agent.id === "tutti" ? "tutti-agent" : agent.id
32367
- );
32368
- function normalizeKey(value) {
32369
- return (value ?? "").trim().toLowerCase();
32370
- }
32371
- function hasAnyAgentState(stateAgentIds, agent) {
32372
- return agent.agentIds.some(
32373
- (candidate) => stateAgentIds.has(normalizeKey(candidate))
32374
- );
32375
- }
32376
- function hasHostConfig(item) {
32377
- return Boolean(item?.hostConfigDetected);
32378
- }
32379
- function findAgentHostManagedAgentsStateItemIndex(agent, managedAgentsState) {
32380
- if (!managedAgentsState) {
32381
- return -1;
32382
- }
32383
- return managedAgentsState.items.findIndex((item) => {
32384
- const toolId = normalizeKey(item.toolId);
32385
- const agentId = normalizeKey(item.agentId);
32386
- return agent.toolIds.some((candidate) => normalizeKey(candidate) === toolId) || agent.agentIds.some((candidate) => normalizeKey(candidate) === agentId);
32387
- });
32388
- }
32389
- function resolveAgentHostManagedToolchainAgentAction(agent, managedAgentsState) {
32390
- const stateItemIndex = findAgentHostManagedAgentsStateItemIndex(
32391
- agent,
32392
- managedAgentsState
32393
- );
32394
- const pendingStateItem = stateItemIndex >= 0 ? managedAgentsState?.items[stateItemIndex] : void 0;
32395
- return resolveAgentHostManagedToolchainAction(
32396
- agent,
32397
- pendingStateItem,
32398
- managedAgentsState
32399
- );
32400
- }
32401
- function resolveAgentHostManagedToolchainAction(agent, pendingStateItem, managedAgentsState) {
32402
- if (!managedAgentsState) {
32403
- return "install";
32404
- }
32405
- const readyAgentIds = new Set(
32406
- (managedAgentsState.readyAgentIds ?? []).map(normalizeKey)
32407
- );
32408
- if (agent.id === "openclaw") {
32409
- if (readyAgentIds.has("openclaw")) {
32410
- return "installed";
32411
- }
32412
- return hasHostConfig(pendingStateItem) ? "sync" : "install";
32413
- }
32414
- if (hasAnyAgentState(readyAgentIds, agent)) {
32415
- return "installed";
32417
+ // agent-gui/agentGuiNode/model/agentReferenceProvenanceCatalog.ts
32418
+ function resolveAgentGUIReferenceProvenanceFilterCatalog(input) {
32419
+ if (input.injectedCatalog !== void 0) {
32420
+ return input.injectedCatalog;
32416
32421
  }
32417
- if (pendingStateItem) {
32418
- return hasHostConfig(pendingStateItem) ? "sync" : "install";
32419
- }
32420
- return "install";
32421
- }
32422
- function getAgentHostManagedToolchainAgentByName(name) {
32423
- const normalized = normalizeKey(name);
32424
- if (!normalized) {
32422
+ if (!input.legacyAgentFilterEnabled) {
32425
32423
  return null;
32426
32424
  }
32427
- return AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS.find(
32428
- (agent) => [
32429
- agent.id,
32430
- agent.label,
32431
- agent.actionAgentId,
32432
- ...agent.agentIds,
32433
- ...agent.aliases ?? []
32434
- ].some((candidate) => normalizeKey(candidate) === normalized)
32435
- ) ?? null;
32425
+ return {
32426
+ enabledDimensions: ["agent"],
32427
+ agentOptions: (input.agentTargets ?? []).flatMap((target) => {
32428
+ const agentTargetId = target.agentTargetId?.trim();
32429
+ return agentTargetId ? [
32430
+ {
32431
+ disabled: target.disabled,
32432
+ iconUrl: target.iconUrl,
32433
+ id: agentTargetId,
32434
+ label: target.label
32435
+ }
32436
+ ] : [];
32437
+ }),
32438
+ memberOptions: []
32439
+ };
32436
32440
  }
32437
32441
 
32438
32442
  // agent-gui/agentGuiNode/AgentGUINode.types.ts
@@ -32482,7 +32486,7 @@ function areAgentGUINodePropsEqual(previous, next) {
32482
32486
  const pc = previous.hostCapabilities, nc = next.hostCapabilities;
32483
32487
  const pa = previous.hostActions, na = next.hostActions;
32484
32488
  const ps = previous.renderSlots, ns = next.renderSlots;
32485
- return pi.nodeId === ni.nodeId && pi.workspaceId === ni.workspaceId && pi.currentUserId === ni.currentUserId && pi.title === ni.title && pw.path === nw.path && pw.fileReferenceAdapter === nw.fileReferenceAdapter && pw.onRequestGitBranches === nw.onRequestGitBranches && pw.selectProjectDirectory === nw.selectProjectDirectory && pw.resolveDroppedFileReferences === nw.resolveDroppedFileReferences && pw.referenceSourceAggregator === nw.referenceSourceAggregator && pw.resolveReferenceEntryIconUrl === nw.resolveReferenceEntryIconUrl && pw.resolveMentionReferenceTarget === nw.resolveMentionReferenceTarget && pw.resolveReferenceInitialTarget === nw.resolveReferenceInitialTarget && pw.onFileReferencesAdded === nw.onFileReferencesAdded && pw.agentSettings.avoidGroupingEdits === nw.agentSettings.avoidGroupingEdits && pc.referenceProvenanceFilterEnabled === nc.referenceProvenanceFilterEnabled && agentGuiStateEquals(previous.state, next.state) && pf.position.x === nf.position.x && pf.position.y === nf.position.y && pf.width === nf.width && pf.height === nf.height && pf.desktopSize.width === nf.desktopSize.width && pf.desktopSize.height === nf.desktopSize.height && pf.isMaximized === nf.isMaximized && pf.isActive === nf.isActive && pf.isVisible === nf.isVisible && pf.embedded === nf.embedded && pf.previewMode === nf.previewMode && pf.conversationRailAutoCollapseWidthPx === nf.conversationRailAutoCollapseWidthPx && pr.composerFocusSequence === nr.composerFocusSequence && pr.newConversationSequence === nr.newConversationSequence && pr.openSession === nr.openSession && pr.prefillPrompt === nr.prefillPrompt && pr.agentProbes === nr.agentProbes && pr.onProbeDemandChange === nr.onProbeDemandChange && pr.onProbeRefreshRequest === nr.onProbeRefreshRequest && pc.capabilityMenuState === nc.capabilityMenuState && pc.accountMenuState === nc.accountMenuState && pc.agentTargets === nc.agentTargets && pc.agentTargetsLoading === nc.agentTargetsLoading && pc.providerRailAllPresentation?.iconUrl === nc.providerRailAllPresentation?.iconUrl && pc.providerRailMode === nc.providerRailMode && pc.comingSoonProviders === nc.comingSoonProviders && pc.providerReadinessGates === nc.providerReadinessGates && pc.defaultAgentTargetId === nc.defaultAgentTargetId && pc.providerAuthAccountLabels === nc.providerAuthAccountLabels && pc.managedAgentsState === nc.managedAgentsState && pc.contextMentionProviders === nc.contextMentionProviders && pc.workspaceAppIcons === nc.workspaceAppIcons && pc.disabledHomeSuggestions === nc.disabledHomeSuggestions && pa.onLinkAction === na.onLinkAction && pa.onHandoffConversation === na.onHandoffConversation && pa.onCapabilitySettingsRequest === na.onCapabilitySettingsRequest && pa.onAgentProviderLogin === na.onAgentProviderLogin && pa.onOpenConversationWindow === na.onOpenConversationWindow && pa.onClose === na.onClose && pa.onResize === na.onResize && pa.onUpdateNode === na.onUpdateNode && pa.onRememberComposerDefaults === na.onRememberComposerDefaults && pa.isMuted === na.isMuted && pa.onMinimize === na.onMinimize && pa.onToggleMaximize === na.onToggleMaximize && pa.onShowMessage === na.onShowMessage && pa.onEngagementEvent === na.onEngagementEvent && ps.providerRailEmpty === ns.providerRailEmpty && ps.providerUnavailableState === ns.providerUnavailableState && ps.sidebarFooter === ns.sidebarFooter;
32489
+ return pi.nodeId === ni.nodeId && pi.workspaceId === ni.workspaceId && pi.currentUserId === ni.currentUserId && pi.title === ni.title && pw.path === nw.path && pw.fileReferenceAdapter === nw.fileReferenceAdapter && pw.onRequestGitBranches === nw.onRequestGitBranches && pw.selectProjectDirectory === nw.selectProjectDirectory && pw.resolveDroppedFileReferences === nw.resolveDroppedFileReferences && pw.referenceSourceAggregator === nw.referenceSourceAggregator && pw.resolveReferenceEntryIconUrl === nw.resolveReferenceEntryIconUrl && pw.resolveMentionReferenceTarget === nw.resolveMentionReferenceTarget && pw.resolveReferenceInitialTarget === nw.resolveReferenceInitialTarget && pw.onFileReferencesAdded === nw.onFileReferencesAdded && pw.agentSettings.avoidGroupingEdits === nw.agentSettings.avoidGroupingEdits && pc.referenceProvenanceFilterCatalog === nc.referenceProvenanceFilterCatalog && pc.referenceProvenanceFilterEnabled === nc.referenceProvenanceFilterEnabled && agentGuiStateEquals(previous.state, next.state) && pf.position.x === nf.position.x && pf.position.y === nf.position.y && pf.width === nf.width && pf.height === nf.height && pf.desktopSize.width === nf.desktopSize.width && pf.desktopSize.height === nf.desktopSize.height && pf.isMaximized === nf.isMaximized && pf.isActive === nf.isActive && pf.isVisible === nf.isVisible && pf.embedded === nf.embedded && pf.previewMode === nf.previewMode && pf.conversationRailAutoCollapseWidthPx === nf.conversationRailAutoCollapseWidthPx && pr.composerFocusSequence === nr.composerFocusSequence && pr.composerAppend === nr.composerAppend && pr.newConversationSequence === nr.newConversationSequence && pr.openSession === nr.openSession && pr.prefillPrompt === nr.prefillPrompt && pr.agentProbes === nr.agentProbes && pr.onProbeDemandChange === nr.onProbeDemandChange && pr.onProbeRefreshRequest === nr.onProbeRefreshRequest && pc.capabilityMenuState === nc.capabilityMenuState && pc.accountMenuState === nc.accountMenuState && pc.agentTargets === nc.agentTargets && pc.agentTargetsLoading === nc.agentTargetsLoading && pc.providerRailAllPresentation?.iconUrl === nc.providerRailAllPresentation?.iconUrl && pc.providerRailMode === nc.providerRailMode && pc.comingSoonProviders === nc.comingSoonProviders && pc.providerReadinessGates === nc.providerReadinessGates && pc.defaultAgentTargetId === nc.defaultAgentTargetId && pc.providerAuthAccountLabels === nc.providerAuthAccountLabels && pc.contextMentionProviders === nc.contextMentionProviders && pc.workspaceAppIcons === nc.workspaceAppIcons && pc.disabledHomeSuggestions === nc.disabledHomeSuggestions && pa.onLinkAction === na.onLinkAction && pa.onHandoffConversation === na.onHandoffConversation && pa.onCapabilitySettingsRequest === na.onCapabilitySettingsRequest && pa.onAgentProviderLogin === na.onAgentProviderLogin && pa.onOpenConversationWindow === na.onOpenConversationWindow && pa.onClose === na.onClose && pa.onResize === na.onResize && pa.onUpdateNode === na.onUpdateNode && pa.onRememberComposerDefaults === na.onRememberComposerDefaults && pa.isMuted === na.isMuted && pa.onMinimize === na.onMinimize && pa.onToggleMaximize === na.onToggleMaximize && pa.onShowMessage === na.onShowMessage && pa.onEngagementEvent === na.onEngagementEvent && ps.providerRailEmpty === ns.providerRailEmpty && ps.providerUnavailableState === ns.providerUnavailableState && ps.sidebarFooter === ns.sidebarFooter;
32486
32490
  }
32487
32491
 
32488
32492
  // agent-gui/agentGuiNode/AgentGUINode.labels.ts
@@ -33330,6 +33334,11 @@ function resolveAgentGUIRailStatusProvider(input) {
33330
33334
  // agent-gui/agentGuiNode/AgentGUINode.tsx
33331
33335
  import { jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
33332
33336
  var EMPTY_SLASH_STATUS_QUOTAS = [];
33337
+ var DISABLED_REFERENCE_PROVENANCE_CATALOG = {
33338
+ enabledDimensions: [],
33339
+ agentOptions: [],
33340
+ memberOptions: []
33341
+ };
33333
33342
  var AgentGUINode = memo14(function AgentGUINode2({
33334
33343
  identity,
33335
33344
  workspace,
@@ -33369,6 +33378,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
33369
33378
  } = frame;
33370
33379
  const railAutoCollapseWidthPx = conversationRailAutoCollapseWidthPx ?? void 0;
33371
33380
  const {
33381
+ composerAppend: composerAppendRequest = null,
33372
33382
  composerFocusSequence: composerFocusRequestSequence = null,
33373
33383
  newConversationSequence: newConversationRequestSequence = null,
33374
33384
  openSession: openSessionRequest = null,
@@ -33388,28 +33398,21 @@ var AgentGUINode = memo14(function AgentGUINode2({
33388
33398
  providerReadinessGates = null,
33389
33399
  defaultAgentTargetId = null,
33390
33400
  providerAuthAccountLabels,
33391
- managedAgentsState,
33392
33401
  contextMentionProviders,
33393
33402
  workspaceAppIcons,
33394
33403
  disabledHomeSuggestions,
33404
+ referenceProvenanceFilterCatalog: injectedReferenceProvenanceFilterCatalog,
33395
33405
  referenceProvenanceFilterEnabled = false
33396
33406
  } = hostCapabilities;
33397
- const referenceProvenanceFilterBinding = useReferenceProvenanceFilterCatalog({
33398
- enabledDimensions: referenceProvenanceFilterEnabled ? ["agent"] : [],
33399
- agentOptions: referenceProvenanceFilterEnabled ? (agentTargets ?? []).flatMap((target) => {
33400
- const agentTargetId = target.agentTargetId?.trim();
33401
- return agentTargetId ? [
33402
- {
33403
- disabled: target.disabled,
33404
- iconUrl: target.iconUrl,
33405
- id: agentTargetId,
33406
- label: target.label
33407
- }
33408
- ] : [];
33409
- }) : [],
33410
- memberOptions: []
33407
+ const referenceProvenanceFilterCatalog = resolveAgentGUIReferenceProvenanceFilterCatalog({
33408
+ agentTargets,
33409
+ injectedCatalog: injectedReferenceProvenanceFilterCatalog,
33410
+ legacyAgentFilterEnabled: referenceProvenanceFilterEnabled
33411
33411
  });
33412
- const referenceProvenanceFilter = referenceProvenanceFilterEnabled ? referenceProvenanceFilterBinding : null;
33412
+ const referenceProvenanceFilterBinding = useReferenceProvenanceFilterCatalog(
33413
+ referenceProvenanceFilterCatalog ?? DISABLED_REFERENCE_PROVENANCE_CATALOG
33414
+ );
33415
+ const referenceProvenanceFilter = referenceProvenanceFilterBinding.snapshot.catalog.enabledDimensions.length > 0 ? referenceProvenanceFilterBinding : null;
33413
33416
  const {
33414
33417
  onLinkAction,
33415
33418
  onHandoffConversation,
@@ -33559,6 +33562,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
33559
33562
  workspacePath,
33560
33563
  avoidGroupingEdits: agentSettings.avoidGroupingEdits,
33561
33564
  data: state,
33565
+ composerAppendRequest,
33562
33566
  openSessionRequest,
33563
33567
  prefillPromptRequest,
33564
33568
  agentTargets,
@@ -33595,7 +33599,6 @@ var AgentGUINode = memo14(function AgentGUINode2({
33595
33599
  );
33596
33600
  const fallbackAgentTitle = t("sidebar.fallbackAgentLabel");
33597
33601
  const activeProvider = viewModel.rail.activeConversation?.provider ?? state.provider;
33598
- const activeReadinessProvider = viewModel.rail.activeConversationId !== null ? activeProvider : viewModel.rail.selectedAgentTarget.provider;
33599
33602
  const selectedAgentTargetLabel = viewModel.rail.selectedAgentTarget?.label ?? resolveAgentGUIProviderDisplayLabel(state.provider, fallbackAgentTitle);
33600
33603
  const displayProviderLabel = viewModel.rail.activeConversation ? resolveAgentGUIProviderDisplayLabel(activeProvider, fallbackAgentTitle) : selectedAgentTargetLabel;
33601
33604
  const labels = useAgentGUIViewLabels({
@@ -33630,21 +33633,6 @@ var AgentGUINode = memo14(function AgentGUINode2({
33630
33633
  ) : null,
33631
33634
  [railStatusProvider, workspaceAgentProbes?.snapshot]
33632
33635
  );
33633
- const isActiveAgentProviderReady = useMemo39(() => {
33634
- const managedAgent = getAgentHostManagedToolchainAgentByName(
33635
- activeReadinessProvider
33636
- );
33637
- if (!managedAgent) {
33638
- return true;
33639
- }
33640
- if (!managedAgentsState) {
33641
- return true;
33642
- }
33643
- return resolveAgentHostManagedToolchainAgentAction(
33644
- managedAgent,
33645
- managedAgentsState
33646
- ) === "installed";
33647
- }, [activeReadinessProvider, managedAgentsState]);
33648
33636
  const canonicalSlashStatusQuotas = viewModel.detail.usage?.quotas ?? EMPTY_SLASH_STATUS_QUOTAS;
33649
33637
  const slashStatusQuotaSource = canonicalSlashStatusQuotas.length > 0 ? canonicalSlashStatusQuotas : activeAgentProbe?.usage?.quotas && activeAgentProbe.usage.quotas.length > 0 ? activeAgentProbe.usage.quotas : EMPTY_SLASH_STATUS_QUOTAS;
33650
33638
  const slashStatusLimits = useMemo39(
@@ -33824,7 +33812,6 @@ var AgentGUINode = memo14(function AgentGUINode2({
33824
33812
  onEngagementEvent,
33825
33813
  composerFocusRequestSequence,
33826
33814
  newConversationRequestSequence,
33827
- isAgentProviderReady: isActiveAgentProviderReady,
33828
33815
  slashStatusLimits,
33829
33816
  slashStatusLimitsLoading: workspaceAgentProbes?.isLoadingUsage ?? false,
33830
33817
  slashStatusLimitsUnavailable,
@@ -33932,4 +33919,4 @@ export {
33932
33919
  resolveAgentGUIAgentTarget,
33933
33920
  AgentGUI
33934
33921
  };
33935
- //# sourceMappingURL=chunk-BQJOYTW2.js.map
33922
+ //# sourceMappingURL=chunk-LHKBR77G.js.map