@tutti-os/agent-gui 0.0.59 → 0.0.61

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 (97) hide show
  1. package/README.md +1 -1
  2. package/dist/@-bold-lined-BLLFKBFI.svg +10 -0
  3. package/dist/add-lined-bold-5QPUDZCU.svg +3 -0
  4. package/dist/agent-conversation/index.d.ts +2 -2
  5. package/dist/agent-conversation/index.js +7 -7
  6. package/dist/agent-message-center/index.js +17 -11
  7. package/dist/agent-message-center/index.js.map +1 -1
  8. package/dist/{agentGuiNodeTypes-CupCLd9p.d.ts → agentGuiNodeTypes-CC52zXAV.d.ts} +7 -4
  9. package/dist/app/renderer/agentactivity.css +533 -56
  10. package/dist/app/renderer/assets/icons/@-bold-lined.svg +10 -0
  11. package/dist/app/renderer/assets/icons/@-lined.svg +10 -0
  12. package/dist/app/renderer/assets/icons/add-lined-bold.svg +3 -0
  13. package/dist/app/renderer/assets/icons/add-lined-icon.svg +3 -0
  14. package/dist/app/renderer/assets/icons/add-lined.svg +3 -0
  15. package/dist/app/renderer/assets/icons/agents/claudecode-flat-filled.svg +10 -0
  16. package/dist/app/renderer/assets/icons/agents/codex-flat-filled.svg +10 -0
  17. package/dist/app/renderer/assets/icons/agents/provider-rail-claude-code-colorful.png +0 -0
  18. package/dist/app/renderer/assets/icons/agents/provider-rail-codex-colorful.png +0 -0
  19. package/dist/app/renderer/assets/icons/agents/provider-rail-hermes-colorful.png +0 -0
  20. package/dist/app/renderer/assets/icons/agents/provider-rail-tutti.png +0 -0
  21. package/dist/app/renderer/assets/icons/handoff-lined.png +0 -0
  22. package/dist/app/renderer/assets/icons/handoff-lined.svg +11 -0
  23. package/dist/{chunk-5SRRKWE4.js → chunk-24CUBQKJ.js} +2 -2
  24. package/dist/{chunk-NX6T3DDS.js → chunk-2LGUBUEJ.js} +3 -3
  25. package/dist/{chunk-4PSDYKZQ.js → chunk-3KS22CG2.js} +12 -9
  26. package/dist/chunk-3KS22CG2.js.map +1 -0
  27. package/dist/{chunk-UCCUIUGK.js → chunk-4OPTXOOZ.js} +2 -2
  28. package/dist/{chunk-Q75AK47T.js → chunk-5WB3NGIN.js} +2 -2
  29. package/dist/{chunk-2WUDORCV.js → chunk-6TEPDMX6.js} +2 -2
  30. package/dist/{chunk-IS6JUDDY.js → chunk-6VVBG4BF.js} +44 -20
  31. package/dist/chunk-6VVBG4BF.js.map +1 -0
  32. package/dist/{chunk-OLI2A3EM.js → chunk-74TIEA6X.js} +2 -2
  33. package/dist/{chunk-SLT5Q37C.js → chunk-B6YDXIZW.js} +5 -3
  34. package/dist/{chunk-SLT5Q37C.js.map → chunk-B6YDXIZW.js.map} +1 -1
  35. package/dist/{chunk-BT5WEZO5.js → chunk-CUMZV32B.js} +5 -5
  36. package/dist/chunk-CUMZV32B.js.map +1 -0
  37. package/dist/{chunk-OFMORNBO.js → chunk-CZSMZRAV.js} +23 -6
  38. package/dist/chunk-CZSMZRAV.js.map +1 -0
  39. package/dist/{chunk-HVU46DDA.js → chunk-FRCIPTUD.js} +13 -2
  40. package/dist/chunk-FRCIPTUD.js.map +1 -0
  41. package/dist/{chunk-CEMXB7LA.js → chunk-I5ZIKJVN.js} +2 -2
  42. package/dist/{chunk-Z2BTIAOC.js → chunk-IIVHPXAB.js} +1 -1
  43. package/dist/chunk-IIVHPXAB.js.map +1 -0
  44. package/dist/{chunk-OQJSZSYB.js → chunk-JBWFRSFQ.js} +2 -2
  45. package/dist/{chunk-BEFNWUOZ.js → chunk-JLJIAKI3.js} +379 -317
  46. package/dist/chunk-JLJIAKI3.js.map +1 -0
  47. package/dist/{chunk-N756UO52.js → chunk-JSIA4K67.js} +68 -65
  48. package/dist/chunk-JSIA4K67.js.map +1 -0
  49. package/dist/{chunk-7GM7UQXD.js → chunk-SXML6H77.js} +47 -8
  50. package/dist/chunk-SXML6H77.js.map +1 -0
  51. package/dist/{chunk-MTFSQWZ6.js → chunk-V4JGVBUN.js} +22 -2
  52. package/dist/chunk-V4JGVBUN.js.map +1 -0
  53. package/dist/claudecode-flat-filled-NHO4JCVK.svg +10 -0
  54. package/dist/codex-flat-filled-WYHCF5VR.svg +10 -0
  55. package/dist/context-mention-palette/index.js +8 -8
  56. package/dist/handoff-lined-4WQUBVG3.svg +11 -0
  57. package/dist/i18n/index.d.ts +43 -19
  58. package/dist/i18n/index.js +2 -2
  59. package/dist/index.d.ts +47 -20
  60. package/dist/index.js +1424 -521
  61. package/dist/index.js.map +1 -1
  62. package/dist/queued-prompt-runtime.d.ts +2 -2
  63. package/dist/{types-BsHvTjIZ.d.ts → types-DSc2ta3s.d.ts} +1 -1
  64. package/dist/workbench/contribution.d.ts +4 -8
  65. package/dist/workbench/contribution.js +9 -7
  66. package/dist/workbench/index.d.ts +4 -4
  67. package/dist/workbench/index.js +10 -12
  68. package/dist/workbench/launch.d.ts +6 -7
  69. package/dist/workbench/launch.js +2 -4
  70. package/dist/workbench/providerCatalog.d.ts +1 -1
  71. package/dist/workbench/sessionTitle.d.ts +1 -1
  72. package/dist/workbench/sessionTitle.js +3 -3
  73. package/dist/workbench/state.d.ts +1 -1
  74. package/dist/workbench/state.js +2 -2
  75. package/dist/workbench/types.d.ts +4 -1
  76. package/dist/workbench/types.js +1 -1
  77. package/dist/workspace-agent-generated-files.js +3 -3
  78. package/package.json +12 -12
  79. package/dist/@-lined-14px-64O2KKB4.svg +0 -3
  80. package/dist/chunk-4PSDYKZQ.js.map +0 -1
  81. package/dist/chunk-7GM7UQXD.js.map +0 -1
  82. package/dist/chunk-BEFNWUOZ.js.map +0 -1
  83. package/dist/chunk-BT5WEZO5.js.map +0 -1
  84. package/dist/chunk-HVU46DDA.js.map +0 -1
  85. package/dist/chunk-IS6JUDDY.js.map +0 -1
  86. package/dist/chunk-MTFSQWZ6.js.map +0 -1
  87. package/dist/chunk-N756UO52.js.map +0 -1
  88. package/dist/chunk-OFMORNBO.js.map +0 -1
  89. package/dist/chunk-Z2BTIAOC.js.map +0 -1
  90. /package/dist/{chunk-5SRRKWE4.js.map → chunk-24CUBQKJ.js.map} +0 -0
  91. /package/dist/{chunk-NX6T3DDS.js.map → chunk-2LGUBUEJ.js.map} +0 -0
  92. /package/dist/{chunk-UCCUIUGK.js.map → chunk-4OPTXOOZ.js.map} +0 -0
  93. /package/dist/{chunk-Q75AK47T.js.map → chunk-5WB3NGIN.js.map} +0 -0
  94. /package/dist/{chunk-2WUDORCV.js.map → chunk-6TEPDMX6.js.map} +0 -0
  95. /package/dist/{chunk-OLI2A3EM.js.map → chunk-74TIEA6X.js.map} +0 -0
  96. /package/dist/{chunk-CEMXB7LA.js.map → chunk-I5ZIKJVN.js.map} +0 -0
  97. /package/dist/{chunk-OQJSZSYB.js.map → chunk-JBWFRSFQ.js.map} +0 -0
package/dist/index.js CHANGED
@@ -9,20 +9,22 @@ import {
9
9
  resolveAgentGUIExpandedWindowFrame,
10
10
  resolveNextAgentGUIConversationRailWidthPx,
11
11
  shouldAutoCollapseAgentGUIConversationRail
12
- } from "./chunk-Q75AK47T.js";
12
+ } from "./chunk-5WB3NGIN.js";
13
13
  import {
14
14
  agentGUIDefaultTargetProviders,
15
15
  agentGUIProviderTargetRefsEqual,
16
+ createDisabledPlaceholderAgentGUIProviderTarget,
16
17
  createLocalAgentGUIProviderTarget,
17
18
  createLocalAgentGUIProviderTargets,
19
+ localAgentGUIAgentTargetId,
18
20
  localAgentGUIProviderTargetId,
19
21
  normalizeAgentGUIProviderTargets,
20
22
  resolveAgentGUIProviderTarget
21
- } from "./chunk-7GM7UQXD.js";
23
+ } from "./chunk-SXML6H77.js";
22
24
  import {
23
25
  AgentInteractivePromptSurface,
24
26
  approvalOptionDisplayLabel
25
- } from "./chunk-OFMORNBO.js";
27
+ } from "./chunk-CZSMZRAV.js";
26
28
  import {
27
29
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
28
30
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -41,7 +43,7 @@ import {
41
43
  resolveAgentGUIExplicitConversationTitle,
42
44
  resolveAgentGUIProviderDisplayLabel,
43
45
  resolveAgentGUIProviderIdentity
44
- } from "./chunk-UCCUIUGK.js";
46
+ } from "./chunk-4OPTXOOZ.js";
45
47
  import {
46
48
  AgentConversationFlow,
47
49
  Button,
@@ -62,14 +64,14 @@ import {
62
64
  skillTriggerForPrefix,
63
65
  toLocalShortDateTime,
64
66
  useProjectedAgentConversation
65
- } from "./chunk-BEFNWUOZ.js";
67
+ } from "./chunk-JLJIAKI3.js";
66
68
  import {
67
69
  AgentMessageMarkdown,
68
70
  AgentTargetPresentationProvider,
69
71
  ZoomableImage,
70
72
  cn,
71
73
  resolveWorkspaceLinkAction
72
- } from "./chunk-SLT5Q37C.js";
74
+ } from "./chunk-B6YDXIZW.js";
73
75
  import {
74
76
  openAgentEnvPanel
75
77
  } from "./chunk-PSLAWU25.js";
@@ -80,7 +82,7 @@ import {
80
82
  DEFAULT_AGENT_MENTION_FILTER,
81
83
  agentMentionItemKey,
82
84
  preloadAgentMentionBrowse
83
- } from "./chunk-BT5WEZO5.js";
85
+ } from "./chunk-CUMZV32B.js";
84
86
  import {
85
87
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
86
88
  buildWorkspaceAgentActivityListViewModel,
@@ -90,10 +92,10 @@ import {
90
92
  isWorkspaceAgentUntitledTask,
91
93
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
92
94
  selectWorkspaceAgentActivityOverlayMessages
93
- } from "./chunk-CEMXB7LA.js";
95
+ } from "./chunk-I5ZIKJVN.js";
94
96
  import {
95
97
  Spinner
96
- } from "./chunk-OLI2A3EM.js";
98
+ } from "./chunk-74TIEA6X.js";
97
99
  import {
98
100
  resolveWorkspaceAgentSessionSortTimeUnixMs
99
101
  } from "./chunk-IBIMGLCD.js";
@@ -104,7 +106,7 @@ import {
104
106
  mentionItemToAttrs,
105
107
  normalizeAgentSessionMentionTitle,
106
108
  parseMentionItemFromHref
107
- } from "./chunk-NX6T3DDS.js";
109
+ } from "./chunk-2LGUBUEJ.js";
108
110
  import "./chunk-Y35GDLP2.js";
109
111
  import "./chunk-LUGELG5V.js";
110
112
  import {
@@ -112,6 +114,7 @@ import {
112
114
  AgentActivityRuntimeProvider,
113
115
  MANAGED_AGENT_ICON_FALLBACK_URL,
114
116
  MANAGED_AGENT_ICON_URLS,
117
+ MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS,
115
118
  getAgentActivityRuntime,
116
119
  getAgentCustomMentionKind,
117
120
  getOptionalAgentActivityRuntime,
@@ -126,7 +129,7 @@ import {
126
129
  useAgentHostApi,
127
130
  useOptionalAgentActivityRuntime,
128
131
  useOptionalAgentHostApi
129
- } from "./chunk-HVU46DDA.js";
132
+ } from "./chunk-FRCIPTUD.js";
130
133
  import "./chunk-TYGL25EL.js";
131
134
  import {
132
135
  AgentGuiI18nProvider,
@@ -134,10 +137,10 @@ import {
134
137
  agentGuiI18nResources,
135
138
  translate,
136
139
  useTranslation
137
- } from "./chunk-5SRRKWE4.js";
140
+ } from "./chunk-24CUBQKJ.js";
138
141
  import "./chunk-PJP5BUU6.js";
139
- import "./chunk-MTFSQWZ6.js";
140
- import "./chunk-IS6JUDDY.js";
142
+ import "./chunk-V4JGVBUN.js";
143
+ import "./chunk-6VVBG4BF.js";
141
144
  import {
142
145
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
143
146
  } from "./chunk-JM24HADP.js";
@@ -310,7 +313,7 @@ import { memo as memo3 } from "react";
310
313
  import { TooltipProvider as TooltipProvider3 } from "@tutti-os/ui-system";
311
314
 
312
315
  // agent-gui/agentGuiNode/AgentGUINode.tsx
313
- import { memo as memo2, useCallback as useCallback12, useEffect as useEffect14, useMemo as useMemo11 } from "react";
316
+ import { memo as memo2, useCallback as useCallback12, useEffect as useEffect15, useMemo as useMemo11 } from "react";
314
317
  import { createWorkspaceUserProjectI18nRuntime } from "@tutti-os/workspace-user-project/i18n";
315
318
  import { createWorkspaceFileManagerI18nRuntime } from "@tutti-os/workspace-file-manager";
316
319
 
@@ -6653,6 +6656,28 @@ function nodeDataFromComposerSettings(current, settings) {
6653
6656
  };
6654
6657
  }
6655
6658
 
6659
+ // agent-gui/agentGuiNode/controller/agentGuiController.sessionHelpers.ts
6660
+ function mergeAgentSessionControlStateSnapshot(current, snapshot3) {
6661
+ const incomingUsage = recordValue2(snapshot3.runtimeContext?.usage);
6662
+ if (incomingUsage || !current) {
6663
+ return snapshot3;
6664
+ }
6665
+ const previousUsage = recordValue2(current.runtimeContext?.usage);
6666
+ if (!previousUsage) {
6667
+ return snapshot3;
6668
+ }
6669
+ return {
6670
+ ...snapshot3,
6671
+ runtimeContext: {
6672
+ ...snapshot3.runtimeContext ?? {},
6673
+ usage: previousUsage
6674
+ }
6675
+ };
6676
+ }
6677
+ function recordValue2(value) {
6678
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
6679
+ }
6680
+
6656
6681
  // agent-gui/agentGuiNode/controller/useAgentGUINodeController.ts
6657
6682
  var EMPTY_AGENT_GUI_MESSAGES = [];
6658
6683
  var EMPTY_AGENT_GUI_AVAILABLE_COMMANDS = [];
@@ -6684,21 +6709,26 @@ var AGENT_PROVIDER_SESSION_NOT_FOUND_FALLBACK_MESSAGE = "The previous agent sess
6684
6709
  var AGENT_RESUME_SESSION_NOT_LOCAL_FALLBACK_MESSAGE = "The previous agent session is not available on this machine.";
6685
6710
  var AGENT_GUI_CAUGHT_ERROR_STACK_LIMIT = 4e3;
6686
6711
  var SELECTED_SESSION_NOT_FOUND_RETRY_DELAY_MS = 150;
6687
- function composerDefaultsFromSettings(settings) {
6688
- const defaults = {};
6689
- const model = normalizeOptionalText2(settings.model);
6690
- const permissionModeId = normalizeOptionalText2(settings.permissionModeId);
6691
- const reasoningEffort = normalizeOptionalText2(settings.reasoningEffort);
6692
- if (model) {
6693
- defaults.model = model;
6694
- }
6695
- if (permissionModeId) {
6696
- defaults.permissionModeId = permissionModeId;
6697
- }
6698
- if (reasoningEffort) {
6699
- defaults.reasoningEffort = reasoningEffort;
6712
+ var rememberComposerDefaultsFields = [
6713
+ "model",
6714
+ "permissionModeId",
6715
+ "reasoningEffort",
6716
+ "speed"
6717
+ ];
6718
+ function composerDefaultsPatchFromSettings(touched, finalSettings) {
6719
+ const patch = {};
6720
+ for (const field of rememberComposerDefaultsFields) {
6721
+ if (touched[field] === void 0) {
6722
+ continue;
6723
+ }
6724
+ const touchedValue = normalizeOptionalText2(touched[field]);
6725
+ const finalValue = normalizeOptionalText2(finalSettings[field]);
6726
+ if (touchedValue !== null && finalValue === null) {
6727
+ continue;
6728
+ }
6729
+ patch[field] = finalValue;
6700
6730
  }
6701
- return Object.keys(defaults).length > 0 ? defaults : null;
6731
+ return Object.keys(patch).length > 0 ? patch : null;
6702
6732
  }
6703
6733
  function composerTargetDataFromProviderTarget(input) {
6704
6734
  const agentTargetId = normalizeOptionalText2(input.target.agentTargetId);
@@ -7849,7 +7879,7 @@ function hasRejectedApprovalDecision(timelineItems) {
7849
7879
  if (status !== "completed") {
7850
7880
  return false;
7851
7881
  }
7852
- const output = recordValue2(payload.output);
7882
+ const output = recordValue3(payload.output);
7853
7883
  return isRejectedApprovalDecision(output);
7854
7884
  });
7855
7885
  }
@@ -7982,7 +8012,7 @@ function normalizeAgentGUIOpenSessionRequest(request) {
7982
8012
  sequence: request.sequence
7983
8013
  };
7984
8014
  }
7985
- function recordValue2(value) {
8015
+ function recordValue3(value) {
7986
8016
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
7987
8017
  }
7988
8018
  function numberValue(value) {
@@ -7996,7 +8026,7 @@ function numberValue(value) {
7996
8026
  return null;
7997
8027
  }
7998
8028
  function activeBackgroundAgentCount(runtimeContext) {
7999
- const backgroundAgents = recordValue2(runtimeContext?.backgroundAgents);
8029
+ const backgroundAgents = recordValue3(runtimeContext?.backgroundAgents);
8000
8030
  if (!backgroundAgents) {
8001
8031
  return 0;
8002
8032
  }
@@ -8006,7 +8036,7 @@ function activeBackgroundAgentCount(runtimeContext) {
8006
8036
  return count === null ? 0 : Math.max(0, Math.floor(count));
8007
8037
  }
8008
8038
  return items.filter((item) => {
8009
- const record = recordValue2(item);
8039
+ const record = recordValue3(item);
8010
8040
  if (!record) {
8011
8041
  return false;
8012
8042
  }
@@ -8021,7 +8051,7 @@ function activeBackgroundAgentCount(runtimeContext) {
8021
8051
  }).length;
8022
8052
  }
8023
8053
  function appServerStartupMetadata(runtimeContext) {
8024
- return recordValue2(runtimeContext?.appServerStartup);
8054
+ return recordValue3(runtimeContext?.appServerStartup);
8025
8055
  }
8026
8056
  function isAppServerStartupLoading(runtimeContext, key) {
8027
8057
  return appServerStartupMetadata(runtimeContext)?.[key] === "loading";
@@ -8043,6 +8073,24 @@ function modelSelectionFromComposerOptions(options, currentValue) {
8043
8073
  currentValue
8044
8074
  };
8045
8075
  }
8076
+ function configOptionCurrentValue(runtimeContext, ids) {
8077
+ const rawConfigOptions = Array.isArray(runtimeContext?.configOptions) ? runtimeContext.configOptions : [];
8078
+ const idSet = new Set(ids);
8079
+ for (const rawOption of rawConfigOptions) {
8080
+ const option = recordValue3(rawOption);
8081
+ if (!option) {
8082
+ continue;
8083
+ }
8084
+ const id = normalizeOptionalText2(option.id);
8085
+ if (!id || !idSet.has(id)) {
8086
+ continue;
8087
+ }
8088
+ return normalizeOptionalText2(
8089
+ option.currentValue ?? option.current_value
8090
+ );
8091
+ }
8092
+ return null;
8093
+ }
8046
8094
  function reasoningSelectionFromComposerOptions(options, currentValue) {
8047
8095
  if (!options) {
8048
8096
  return null;
@@ -8741,7 +8789,6 @@ function useAgentGUINodeController({
8741
8789
  workspacePath,
8742
8790
  avoidGroupingEdits,
8743
8791
  data,
8744
- conversationScope = "single-provider",
8745
8792
  providerTargets,
8746
8793
  providerTargetsLoading = false,
8747
8794
  providerReadinessGates = null,
@@ -8759,23 +8806,35 @@ function useAgentGUINodeController({
8759
8806
  const agentActivitySnapshot = useAgentActivitySnapshot(workspaceId);
8760
8807
  const normalizedExplicitProviderTargets = useMemo4(
8761
8808
  () => normalizeAgentGUIProviderTargets(providerTargets, {
8762
- fallbackToLocal: false
8809
+ includeDisabledPlaceholders: true,
8810
+ useStaticCatalog: false
8763
8811
  }),
8764
8812
  [providerTargets]
8765
8813
  );
8766
- const normalizedProviderTargets = useMemo4(
8767
- () => providerTargetsLoading ? [] : providerTargets === void 0 ? normalizeAgentGUIProviderTargets(null) : normalizedExplicitProviderTargets,
8768
- [normalizedExplicitProviderTargets, providerTargets, providerTargetsLoading]
8769
- );
8770
- const shouldFallbackToLocalProviderTargets = providerTargets === void 0 && !providerTargetsLoading;
8814
+ const normalizedProviderTargets = useMemo4(() => {
8815
+ if (providerTargetsLoading) {
8816
+ return [];
8817
+ }
8818
+ if (providerTargets === void 0 || normalizedExplicitProviderTargets.length === 0) {
8819
+ return normalizeAgentGUIProviderTargets(null, {
8820
+ includeDisabledPlaceholders: true
8821
+ });
8822
+ }
8823
+ return normalizedExplicitProviderTargets;
8824
+ }, [
8825
+ normalizedExplicitProviderTargets,
8826
+ providerTargets,
8827
+ providerTargetsLoading
8828
+ ]);
8829
+ const shouldUseStaticProviderTargets = !providerTargetsLoading && (providerTargets === void 0 || normalizedExplicitProviderTargets.length === 0);
8771
8830
  const selectedProviderTarget = useMemo4(() => {
8772
8831
  const resolved = resolveAgentGUIProviderTarget({
8773
8832
  agentTargetId: data.agentTargetId,
8774
8833
  defaultProviderTargetId,
8775
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
8776
8834
  provider: data.provider,
8777
8835
  providerTargetId: data.providerTargetId,
8778
- providerTargets: normalizedProviderTargets
8836
+ providerTargets: normalizedProviderTargets,
8837
+ useStaticCatalog: shouldUseStaticProviderTargets
8779
8838
  });
8780
8839
  return resolved ?? {
8781
8840
  targetId: data.agentTargetId ?? "__loading__",
@@ -8793,7 +8852,7 @@ function useAgentGUINodeController({
8793
8852
  data.providerTargetId,
8794
8853
  defaultProviderTargetId,
8795
8854
  normalizedProviderTargets,
8796
- shouldFallbackToLocalProviderTargets
8855
+ shouldUseStaticProviderTargets
8797
8856
  ]);
8798
8857
  const selectedProviderTargetIsExplicit = useMemo4(
8799
8858
  () => normalizedExplicitProviderTargets.some(
@@ -8870,14 +8929,6 @@ function useAgentGUINodeController({
8870
8929
  );
8871
8930
  const conversationFilterRef = useRef4(conversationFilter);
8872
8931
  conversationFilterRef.current = conversationFilter;
8873
- const canUseConversationTargetFilter = conversationScope === "multi-provider";
8874
- const queryConversationFilter = canUseConversationTargetFilter ? conversationFilter : null;
8875
- useEffect4(() => {
8876
- if (canUseConversationTargetFilter || conversationFilter.kind === "all") {
8877
- return;
8878
- }
8879
- setConversationFilter({ kind: "all" });
8880
- }, [canUseConversationTargetFilter, conversationFilter]);
8881
8932
  const conversationListQuery = useMemo4(() => {
8882
8933
  const userId = currentUserId?.trim() ?? "";
8883
8934
  const provider = data.provider?.trim() ?? "";
@@ -8885,13 +8936,13 @@ function useAgentGUINodeController({
8885
8936
  return null;
8886
8937
  }
8887
8938
  return {
8888
- ...queryConversationFilter ? { conversationFilter: queryConversationFilter } : {},
8939
+ conversationFilter,
8889
8940
  workspaceId,
8890
8941
  userId,
8891
8942
  provider: data.provider,
8892
8943
  sessionOrigin: AGENT_GUI_RUNTIME_SESSION_ORIGIN
8893
8944
  };
8894
- }, [currentUserId, data.provider, queryConversationFilter, workspaceId]);
8945
+ }, [currentUserId, data.provider, conversationFilter, workspaceId]);
8895
8946
  const conversationListState = useAgentGuiConversationList(
8896
8947
  conversationListQuery
8897
8948
  );
@@ -9002,6 +9053,10 @@ function useAgentGUINodeController({
9002
9053
  composerOptions: providerComposerOptions,
9003
9054
  sessionRuntimeContext: activeSessionState?.runtimeContext
9004
9055
  });
9056
+ const goalPauseSupported = resolveAgentActivityCapability2("goalPause", {
9057
+ composerOptions: providerComposerOptions,
9058
+ sessionRuntimeContext: activeSessionState?.runtimeContext
9059
+ }) ?? false;
9005
9060
  const activeSessionRuntimeContext = activeSessionState?.runtimeContext;
9006
9061
  const backgroundAgentCount = useMemo4(
9007
9062
  () => activeBackgroundAgentCount(activeSessionRuntimeContext),
@@ -10253,9 +10308,9 @@ function useAgentGUINodeController({
10253
10308
  ...sessionStateSnapshotCauseBySessionIdRef.current,
10254
10309
  [agentSessionId]: cause ? { source: cause.source } : void 0
10255
10310
  };
10256
- setAgentSessionViewControlState(
10311
+ updateAgentSessionViewControlState(
10257
10312
  sessionViewRef(agentSessionId),
10258
- snapshot3
10313
+ (current) => mergeAgentSessionControlStateSnapshot(current, snapshot3)
10259
10314
  );
10260
10315
  } catch (error) {
10261
10316
  if (!isMountedRef.current || cause?.allowInactive !== true && activeConversationIdRef.current !== agentSessionId) {
@@ -11924,13 +11979,13 @@ function useAgentGUINodeController({
11924
11979
  setDetailError(null);
11925
11980
  persistActiveConversation(null);
11926
11981
  const filter = conversationFilterRef.current;
11927
- if (canUseConversationTargetFilter && filter.kind === "agentTarget") {
11982
+ if (filter.kind === "agentTarget") {
11928
11983
  const filterTarget = resolveAgentGUIProviderTarget({
11929
11984
  agentTargetId: filter.agentTargetId,
11930
11985
  defaultProviderTargetId,
11931
- fallbackToLocal: false,
11932
11986
  provider: dataRef.current.provider,
11933
- providerTargets: normalizedProviderTargets
11987
+ providerTargets: normalizedProviderTargets,
11988
+ useStaticCatalog: false
11934
11989
  });
11935
11990
  if (filterTarget && filterTarget.disabled !== true && (filterTarget.agentTargetId?.trim() ?? "") === filter.agentTargetId) {
11936
11991
  setHomeComposerTargetOverride(filterTarget);
@@ -11941,7 +11996,6 @@ function useAgentGUINodeController({
11941
11996
  [
11942
11997
  activation,
11943
11998
  agentActivityRuntime,
11944
- canUseConversationTargetFilter,
11945
11999
  defaultProviderTargetId,
11946
12000
  loadDraftComposerOptions,
11947
12001
  normalizedProviderTargets,
@@ -11987,13 +12041,12 @@ function useAgentGUINodeController({
11987
12041
  setActiveConversationId(null);
11988
12042
  setIsLoadingMessages(false);
11989
12043
  setDetailError(null);
11990
- const targetData = selectedComposerTargetDataRef.current;
12044
+ const selectedTargetData = selectedComposerTargetDataRef.current;
12045
+ const targetProvider = prefillPromptRequest.provider ?? selectedTargetData.provider;
12046
+ const targetAgentTargetId = prefillPromptRequest.agentTargetId ?? selectedTargetData.agentTargetId;
11991
12047
  setDraftBySessionId((current) => ({
11992
12048
  ...current,
11993
- [nodeDefaultDraftContentKey(
11994
- targetData.provider,
11995
- targetData.agentTargetId
11996
- )]: {
12049
+ [nodeDefaultDraftContentKey(targetProvider, targetAgentTargetId)]: {
11997
12050
  ...emptyAgentComposerDraft(),
11998
12051
  prompt: draftPrompt2
11999
12052
  }
@@ -12514,6 +12567,36 @@ function useAgentGUINodeController({
12514
12567
  shouldQueuePromptLocally
12515
12568
  ]
12516
12569
  );
12570
+ const goalControl = useCallback4(
12571
+ (action, objective) => {
12572
+ if (previewMode) {
12573
+ return;
12574
+ }
12575
+ const agentSessionId = activeConversationIdRef.current;
12576
+ if (!agentSessionId) {
12577
+ return;
12578
+ }
12579
+ setDetailError(null);
12580
+ void agentActivityRuntime.goalControl({
12581
+ workspaceId,
12582
+ agentSessionId,
12583
+ action,
12584
+ ...objective !== void 0 ? { objective } : {}
12585
+ }).catch((error) => {
12586
+ if (!isCurrentConversation(agentSessionId)) {
12587
+ return;
12588
+ }
12589
+ setDetailError(getAgentGUIErrorMessage(error));
12590
+ });
12591
+ },
12592
+ [
12593
+ agentActivityRuntime,
12594
+ isCurrentConversation,
12595
+ previewMode,
12596
+ setDetailError,
12597
+ workspaceId
12598
+ ]
12599
+ );
12517
12600
  const submitPrompt = useCallback4(
12518
12601
  (content, displayPrompt) => {
12519
12602
  if (previewMode) {
@@ -12875,10 +12958,12 @@ function useAgentGUINodeController({
12875
12958
  }).then((result) => {
12876
12959
  const queuedUpdate = queuedComposerSettingsUpdatesRef.current[agentSessionId] ?? null;
12877
12960
  const optimisticSettings = queuedUpdate?.sessionSettingsPatch ?? null;
12878
- const nextAppliedSettings = optimisticSettings ? {
12961
+ const pendingClaudeModelRefreshSettings = dataRef.current.provider === "claude-code" && sessionSettingsPatch.model !== void 0 ? { model: sessionSettingsPatch.model } : null;
12962
+ const nextAppliedSettings = {
12879
12963
  ...result.settings,
12880
- ...optimisticSettings
12881
- } : result.settings;
12964
+ ...pendingClaudeModelRefreshSettings ?? {},
12965
+ ...optimisticSettings ?? {}
12966
+ };
12882
12967
  updateAgentSessionViewControlState(
12883
12968
  sessionViewRef(agentSessionId),
12884
12969
  (existing) => existing ? {
@@ -13003,8 +13088,12 @@ function useAgentGUINodeController({
13003
13088
  )
13004
13089
  );
13005
13090
  void onRememberComposerDefaultsRef.current?.({
13091
+ agentTargetId: targetData.agentTargetId,
13006
13092
  provider: targetData.provider,
13007
- defaults: composerDefaultsFromSettings(targetSafeMerged)
13093
+ defaults: composerDefaultsPatchFromSettings(
13094
+ supportedNextSettings,
13095
+ targetSafeMerged
13096
+ )
13008
13097
  });
13009
13098
  void agentActivityRuntime.trackDraftComposerSettingsChange?.({
13010
13099
  workspaceId,
@@ -13076,6 +13165,46 @@ function useAgentGUINodeController({
13076
13165
  }
13077
13166
  } : existing
13078
13167
  );
13168
+ void onRememberComposerDefaultsRef.current?.({
13169
+ agentTargetId: normalizeOptionalText2(dataRef.current.agentTargetId),
13170
+ provider: dataRef.current.provider,
13171
+ defaults: composerDefaultsPatchFromSettings(
13172
+ sessionSettingsPatch,
13173
+ sessionSettingsPatch
13174
+ )
13175
+ });
13176
+ const durableNodeDefaultsPatch = {};
13177
+ for (const field of rememberComposerDefaultsFields) {
13178
+ if (sessionSettingsPatch[field] !== void 0) {
13179
+ durableNodeDefaultsPatch[field] = sessionSettingsPatch[field];
13180
+ }
13181
+ }
13182
+ if (Object.keys(durableNodeDefaultsPatch).length > 0) {
13183
+ const defaultDraftKey = nodeDefaultDraftKey(
13184
+ dataRef.current.provider,
13185
+ dataRef.current.agentTargetId
13186
+ );
13187
+ const storedNodeDefaults = readNodeDefaultDraftSettings({
13188
+ data: dataRef.current,
13189
+ defaultReasoningEffort,
13190
+ drafts: draftSettingsBySessionIdRef.current
13191
+ });
13192
+ const nextNodeDefaults = {
13193
+ ...storedNodeDefaults,
13194
+ ...durableNodeDefaultsPatch
13195
+ };
13196
+ draftSettingsBySessionIdRef.current = {
13197
+ ...draftSettingsBySessionIdRef.current,
13198
+ [defaultDraftKey]: nextNodeDefaults
13199
+ };
13200
+ setDraftSettingsBySessionId((current) => ({
13201
+ ...current,
13202
+ [defaultDraftKey]: nextNodeDefaults
13203
+ }));
13204
+ onDataChangeRef.current(
13205
+ (current) => nodeDataFromComposerSettings(current, nextNodeDefaults)
13206
+ );
13207
+ }
13079
13208
  if (updatingSessionSettingsIdsRef.current[agentSessionId]) {
13080
13209
  const queuedUpdate = queuedComposerSettingsUpdatesRef.current[agentSessionId];
13081
13210
  queuedComposerSettingsUpdatesRef.current[agentSessionId] = {
@@ -13787,9 +13916,9 @@ function useAgentGUINodeController({
13787
13916
  const sessionTarget = resolveAgentGUIProviderTarget({
13788
13917
  agentTargetId: summaryAgentTargetId,
13789
13918
  defaultProviderTargetId,
13790
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
13791
13919
  provider: summary.provider,
13792
- providerTargets: normalizedProviderTargets
13920
+ providerTargets: normalizedProviderTargets,
13921
+ useStaticCatalog: shouldUseStaticProviderTargets
13793
13922
  });
13794
13923
  if (!sessionTarget || sessionTarget.provider !== summary.provider) {
13795
13924
  return;
@@ -13824,7 +13953,7 @@ function useAgentGUINodeController({
13824
13953
  normalizedProviderTargets,
13825
13954
  previewMode,
13826
13955
  providerTargetsLoading,
13827
- shouldFallbackToLocalProviderTargets
13956
+ shouldUseStaticProviderTargets
13828
13957
  ]);
13829
13958
  const visibleConversationsRef = useRef4(
13830
13959
  null
@@ -14129,10 +14258,6 @@ function useAgentGUINodeController({
14129
14258
  targetSafeNodeDefaultSettings
14130
14259
  )
14131
14260
  );
14132
- void onRememberComposerDefaultsRef.current?.({
14133
- provider: selectedComposerTargetData.provider,
14134
- defaults: composerDefaultsFromSettings(targetSafeNodeDefaultSettings)
14135
- });
14136
14261
  }, [
14137
14262
  activeConversationId,
14138
14263
  providerComposerOptions,
@@ -14148,7 +14273,8 @@ function useAgentGUINodeController({
14148
14273
  )
14149
14274
  });
14150
14275
  const draftSettings = activeConversationId ? sessionSettings ?? defaultConversationDraftSettings : homeComposerSettings;
14151
- const draftModel = normalizeOptionalText2(draftSettings.model);
14276
+ const liveConfigModel = activeConversationId !== null ? configOptionCurrentValue(activeSessionRuntimeContext, ["model"]) : null;
14277
+ const draftModel = liveConfigModel ?? normalizeOptionalText2(draftSettings.model);
14152
14278
  const draftReasoningEffort = normalizeOptionalText2(
14153
14279
  draftSettings.reasoningEffort
14154
14280
  );
@@ -14411,15 +14537,11 @@ function useAgentGUINodeController({
14411
14537
  const stableComposerSettings = useStableComposerSettingsVM(composerSettings);
14412
14538
  const updateConversationFilter = useCallback4(
14413
14539
  (filter) => {
14414
- if (!canUseConversationTargetFilter) {
14415
- setConversationFilter({ kind: "all" });
14416
- return;
14417
- }
14418
14540
  setConversationFilter(normalizeAgentGUIConversationFilter(filter));
14419
14541
  },
14420
- [canUseConversationTargetFilter]
14542
+ []
14421
14543
  );
14422
- const selectProvider = useCallback4(
14544
+ const selectHomeComposerAgentTarget = useCallback4(
14423
14545
  (input) => {
14424
14546
  if (previewMode) {
14425
14547
  return;
@@ -14427,17 +14549,14 @@ function useAgentGUINodeController({
14427
14549
  const nextProvider = input.provider;
14428
14550
  const nextTarget = resolveAgentGUIProviderTarget({
14429
14551
  defaultProviderTargetId,
14430
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
14431
14552
  provider: nextProvider,
14432
14553
  providerTargetId: input.providerTargetId,
14433
- providerTargets: normalizedProviderTargets
14554
+ providerTargets: normalizedProviderTargets,
14555
+ useStaticCatalog: shouldUseStaticProviderTargets
14434
14556
  });
14435
14557
  if (!nextTarget) {
14436
14558
  return;
14437
14559
  }
14438
- if (nextTarget.disabled === true) {
14439
- return;
14440
- }
14441
14560
  const nextTargetIsExplicit = normalizedExplicitProviderTargets.some(
14442
14561
  (target) => target.provider === nextTarget.provider && target.targetId === nextTarget.targetId && agentGUIProviderTargetRefsEqual(target.ref, nextTarget.ref)
14443
14562
  );
@@ -14481,7 +14600,9 @@ function useAgentGUINodeController({
14481
14600
  dataRef.current = nextData;
14482
14601
  return nextData;
14483
14602
  });
14484
- loadComposerOptionsForTarget(nextTargetData, { force: true });
14603
+ if (nextTarget.disabled !== true) {
14604
+ loadComposerOptionsForTarget(nextTargetData, { force: true });
14605
+ }
14485
14606
  },
14486
14607
  [
14487
14608
  activation,
@@ -14491,21 +14612,17 @@ function useAgentGUINodeController({
14491
14612
  normalizedProviderTargets,
14492
14613
  persistActiveConversation,
14493
14614
  previewMode,
14494
- shouldFallbackToLocalProviderTargets
14615
+ shouldUseStaticProviderTargets
14495
14616
  ]
14496
14617
  );
14497
14618
  const selectConversationFilterTarget = useCallback4(
14498
14619
  (input) => {
14499
- if (!canUseConversationTargetFilter) {
14500
- setConversationFilter({ kind: "all" });
14501
- return;
14502
- }
14503
14620
  const nextTarget = resolveAgentGUIProviderTarget({
14504
14621
  defaultProviderTargetId,
14505
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
14506
14622
  provider: input.provider,
14507
14623
  providerTargetId: input.providerTargetId,
14508
- providerTargets: normalizedProviderTargets
14624
+ providerTargets: normalizedProviderTargets,
14625
+ useStaticCatalog: shouldUseStaticProviderTargets
14509
14626
  });
14510
14627
  if (!nextTarget || nextTarget.disabled === true) {
14511
14628
  reportAgentGUIConversationFilterTargetUnresolved({
@@ -14518,29 +14635,32 @@ function useAgentGUINodeController({
14518
14635
  });
14519
14636
  return;
14520
14637
  }
14521
- if (activeConversationIdRef.current === null) {
14522
- setHomeComposerTargetOverride(nextTarget);
14523
- }
14524
14638
  const agentTargetId = nextTarget.agentTargetId?.trim() ?? "";
14525
14639
  const nextFilter = agentTargetId ? { kind: "agentTarget", agentTargetId } : { kind: "all" };
14526
14640
  setConversationFilter(nextFilter);
14641
+ if (activeConversationIdRef.current === null) {
14642
+ selectHomeComposerAgentTarget(input);
14643
+ }
14527
14644
  },
14528
14645
  [
14529
14646
  agentActivityRuntime,
14530
- canUseConversationTargetFilter,
14531
14647
  defaultProviderTargetId,
14532
14648
  normalizedProviderTargets,
14533
- shouldFallbackToLocalProviderTargets,
14649
+ selectHomeComposerAgentTarget,
14650
+ shouldUseStaticProviderTargets,
14534
14651
  workspaceId
14535
14652
  ]
14536
14653
  );
14537
14654
  const stableCreateConversation = useStableControllerEventCallback(createConversation);
14538
- const stableSelectProvider = useStableControllerEventCallback(selectProvider);
14655
+ const stableSelectHomeComposerAgentTarget = useStableControllerEventCallback(
14656
+ selectHomeComposerAgentTarget
14657
+ );
14539
14658
  const stableSelectConversationFilterTarget = useStableControllerEventCallback(
14540
14659
  selectConversationFilterTarget
14541
14660
  );
14542
14661
  const stableSelectConversation = useStableControllerEventCallback(selectConversation);
14543
14662
  const stableSubmitPrompt = useStableControllerEventCallback(submitPrompt);
14663
+ const stableGoalControl = useStableControllerEventCallback(goalControl);
14544
14664
  const stableSubmitGuidancePrompt = useStableControllerEventCallback(submitGuidancePrompt);
14545
14665
  const stableShowPromptImagesUnsupported = useStableControllerEventCallback(
14546
14666
  showPromptImagesUnsupported
@@ -14598,10 +14718,11 @@ function useAgentGUINodeController({
14598
14718
  () => ({
14599
14719
  updateConversationFilter: stableUpdateConversationFilter,
14600
14720
  selectConversationFilterTarget: stableSelectConversationFilterTarget,
14601
- selectProvider: stableSelectProvider,
14721
+ selectHomeComposerAgentTarget: stableSelectHomeComposerAgentTarget,
14602
14722
  createConversation: stableCreateConversation,
14603
14723
  selectConversation: stableSelectConversation,
14604
14724
  submitPrompt: stableSubmitPrompt,
14725
+ goalControl: stableGoalControl,
14605
14726
  submitGuidancePrompt: stableSubmitGuidancePrompt,
14606
14727
  loadOlderConversationMessages: stableLoadOlderConversationMessages,
14607
14728
  showPromptImagesUnsupported: stableShowPromptImagesUnsupported,
@@ -14646,13 +14767,14 @@ function useAgentGUINodeController({
14646
14767
  stableRetryOpenclawGateway,
14647
14768
  stableSelectConversation,
14648
14769
  stableSelectConversationFilterTarget,
14649
- stableSelectProvider,
14770
+ stableSelectHomeComposerAgentTarget,
14650
14771
  stableSendQueuedPromptNext,
14651
14772
  stableSubmitGuidancePrompt,
14652
14773
  stableShowPromptImagesUnsupported,
14653
14774
  stableSubmitApprovalOption,
14654
14775
  stableSubmitInteractivePrompt,
14655
14776
  stableSubmitPrompt,
14777
+ stableGoalControl,
14656
14778
  stableToggleConversationPinned,
14657
14779
  stableUpdateConversationFilter,
14658
14780
  stableUpdateComposerSettings,
@@ -14670,7 +14792,6 @@ function useAgentGUINodeController({
14670
14792
  selectedProviderTarget: effectiveSelectedProviderTarget,
14671
14793
  providerTargets: normalizedProviderTargets,
14672
14794
  providerTargetsLoading,
14673
- conversationScope,
14674
14795
  conversationFilter,
14675
14796
  conversations: visibleConversations,
14676
14797
  userProjects,
@@ -14691,6 +14812,7 @@ function useAgentGUINodeController({
14691
14812
  isRespondingApproval,
14692
14813
  promptImagesSupported,
14693
14814
  compactSupported,
14815
+ goalPauseSupported,
14694
14816
  usage,
14695
14817
  backgroundAgentCount,
14696
14818
  listError,
@@ -14735,7 +14857,6 @@ function useAgentGUINodeController({
14735
14857
  canSubmit,
14736
14858
  canQueueWhileBusy,
14737
14859
  conversation,
14738
- conversationScope,
14739
14860
  conversationFilter,
14740
14861
  conversationDetail,
14741
14862
  controllerActions,
@@ -14751,6 +14872,7 @@ function useAgentGUINodeController({
14751
14872
  openclawGateway,
14752
14873
  promptImagesSupported,
14753
14874
  compactSupported,
14875
+ goalPauseSupported,
14754
14876
  usage,
14755
14877
  backgroundAgentCount,
14756
14878
  isInterrupting,
@@ -14967,19 +15089,19 @@ import {
14967
15089
  Fragment as Fragment7,
14968
15090
  memo,
14969
15091
  useCallback as useCallback10,
14970
- useEffect as useEffect12,
15092
+ useEffect as useEffect13,
14971
15093
  useLayoutEffect as useLayoutEffect4,
14972
15094
  useMemo as useMemo10,
14973
15095
  useRef as useRef12,
14974
- useState as useState11
15096
+ useState as useState12
14975
15097
  } from "react";
14976
15098
  import { useSnapshot } from "valtio";
14977
15099
  import { proxy as proxy2 } from "valtio/vanilla";
14978
15100
  import {
14979
15101
  ChevronRight as ChevronRight2,
15102
+ ChevronsDown,
14980
15103
  ExternalLink,
14981
15104
  Info as Info2,
14982
- LayoutGrid,
14983
15105
  Wrench
14984
15106
  } from "lucide-react";
14985
15107
 
@@ -15051,6 +15173,10 @@ import {
15051
15173
  TooltipContent as TooltipContent3,
15052
15174
  TooltipProvider as TooltipProvider2,
15053
15175
  TooltipTrigger as TooltipTrigger3,
15176
+ Select as Select3,
15177
+ SelectContent as SelectContent3,
15178
+ SelectItem as SelectItem3,
15179
+ SelectTrigger as SelectTrigger3,
15054
15180
  NewWorkspaceLinedIcon as NewWorkspaceLinedIcon2,
15055
15181
  ConfirmationDialog,
15056
15182
  toastVariants,
@@ -15730,7 +15856,9 @@ var styles2 = {
15730
15856
  chromeActions: "agent-gui-chrome__actions",
15731
15857
  chromeMetaRow: "agent-gui-chrome__meta-row",
15732
15858
  chromeDangerGhostButton: "agent-gui-chrome__danger-ghost-button",
15733
- chromeGoalHint: "agent-gui-chrome__goal-hint"
15859
+ chromeGoalHint: "agent-gui-chrome__goal-hint",
15860
+ chromeGoalActions: "agent-gui-chrome__goal-actions",
15861
+ chromeGoalEditInput: "agent-gui-chrome__goal-edit-input"
15734
15862
  };
15735
15863
  var AgentGUIChrome_styles_default = styles2;
15736
15864
 
@@ -15931,8 +16059,15 @@ function AgentSessionChrome({
15931
16059
  }
15932
16060
 
15933
16061
  // agent-gui/agentGuiNode/AgentGoalBanner.tsx
15934
- import { Target } from "lucide-react";
16062
+ import { useEffect as useEffect6, useState as useState5 } from "react";
16063
+ import { CirclePause, CirclePlay, Pencil, Target, Trash2 } from "lucide-react";
15935
16064
  import { jsx as jsx20, jsxs as jsxs8 } from "react/jsx-runtime";
16065
+ var RESUMABLE_GOAL_STATUSES = /* @__PURE__ */ new Set([
16066
+ "paused",
16067
+ "blocked",
16068
+ "usagelimited",
16069
+ "budgetlimited"
16070
+ ]);
15936
16071
  var TERMINAL_GOAL_STATUSES = /* @__PURE__ */ new Set(["complete", "completed", "done"]);
15937
16072
  function normalizeGoalStatus(status) {
15938
16073
  return (status ?? "").trim().toLowerCase();
@@ -15943,49 +16078,98 @@ function isGoalBannerVisible(objective, status) {
15943
16078
  }
15944
16079
  return !TERMINAL_GOAL_STATUSES.has(normalizeGoalStatus(status));
15945
16080
  }
15946
- function goalStatusLabel(status, labels) {
16081
+ function goalStatusTitle(status, labels) {
15947
16082
  switch (normalizeGoalStatus(status)) {
15948
16083
  case "paused":
15949
- return labels.statusPaused;
16084
+ return labels.titlePaused;
15950
16085
  case "blocked":
15951
- return labels.statusBlocked;
16086
+ return labels.titleBlocked;
15952
16087
  case "usagelimited":
15953
- return labels.statusUsageLimited;
16088
+ return labels.titleUsageLimited;
15954
16089
  case "budgetlimited":
15955
- return labels.statusBudgetLimited;
16090
+ return labels.titleBudgetLimited;
15956
16091
  case "complete":
15957
16092
  case "completed":
15958
16093
  case "done":
15959
- return labels.statusComplete;
16094
+ return labels.titleComplete;
15960
16095
  default:
15961
- return labels.statusActive;
16096
+ return labels.titleActive;
16097
+ }
16098
+ }
16099
+ function formatGoalElapsed(totalSeconds) {
16100
+ const seconds = Math.max(0, Math.floor(totalSeconds));
16101
+ if (seconds < 60) {
16102
+ return `${seconds}s`;
15962
16103
  }
16104
+ const minutes = Math.floor(seconds / 60);
16105
+ if (minutes < 60) {
16106
+ const rest = seconds % 60;
16107
+ return rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`;
16108
+ }
16109
+ const hours = Math.floor(minutes / 60);
16110
+ const restMinutes = minutes % 60;
16111
+ return restMinutes > 0 ? `${hours}h ${restMinutes}m` : `${hours}h`;
15963
16112
  }
15964
16113
  function describeGoal(input) {
15965
- const trimmedObjective = input.objective.trim();
15966
- const detailParts = [goalStatusLabel(input.status, input.labels)];
16114
+ const detailParts = [input.objective.trim()];
16115
+ if (typeof input.elapsedSeconds === "number") {
16116
+ detailParts.push(formatGoalElapsed(input.elapsedSeconds));
16117
+ }
15967
16118
  if (typeof input.tokenBudget === "number" && input.tokenBudget > 0) {
15968
16119
  const used = typeof input.tokensUsed === "number" && input.tokensUsed >= 0 ? input.tokensUsed : 0;
15969
16120
  detailParts.push(input.labels.budgetUsage(used, input.tokenBudget));
15970
16121
  }
15971
- return `${trimmedObjective} \xB7 ${detailParts.join(" \xB7 ")}`;
16122
+ return detailParts.join(" \xB7 ");
15972
16123
  }
15973
16124
  function AgentGoalBanner({
15974
16125
  objective,
15975
16126
  status,
15976
16127
  tokenBudget,
15977
16128
  tokensUsed,
15978
- labels
16129
+ timeUsedSeconds,
16130
+ labels,
16131
+ onEditObjective,
16132
+ onPauseGoal,
16133
+ onResumeGoal,
16134
+ onClearGoal
15979
16135
  }) {
15980
16136
  "use memo";
16137
+ const [editDraft, setEditDraft] = useState5(null);
16138
+ const normalizedStatus = normalizeGoalStatus(status);
16139
+ const isActive = normalizedStatus === "" || normalizedStatus === "active";
16140
+ const serverSeconds = typeof timeUsedSeconds === "number" && timeUsedSeconds >= 0 ? Math.floor(timeUsedSeconds) : null;
16141
+ const [localElapsed, setLocalElapsed] = useState5(0);
16142
+ useEffect6(() => {
16143
+ setLocalElapsed(0);
16144
+ if (!isActive || serverSeconds === null) {
16145
+ return;
16146
+ }
16147
+ const startedAtMs = Date.now();
16148
+ const timer = window.setInterval(() => {
16149
+ setLocalElapsed(Math.floor((Date.now() - startedAtMs) / 1e3));
16150
+ }, 1e3);
16151
+ return () => window.clearInterval(timer);
16152
+ }, [isActive, serverSeconds]);
16153
+ const elapsedSeconds = serverSeconds === null ? null : serverSeconds + (isActive ? localElapsed : 0);
16154
+ const title = goalStatusTitle(status, labels);
15981
16155
  const description = describeGoal({
15982
16156
  objective,
15983
- status,
16157
+ elapsedSeconds,
15984
16158
  tokenBudget,
15985
16159
  tokensUsed,
15986
16160
  labels
15987
16161
  });
15988
- const fullMessage = `${labels.goalLabel} ${description}`;
16162
+ const fullMessage = `${title} ${description}`;
16163
+ const showPause = onPauseGoal !== void 0 && isActive;
16164
+ const showResume = onResumeGoal !== void 0 && RESUMABLE_GOAL_STATUSES.has(normalizedStatus);
16165
+ const hasActions = onEditObjective !== void 0 || showPause || showResume || onClearGoal !== void 0;
16166
+ const commitEdit = () => {
16167
+ const next = (editDraft ?? "").trim();
16168
+ setEditDraft(null);
16169
+ if (next !== "" && next !== objective.trim()) {
16170
+ onEditObjective?.(next);
16171
+ }
16172
+ };
15989
16173
  return /* @__PURE__ */ jsx20("div", { className: AgentGUIChrome_styles_default.sessionChrome, children: /* @__PURE__ */ jsx20(
15990
16174
  "section",
15991
16175
  {
@@ -15995,19 +16179,91 @@ function AgentGoalBanner({
15995
16179
  children: /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeMetaRow, children: [
15996
16180
  /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: [
15997
16181
  /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeIcon, children: /* @__PURE__ */ jsx20(Target, { "aria-hidden": true, className: "size-3.5" }) }),
15998
- /* @__PURE__ */ jsxs8(
16182
+ editDraft !== null ? /* @__PURE__ */ jsx20(
16183
+ "input",
16184
+ {
16185
+ className: AgentGUIChrome_styles_default.chromeGoalEditInput,
16186
+ value: editDraft,
16187
+ autoFocus: true,
16188
+ "aria-label": labels.editAction,
16189
+ "data-testid": "agent-gui-goal-banner-edit-input",
16190
+ onChange: (event) => setEditDraft(event.target.value),
16191
+ onKeyDown: (event) => {
16192
+ if (event.key === "Enter") {
16193
+ event.preventDefault();
16194
+ commitEdit();
16195
+ } else if (event.key === "Escape") {
16196
+ event.preventDefault();
16197
+ setEditDraft(null);
16198
+ }
16199
+ },
16200
+ onBlur: () => setEditDraft(null)
16201
+ }
16202
+ ) : /* @__PURE__ */ jsxs8(
15999
16203
  "p",
16000
16204
  {
16001
16205
  className: cn(AgentGUIChrome_styles_default.chromeMessage, AgentGUIChrome_styles_default.chromeNoticeMessage),
16002
16206
  title: fullMessage,
16003
16207
  children: [
16004
- /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeTitle, children: labels.goalLabel }),
16005
- /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeDescription, children: description })
16208
+ /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeTitle, children: title }),
16209
+ /* @__PURE__ */ jsx20(
16210
+ "span",
16211
+ {
16212
+ className: AgentGUIChrome_styles_default.chromeNoticeDescription,
16213
+ "data-testid": "agent-gui-goal-banner-description",
16214
+ children: description
16215
+ }
16216
+ )
16006
16217
  ]
16007
16218
  }
16008
16219
  )
16009
16220
  ] }),
16010
- /* @__PURE__ */ jsx20(
16221
+ hasActions ? /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeGoalActions, children: [
16222
+ onEditObjective !== void 0 && editDraft === null ? /* @__PURE__ */ jsx20(
16223
+ "button",
16224
+ {
16225
+ type: "button",
16226
+ onClick: () => setEditDraft(objective),
16227
+ title: labels.editAction,
16228
+ "aria-label": labels.editAction,
16229
+ "data-testid": "agent-gui-goal-banner-edit",
16230
+ children: /* @__PURE__ */ jsx20(Pencil, { "aria-hidden": true, className: "size-3.5" })
16231
+ }
16232
+ ) : null,
16233
+ showPause ? /* @__PURE__ */ jsx20(
16234
+ "button",
16235
+ {
16236
+ type: "button",
16237
+ onClick: onPauseGoal,
16238
+ title: labels.pauseAction,
16239
+ "aria-label": labels.pauseAction,
16240
+ "data-testid": "agent-gui-goal-banner-pause",
16241
+ children: /* @__PURE__ */ jsx20(CirclePause, { "aria-hidden": true, className: "size-3.5" })
16242
+ }
16243
+ ) : null,
16244
+ showResume ? /* @__PURE__ */ jsx20(
16245
+ "button",
16246
+ {
16247
+ type: "button",
16248
+ onClick: onResumeGoal,
16249
+ title: labels.resumeAction,
16250
+ "aria-label": labels.resumeAction,
16251
+ "data-testid": "agent-gui-goal-banner-resume",
16252
+ children: /* @__PURE__ */ jsx20(CirclePlay, { "aria-hidden": true, className: "size-3.5" })
16253
+ }
16254
+ ) : null,
16255
+ onClearGoal !== void 0 ? /* @__PURE__ */ jsx20(
16256
+ "button",
16257
+ {
16258
+ type: "button",
16259
+ onClick: onClearGoal,
16260
+ title: labels.clearAction,
16261
+ "aria-label": labels.clearAction,
16262
+ "data-testid": "agent-gui-goal-banner-clear",
16263
+ children: /* @__PURE__ */ jsx20(Trash2, { "aria-hidden": true, className: "size-3.5" })
16264
+ }
16265
+ ) : null
16266
+ ] }) : /* @__PURE__ */ jsx20(
16011
16267
  "span",
16012
16268
  {
16013
16269
  className: AgentGUIChrome_styles_default.chromeGoalHint,
@@ -16023,21 +16279,19 @@ function AgentGoalBanner({
16023
16279
  // agent-gui/agentGuiNode/AgentComposer.tsx
16024
16280
  import {
16025
16281
  useCallback as useCallback9,
16026
- useEffect as useEffect11,
16282
+ useEffect as useEffect12,
16027
16283
  useLayoutEffect as useLayoutEffect3,
16028
16284
  useMemo as useMemo9,
16029
16285
  useRef as useRef11,
16030
- useState as useState10
16286
+ useState as useState11
16031
16287
  } from "react";
16032
16288
  import { createPortal as createPortal3, flushSync } from "react-dom";
16033
16289
  import {
16034
- AddIcon,
16035
16290
  Button as Button3,
16036
16291
  Select as Select2,
16037
16292
  SelectContent as SelectContent2,
16038
16293
  SelectItem as SelectItem2,
16039
- SelectTrigger as SelectTrigger2,
16040
- SelectValue
16294
+ SelectTrigger as SelectTrigger2
16041
16295
  } from "@tutti-os/ui-system";
16042
16296
  import { ListChecks as ListChecks2, Target as Target3, X } from "lucide-react";
16043
16297
  import {
@@ -16481,7 +16735,7 @@ function filterUnavailableSlashCommands(commands, input) {
16481
16735
  }
16482
16736
 
16483
16737
  // agent-gui/agentGuiNode/AgentSlashCommandPalette.tsx
16484
- import { Fragment as Fragment3, useEffect as useEffect6, useRef as useRef6 } from "react";
16738
+ import { Fragment as Fragment3, useEffect as useEffect7, useRef as useRef6 } from "react";
16485
16739
  import {
16486
16740
  Globe,
16487
16741
  Info,
@@ -16525,7 +16779,7 @@ function AgentSlashCommandPalette({
16525
16779
  }) {
16526
16780
  "use memo";
16527
16781
  const highlightedOptionRef = useRef6(null);
16528
- useEffect6(() => {
16782
+ useEffect7(() => {
16529
16783
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
16530
16784
  }, [highlightedIndex]);
16531
16785
  if (entries.length === 0) {
@@ -16683,7 +16937,7 @@ function slashPaletteEntryIcon(entry) {
16683
16937
  import {
16684
16938
  useLayoutEffect,
16685
16939
  useRef as useRef7,
16686
- useState as useState5
16940
+ useState as useState6
16687
16941
  } from "react";
16688
16942
  import { ChevronRight } from "lucide-react";
16689
16943
 
@@ -16691,6 +16945,7 @@ import { ChevronRight } from "lucide-react";
16691
16945
  var styles3 = {
16692
16946
  bottomDock: "agent-gui-node__bottom-dock",
16693
16947
  bottomDockPrompt: "agent-gui-node__bottom-dock-prompt",
16948
+ bottomDockScrollToBottom: "agent-gui-node__bottom-dock-scroll-to-bottom",
16694
16949
  body: "agent-gui-node__body",
16695
16950
  composer: "agent-gui-node__composer",
16696
16951
  composerChip: "agent-gui-node__composer-chip",
@@ -16700,6 +16955,10 @@ var styles3 = {
16700
16955
  composerFooterRight: "agent-gui-node__composer-footer-right",
16701
16956
  composerHero: "agent-gui-node__composer-hero",
16702
16957
  composerFloatingPrompt: "agent-gui-node__composer-floating-prompt",
16958
+ composerHandoffIcon: "agent-gui-node__composer-handoff-icon",
16959
+ composerHandoffMenuContent: "agent-gui-node__composer-handoff-menu-content",
16960
+ composerHandoffStaticIcon: "agent-gui-node__composer-handoff-icon-static",
16961
+ composerHandoffTrigger: "agent-gui-node__composer-handoff-trigger",
16703
16962
  composerQueuedPromptFloating: "agent-gui-node__composer-floating-prompt--queued",
16704
16963
  composerInputGroup: "agent-gui-node__composer-input-group",
16705
16964
  composerInputGroupHero: "agent-gui-node__composer-input-group-hero",
@@ -16745,6 +17004,7 @@ var styles3 = {
16745
17004
  conversationItem: "agent-gui-node__conversation-item",
16746
17005
  conversationList: "agent-gui-node__conversation-list",
16747
17006
  conversationMeta: "agent-gui-node__conversation-meta",
17007
+ conversationProviderIcon: "agent-gui-node__conversation-provider-icon",
16748
17008
  conversationOpenWindowButton: "agent-gui-node__conversation-open-window-button",
16749
17009
  conversationPinButton: "agent-gui-node__conversation-pin-button",
16750
17010
  conversationSection: "agent-gui-node__conversation-section",
@@ -16766,6 +17026,7 @@ var styles3 = {
16766
17026
  conversationStatusGlyph: "agent-gui-node__conversation-status-glyph",
16767
17027
  conversationTime: "agent-gui-node__conversation-time",
16768
17028
  conversationTitle: "agent-gui-node__conversation-title",
17029
+ conversationTitleRow: "agent-gui-node__conversation-title-row",
16769
17030
  conversationUnreadLamp: "agent-gui-node__conversation-unread-lamp",
16770
17031
  detailHeader: "agent-gui-node__detail-header",
16771
17032
  detailHeaderPathInfo: "agent-gui-node__detail-header-path-info",
@@ -16781,7 +17042,11 @@ var styles3 = {
16781
17042
  emptyHero: "agent-gui-node__empty-hero",
16782
17043
  emptyHeroBody: "agent-gui-node__empty-hero-body",
16783
17044
  emptyHeroIconEffect: "agent-gui-node__empty-hero-icon-effect",
17045
+ emptyHeroIconRail: "agent-gui-node__empty-hero-icon-rail",
17046
+ emptyHeroIconRailItem: "agent-gui-node__empty-hero-icon-rail-item",
17047
+ emptyHeroIconRailScroller: "agent-gui-node__empty-hero-icon-rail-scroller",
16784
17048
  emptyHeroProvider: "agent-gui-node__empty-hero-provider",
17049
+ emptyHeroProviderSelect: "agent-gui-node__empty-hero-provider-select",
16785
17050
  emptyHeroTitle: "agent-gui-node__empty-hero-title",
16786
17051
  emptyProviderGate: "agent-gui-node__empty-provider-gate",
16787
17052
  emptyProviderGateAction: "agent-gui-node__empty-provider-gate-action",
@@ -16805,6 +17070,11 @@ var styles3 = {
16805
17070
  providerRailAvatar: "agent-gui-node__provider-rail-avatar",
16806
17071
  providerRailAvatarIcon: "agent-gui-node__provider-rail-avatar-icon",
16807
17072
  providerRailAvatarImage: "agent-gui-node__provider-rail-avatar-image",
17073
+ providerRailLaunchpadIcon: "agent-gui-node__provider-rail-launchpad-icon",
17074
+ emptyHeroLaunchpadIcon: "agent-gui-node__empty-hero-launchpad-icon",
17075
+ providerRailLaunchpadItem: "agent-gui-node__provider-rail-launchpad-item",
17076
+ providerRailPanel: "agent-gui-node__provider-rail-panel",
17077
+ providerRailSeparator: "agent-gui-node__provider-rail-separator",
16808
17078
  providerRailTile: "agent-gui-node__provider-rail-tile",
16809
17079
  providerRailTileLabel: "agent-gui-node__provider-rail-tile-label",
16810
17080
  rail: "agent-gui-node__rail",
@@ -16860,12 +17130,12 @@ function AgentQueuedPromptPanel({
16860
17130
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS
16861
17131
  }) {
16862
17132
  "use memo";
16863
- const [isExpanded, setIsExpanded] = useState5(false);
17133
+ const [isExpanded, setIsExpanded] = useState6(false);
16864
17134
  const singlePromptTextRef = useRef7(null);
16865
17135
  const queuedPromptListRef = useRef7(null);
16866
17136
  const pointerHandledEditPromptIdRef = useRef7(null);
16867
- const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState5(false);
16868
- const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState5(280);
17137
+ const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState6(false);
17138
+ const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState6(280);
16869
17139
  const singlePromptHasImages = queuedPrompts.length === 1 && queuedPromptImages(queuedPrompts[0]).length > 0;
16870
17140
  const canExpand = queuedPrompts.length > 1 || singlePromptHasImages || isSinglePromptOverflowing;
16871
17141
  const panelStyle = {
@@ -17104,9 +17374,9 @@ function AgentQueuedPromptPanel({
17104
17374
  // agent-gui/agentGuiNode/AgentComposerSettingsMenus.tsx
17105
17375
  import {
17106
17376
  cloneElement,
17107
- useEffect as useEffect7,
17377
+ useEffect as useEffect8,
17108
17378
  useMemo as useMemo5,
17109
- useState as useState6
17379
+ useState as useState7
17110
17380
  } from "react";
17111
17381
  import { ChevronDown, ZapIcon as ZapIcon2 } from "lucide-react";
17112
17382
  import {
@@ -17579,7 +17849,7 @@ function AgentPermissionModeDropdown({
17579
17849
  onSettingsChange
17580
17850
  }) {
17581
17851
  "use memo";
17582
- const [isSelectOpen, setIsSelectOpen] = useState6(false);
17852
+ const [isSelectOpen, setIsSelectOpen] = useState7(false);
17583
17853
  const isLoading = composerSettings.isSettingsLoading || composerSettings.isModelOptionsLoading === true;
17584
17854
  const availableOptions = composerSettings.availablePermissionModes ?? [];
17585
17855
  const selectedValue = composerSettings.selectedPermissionModeValue ?? composerSettings.draftSettings.permissionModeId;
@@ -17718,7 +17988,7 @@ function AgentProjectMissingStatusProbe({
17718
17988
  "use memo";
17719
17989
  const agentHostApi = useAgentHostApi();
17720
17990
  const selectedPath = composerSettings.selectedProjectPath?.trim() ?? "";
17721
- useEffect7(() => {
17991
+ useEffect8(() => {
17722
17992
  let canceled = false;
17723
17993
  const userProjects = agentHostApi.userProjects;
17724
17994
  if (!userProjects || !composerSettings.projectLocked || !selectedPath) {
@@ -17809,7 +18079,7 @@ function AgentModelReasoningDropdown({
17809
18079
  onSettingsChange
17810
18080
  }) {
17811
18081
  "use memo";
17812
- const [menuOpen, setMenuOpen] = useState6(false);
18082
+ const [menuOpen, setMenuOpen] = useState7(false);
17813
18083
  const menu = buildComposerModelMenuModel(composerSettings, labels);
17814
18084
  const menuDisabled = disabled || menu.disabled;
17815
18085
  const isModelLoading = composerSettings.isModelOptionsLoading || composerSettings.isSettingsLoading;
@@ -18064,7 +18334,7 @@ function ComposerModelOptionTooltip({
18064
18334
  "data-agent-model-option-tooltip": "true",
18065
18335
  children: [
18066
18336
  /* @__PURE__ */ jsx23("span", { className: "block text-[15px] font-semibold leading-[1.2]", children: option.tooltip.title }),
18067
- option.tooltip.description ? /* @__PURE__ */ jsx23("span", { className: "mt-1.5 block text-[13px] leading-[1.35]", children: option.tooltip.description }) : null,
18337
+ option.tooltip.description ? /* @__PURE__ */ jsx23("span", { className: "mt-1.5 block text-[13px] leading-[1.35] text-[var(--text-tertiary)]", children: option.tooltip.description }) : null,
18068
18338
  option.tooltip.contextWindow ? /* @__PURE__ */ jsx23("span", { className: "mt-4 block", children: option.tooltip.contextWindow }) : null,
18069
18339
  option.tooltip.version ? /* @__PURE__ */ jsx23("span", { className: "mt-4 block italic", children: option.tooltip.version }) : null
18070
18340
  ]
@@ -18077,11 +18347,11 @@ function ComposerModelOptionTooltip({
18077
18347
  import {
18078
18348
  forwardRef as forwardRef3,
18079
18349
  useCallback as useCallback6,
18080
- useEffect as useEffect8,
18350
+ useEffect as useEffect9,
18081
18351
  useImperativeHandle as useImperativeHandle2,
18082
18352
  useMemo as useMemo6,
18083
18353
  useRef as useRef8,
18084
- useState as useState7
18354
+ useState as useState8
18085
18355
  } from "react";
18086
18356
  import { createPortal } from "react-dom";
18087
18357
  import { Extension } from "@tiptap/core";
@@ -18677,7 +18947,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
18677
18947
  const availableCapabilitiesRef = useRef8(availableCapabilities);
18678
18948
  const suppressPastedAtSuggestionRef = useRef8(false);
18679
18949
  const scrollFrameRef = useRef8(null);
18680
- const [contextMenu, setContextMenu] = useState7(null);
18950
+ const [contextMenu, setContextMenu] = useState8(null);
18681
18951
  const closeContextMenu = useCallback6(() => {
18682
18952
  setContextMenu(null);
18683
18953
  }, []);
@@ -19150,10 +19420,10 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19150
19420
  }
19151
19421
  onSubmitRef.current();
19152
19422
  };
19153
- useEffect8(() => {
19423
+ useEffect9(() => {
19154
19424
  editorRef.current = editor;
19155
19425
  }, [editor]);
19156
- useEffect8(
19426
+ useEffect9(
19157
19427
  () => () => {
19158
19428
  if (scrollFrameRef.current !== null && typeof window.cancelAnimationFrame === "function") {
19159
19429
  window.cancelAnimationFrame(scrollFrameRef.current);
@@ -19161,7 +19431,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19161
19431
  },
19162
19432
  []
19163
19433
  );
19164
- useEffect8(() => {
19434
+ useEffect9(() => {
19165
19435
  if (!contextMenu) {
19166
19436
  return;
19167
19437
  }
@@ -19267,7 +19537,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19267
19537
  }),
19268
19538
  []
19269
19539
  );
19270
- useEffect8(() => {
19540
+ useEffect9(() => {
19271
19541
  if (!editor) {
19272
19542
  return;
19273
19543
  }
@@ -19278,7 +19548,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19278
19548
  editor.state.tr.setMeta("agentRichTextPlaceholder", placeholder)
19279
19549
  );
19280
19550
  }, [disabled, editor, placeholder]);
19281
- useEffect8(() => {
19551
+ useEffect9(() => {
19282
19552
  if (!editor || editor.isDestroyed) {
19283
19553
  return;
19284
19554
  }
@@ -19520,7 +19790,7 @@ function AgentSlashStatusPanel({
19520
19790
  }
19521
19791
 
19522
19792
  // agent-gui/agentGuiNode/AgentReviewPickerPanel.tsx
19523
- import { useCallback as useCallback7, useEffect as useEffect9, useMemo as useMemo7, useRef as useRef9, useState as useState8 } from "react";
19793
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo7, useRef as useRef9, useState as useState9 } from "react";
19524
19794
  import { menuItemClassName } from "@tutti-os/ui-system";
19525
19795
 
19526
19796
  // agent-gui/agentGuiNode/AgentReviewBranchController.ts
@@ -19635,21 +19905,21 @@ function AgentReviewPickerPanel({
19635
19905
  onSubmitReview,
19636
19906
  onClose
19637
19907
  }) {
19638
- const [stage, setStage] = useState8("root");
19639
- const [query, setQuery] = useState8("");
19640
- const [highlightedIndex, setHighlightedIndex] = useState8(0);
19908
+ const [stage, setStage] = useState9("root");
19909
+ const [query, setQuery] = useState9("");
19910
+ const [highlightedIndex, setHighlightedIndex] = useState9(0);
19641
19911
  const searchInputRef = useRef9(null);
19642
19912
  const highlightedOptionRef = useRef9(null);
19643
19913
  const reviewBranchControllerRef = useRef9(
19644
19914
  null
19645
19915
  );
19646
- const [branchState, setBranchState] = useState8({
19916
+ const [branchState, setBranchState] = useState9({
19647
19917
  status: "idle",
19648
19918
  branches: [],
19649
19919
  currentBranch: null,
19650
19920
  error: null
19651
19921
  });
19652
- useEffect9(() => {
19922
+ useEffect10(() => {
19653
19923
  const controller = new AgentReviewBranchController();
19654
19924
  reviewBranchControllerRef.current = controller;
19655
19925
  const unsubscribe = controller.subscribe(setBranchState);
@@ -19659,7 +19929,7 @@ function AgentReviewPickerPanel({
19659
19929
  reviewBranchControllerRef.current = null;
19660
19930
  };
19661
19931
  }, []);
19662
- useEffect9(() => {
19932
+ useEffect10(() => {
19663
19933
  const controller = reviewBranchControllerRef.current;
19664
19934
  if (!controller) {
19665
19935
  return;
@@ -19669,7 +19939,7 @@ function AgentReviewPickerPanel({
19669
19939
  controller.ensureLoaded();
19670
19940
  }
19671
19941
  }, [onRequestGitBranches, stage]);
19672
- useEffect9(() => {
19942
+ useEffect10(() => {
19673
19943
  searchInputRef.current?.focus();
19674
19944
  }, [stage]);
19675
19945
  const submit = useCallback7(
@@ -19759,7 +20029,7 @@ function AgentReviewPickerPanel({
19759
20029
  goToStage
19760
20030
  ]);
19761
20031
  const safeHighlightedIndex = entries.length === 0 ? -1 : Math.min(highlightedIndex, entries.length - 1);
19762
- useEffect9(() => {
20032
+ useEffect10(() => {
19763
20033
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
19764
20034
  }, [safeHighlightedIndex]);
19765
20035
  const searchPlaceholder = stage === "base" ? labels.branchPlaceholder : stage === "commit" ? labels.commitPlaceholder : stage === "custom" ? labels.customPlaceholder : labels.searchPlaceholder;
@@ -19882,11 +20152,11 @@ function AgentReviewPickerPanel({
19882
20152
  import {
19883
20153
  forwardRef as forwardRef4,
19884
20154
  useCallback as useCallback8,
19885
- useEffect as useEffect10,
20155
+ useEffect as useEffect11,
19886
20156
  useLayoutEffect as useLayoutEffect2,
19887
20157
  useMemo as useMemo8,
19888
20158
  useRef as useRef10,
19889
- useState as useState9
20159
+ useState as useState10
19890
20160
  } from "react";
19891
20161
  import { createPortal as createPortal2 } from "react-dom";
19892
20162
  import { jsx as jsx27 } from "react/jsx-runtime";
@@ -19963,7 +20233,7 @@ function useComposerAnchoredMenuFrame({
19963
20233
  maxHeight,
19964
20234
  open
19965
20235
  }) {
19966
- const [frame, setFrame] = useState9(null);
20236
+ const [frame, setFrame] = useState10(null);
19967
20237
  const syncFrame = useCallback8(() => {
19968
20238
  const anchor = anchorRef.current;
19969
20239
  if (!anchor || typeof window === "undefined") {
@@ -20035,7 +20305,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
20035
20305
  },
20036
20306
  [forwardedRef, surfaceRef]
20037
20307
  );
20038
- useEffect10(() => {
20308
+ useEffect11(() => {
20039
20309
  if (!open || !onDismiss) {
20040
20310
  return;
20041
20311
  }
@@ -20125,8 +20395,14 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
20125
20395
  );
20126
20396
  });
20127
20397
 
20128
- // app/renderer/assets/icons/@-lined-14px.svg
20129
- var lined_14px_default = "./@-lined-14px-64O2KKB4.svg";
20398
+ // app/renderer/assets/icons/add-lined-bold.svg
20399
+ var add_lined_bold_default = "./add-lined-bold-5QPUDZCU.svg";
20400
+
20401
+ // app/renderer/assets/icons/@-bold-lined.svg
20402
+ var bold_lined_default = "./@-bold-lined-BLLFKBFI.svg";
20403
+
20404
+ // app/renderer/assets/icons/handoff-lined.svg
20405
+ var handoff_lined_default = "./handoff-lined-4WQUBVG3.svg";
20130
20406
 
20131
20407
  // agent-gui/agentGuiNode/AgentComposer.tsx
20132
20408
  import { jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
@@ -20168,7 +20444,7 @@ function AgentUsageChip({
20168
20444
  compactDisabled
20169
20445
  }) {
20170
20446
  "use memo";
20171
- const [usagePopoverOpen, setUsagePopoverOpen] = useState10(false);
20447
+ const [usagePopoverOpen, setUsagePopoverOpen] = useState11(false);
20172
20448
  const usagePopoverHoverTimerRef = useRef11(null);
20173
20449
  const usagePopoverContentRef = useRef11(null);
20174
20450
  const clampedPercent = Math.max(0, Math.min(100, percentUsed));
@@ -20241,7 +20517,7 @@ function AgentUsageChip({
20241
20517
  closeUsagePopover
20242
20518
  ]
20243
20519
  );
20244
- useEffect11(
20520
+ useEffect12(
20245
20521
  () => () => {
20246
20522
  clearUsagePopoverHoverTimer();
20247
20523
  clearUsagePopoverCloseTimer();
@@ -20364,6 +20640,12 @@ var MENTION_PALETTE_DISMISS_INTERACTION_SELECTOR = [
20364
20640
  ".workbench-window__resize-handle",
20365
20641
  "#agent-gui-conversation-rail-resize"
20366
20642
  ].join(",");
20643
+ function resolveComposerProviderIconUrl(provider) {
20644
+ return MANAGED_AGENT_ICON_URLS[normalizeManagedAgentProvider(provider)] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20645
+ }
20646
+ function resolveComposerProviderTargetIconUrl(target) {
20647
+ return target.iconUrl ?? resolveComposerProviderIconUrl(target.provider);
20648
+ }
20367
20649
  function resolveMentionPalettePortalTarget(anchor) {
20368
20650
  return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? anchor.closest(
20369
20651
  "[data-workbench-window-id], [data-workspace-node-window-root='true']"
@@ -20393,21 +20675,53 @@ function hasInlineOverflow(element) {
20393
20675
  }
20394
20676
  return element.scrollWidth > element.clientWidth + 1;
20395
20677
  }
20396
- function resolveComposerProviderIconUrl(provider) {
20397
- const normalizedProvider = normalizeManagedAgentProvider(provider);
20398
- return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20678
+ function AgentComposerMaskIcon({
20679
+ iconUrl,
20680
+ marker
20681
+ }) {
20682
+ return /* @__PURE__ */ jsx28(
20683
+ "span",
20684
+ {
20685
+ "aria-hidden": true,
20686
+ className: "inline-block size-3.5 bg-[var(--text-secondary)] transition-colors group-hover:bg-[var(--text-primary)] group-focus-visible:bg-[var(--text-primary)]",
20687
+ "data-agent-reference-add-icon": marker === "reference-add" ? "true" : void 0,
20688
+ style: {
20689
+ WebkitMaskImage: `url("${iconUrl}")`,
20690
+ WebkitMaskPosition: "center",
20691
+ WebkitMaskRepeat: "no-repeat",
20692
+ WebkitMaskSize: "contain",
20693
+ maskImage: `url("${iconUrl}")`,
20694
+ maskPosition: "center",
20695
+ maskRepeat: "no-repeat",
20696
+ maskSize: "contain"
20697
+ }
20698
+ }
20699
+ );
20399
20700
  }
20400
- function resolveComposerProviderTargetIconUrl(target) {
20401
- return target.iconUrl?.trim() || resolveComposerProviderIconUrl(target.provider);
20701
+ var HANDOFF_SELECT_IDLE_VALUE = "__agent-handoff-idle__";
20702
+ function AgentComposerHandoffIcon() {
20703
+ return /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.composerHandoffIcon, children: /* @__PURE__ */ jsx28(
20704
+ "span",
20705
+ {
20706
+ className: AgentGUINode_styles_default.composerHandoffStaticIcon,
20707
+ style: {
20708
+ WebkitMaskImage: `url("${handoff_lined_default}")`,
20709
+ WebkitMaskPosition: "center",
20710
+ WebkitMaskRepeat: "no-repeat",
20711
+ WebkitMaskSize: "contain",
20712
+ maskImage: `url("${handoff_lined_default}")`,
20713
+ maskPosition: "center",
20714
+ maskRepeat: "no-repeat",
20715
+ maskSize: "contain"
20716
+ }
20717
+ }
20718
+ ) });
20402
20719
  }
20403
20720
  function AgentComposer({
20404
20721
  workspaceId,
20405
20722
  workspacePath,
20406
20723
  currentUserId,
20407
20724
  provider,
20408
- selectedProviderTarget = null,
20409
- providerTargets = [],
20410
- providerSelectReadonly = false,
20411
20725
  slashStatus = null,
20412
20726
  usage = null,
20413
20727
  draftContent,
@@ -20417,12 +20731,18 @@ function AgentComposer({
20417
20731
  availableSkills = EMPTY_PROVIDER_SKILLS,
20418
20732
  disabled,
20419
20733
  disabledReason,
20734
+ hasActiveConversation = true,
20420
20735
  submitDisabled,
20421
20736
  placeholder,
20422
20737
  composerSettings,
20423
20738
  queuedPrompts,
20424
20739
  drainingQueuedPromptId,
20425
20740
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS2,
20741
+ selectedProviderTarget = null,
20742
+ providerTargets = [],
20743
+ providerSelectReadonly = false,
20744
+ onProviderSelect,
20745
+ onHandoffConversation,
20426
20746
  canQueueWhileBusy,
20427
20747
  showStopButton,
20428
20748
  activePrompt,
@@ -20439,13 +20759,15 @@ function AgentComposer({
20439
20759
  promptImagesSupported = true,
20440
20760
  composerFocusRequestSequence = null,
20441
20761
  layoutMode = "dock",
20762
+ providerSelectLabel = "",
20763
+ handoffLabel,
20764
+ handoffMenuLabel,
20442
20765
  labels,
20443
20766
  workspaceUserProjectI18n,
20444
20767
  onDraftContentChange,
20445
20768
  onProjectPathChange = () => {
20446
20769
  },
20447
20770
  onSettingsChange,
20448
- onProviderSelect,
20449
20771
  capabilityMenuState,
20450
20772
  onSubmit,
20451
20773
  onSubmitGuidance,
@@ -20478,28 +20800,28 @@ function AgentComposer({
20478
20800
  const promptFilesSupported = Boolean(
20479
20801
  resolveDroppedFileReferences && promptFileUploadSupported
20480
20802
  );
20481
- const [isPaletteOpen, setIsPaletteOpen] = useState10(true);
20482
- const [isReviewPickerOpen, setIsReviewPickerOpen] = useState10(false);
20483
- const [highlightedIndex, setHighlightedIndex] = useState10(0);
20484
- const [mentionHighlightedKey, setMentionHighlightedKey] = useState10(null);
20485
- const [shouldCenterMentionHighlight, setShouldCenterMentionHighlight] = useState10(false);
20803
+ const [isPaletteOpen, setIsPaletteOpen] = useState11(true);
20804
+ const [isReviewPickerOpen, setIsReviewPickerOpen] = useState11(false);
20805
+ const [highlightedIndex, setHighlightedIndex] = useState11(0);
20806
+ const [mentionHighlightedKey, setMentionHighlightedKey] = useState11(null);
20807
+ const [shouldCenterMentionHighlight, setShouldCenterMentionHighlight] = useState11(false);
20486
20808
  const [
20487
20809
  shouldResetMentionHighlightToFilter,
20488
20810
  setShouldResetMentionHighlightToFilter
20489
- ] = useState10(false);
20490
- const [paletteDraftPrompt, setPaletteDraftPrompt] = useState10(
20811
+ ] = useState11(false);
20812
+ const [paletteDraftPrompt, setPaletteDraftPrompt] = useState11(
20491
20813
  goalDraftObjective ?? draftPrompt
20492
20814
  );
20493
- const [fileMentionSuggestion, setFileMentionSuggestion] = useState10(null);
20494
- const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState10(false);
20495
- const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState10(false);
20815
+ const [fileMentionSuggestion, setFileMentionSuggestion] = useState11(null);
20816
+ const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState11(false);
20817
+ const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState11(false);
20496
20818
  const slashStatusAgentSessionId = slashStatus?.agentSessionId ?? null;
20497
20819
  const previousSlashStatusAgentSessionIdRef = useRef11(
20498
20820
  slashStatusAgentSessionId
20499
20821
  );
20500
20822
  const selectedProjectPath = composerSettings.selectedProjectPath?.trim() ?? "";
20501
20823
  const previousSelectedProjectPathRef = useRef11(selectedProjectPath);
20502
- const [mentionSearchState, setMentionSearchState] = useState10({
20824
+ const [mentionSearchState, setMentionSearchState] = useState11({
20503
20825
  status: "idle",
20504
20826
  query: "",
20505
20827
  mode: "browse",
@@ -20523,15 +20845,15 @@ function AgentComposer({
20523
20845
  const wasActiveRef = useRef11(isActive);
20524
20846
  const lastComposerFocusRequestRef = useRef11(null);
20525
20847
  const autoMentionHighlightedKeyRef = useRef11(null);
20526
- const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState10(false);
20527
- const [dockComposerInputHeight, setDockComposerInputHeight] = useState10(
20848
+ const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState11(false);
20849
+ const [dockComposerInputHeight, setDockComposerInputHeight] = useState11(
20528
20850
  DOCK_COMPOSER_INPUT_MIN_HEIGHT
20529
20851
  );
20530
- const [dockComposerInputMaxHeight, setDockComposerInputMaxHeight] = useState10(
20852
+ const [dockComposerInputMaxHeight, setDockComposerInputMaxHeight] = useState11(
20531
20853
  DOCK_COMPOSER_INPUT_MAX_HEIGHT
20532
20854
  );
20533
- const [dockComposerAttachmentHeight, setDockComposerAttachmentHeight] = useState10(0);
20534
- const [dockComposerTextHeight, setDockComposerTextHeight] = useState10(
20855
+ const [dockComposerAttachmentHeight, setDockComposerAttachmentHeight] = useState11(0);
20856
+ const [dockComposerTextHeight, setDockComposerTextHeight] = useState11(
20535
20857
  DOCK_COMPOSER_INPUT_MIN_HEIGHT
20536
20858
  );
20537
20859
  const slashQuery = isGoalModeActive ? null : getPromptStartSlashCommandQuery(paletteDraftPrompt);
@@ -20691,11 +21013,11 @@ function AgentComposer({
20691
21013
  highlightedIndex,
20692
21014
  slashPaletteEntries.length
20693
21015
  );
20694
- const [mentionPaletteFrame, setMentionPaletteFrame] = useState10(null);
20695
- useEffect11(() => {
21016
+ const [mentionPaletteFrame, setMentionPaletteFrame] = useState11(null);
21017
+ useEffect12(() => {
20696
21018
  setHighlightedIndex(0);
20697
21019
  }, [skillQueryMatch?.prefix, skillQueryMatch?.query, slashQuery]);
20698
- useEffect11(() => {
21020
+ useEffect12(() => {
20699
21021
  const preferredKey = shouldResetMentionHighlightToFilter && mentionSearchState.mode === "browse" ? `category:${mentionSearchState.filter}` : null;
20700
21022
  if (shouldResetMentionHighlightToFilter) {
20701
21023
  const nextKey = repairMentionPaletteHighlight({
@@ -20727,7 +21049,7 @@ function AgentComposer({
20727
21049
  mentionSearchState,
20728
21050
  shouldResetMentionHighlightToFilter
20729
21051
  ]);
20730
- useEffect11(() => {
21052
+ useEffect12(() => {
20731
21053
  const controller = new AgentMentionSearchController({
20732
21054
  contextMentionProviders
20733
21055
  });
@@ -20739,7 +21061,7 @@ function AgentComposer({
20739
21061
  mentionControllerRef.current = null;
20740
21062
  };
20741
21063
  }, [contextMentionProviders]);
20742
- useEffect11(() => {
21064
+ useEffect12(() => {
20743
21065
  const isExternalDraftReplacement = draftPromptRef.current !== draftPrompt;
20744
21066
  draftPromptRef.current = draftPrompt;
20745
21067
  setPaletteDraftPrompt(goalDraftObjective ?? draftPrompt);
@@ -20751,13 +21073,13 @@ function AgentComposer({
20751
21073
  });
20752
21074
  }
20753
21075
  }, [draftPrompt, goalDraftObjective]);
20754
- useEffect11(() => {
21076
+ useEffect12(() => {
20755
21077
  draftImagesRef.current = draftImages;
20756
21078
  }, [draftImages]);
20757
- useEffect11(() => {
21079
+ useEffect12(() => {
20758
21080
  draftFilesRef.current = draftFiles;
20759
21081
  }, [draftFiles]);
20760
- useEffect11(() => {
21082
+ useEffect12(() => {
20761
21083
  if (previousSlashStatusAgentSessionIdRef.current === slashStatusAgentSessionId) {
20762
21084
  return;
20763
21085
  }
@@ -21013,11 +21335,13 @@ function AgentComposer({
21013
21335
  } else {
21014
21336
  onSubmit(submitContent);
21015
21337
  }
21016
- draftPromptRef.current = "";
21017
- draftImagesRef.current = [];
21018
- draftFilesRef.current = [];
21019
- setPaletteDraftPrompt("");
21020
- onDraftContentChange(emptyAgentComposerDraft());
21338
+ if (hasActiveConversation) {
21339
+ draftPromptRef.current = "";
21340
+ draftImagesRef.current = [];
21341
+ draftFilesRef.current = [];
21342
+ setPaletteDraftPrompt("");
21343
+ onDraftContentChange(emptyAgentComposerDraft());
21344
+ }
21021
21345
  }
21022
21346
  );
21023
21347
  const submit = useCallback9(
@@ -21201,7 +21525,10 @@ function AgentComposer({
21201
21525
  return makeAtPanelKeyDown({
21202
21526
  close: closeFileMentionPalette,
21203
21527
  commitSelection: () => {
21204
- createFileMentionPaletteAdapter().commitHighlighted();
21528
+ const result = createFileMentionPaletteAdapter().commitHighlighted();
21529
+ if (result.type === "none") {
21530
+ closeFileMentionPalette();
21531
+ }
21205
21532
  },
21206
21533
  cycleFilter: cycleFileMentionFilter,
21207
21534
  moveSelection: moveFileMentionSelection,
@@ -21242,7 +21569,7 @@ function AgentComposer({
21242
21569
  const handlePaletteKeyDown = useStableEventCallback(
21243
21570
  (event) => handleFileMentionKeyDown(event) || handleSlashPaletteKeyDown(event) || handleSlashCommandMenuKeyDown(event) || handlePlanModeToggleKeyDown(event)
21244
21571
  );
21245
- useEffect11(() => {
21572
+ useEffect12(() => {
21246
21573
  if (!showPalette || workspaceReferencePickerOpen) {
21247
21574
  return;
21248
21575
  }
@@ -21308,12 +21635,12 @@ function AgentComposer({
21308
21635
  },
21309
21636
  [onLinkAction, workspacePath]
21310
21637
  );
21311
- useEffect11(() => {
21638
+ useEffect12(() => {
21312
21639
  if (!showFileMentionPalette && shouldCenterMentionHighlight) {
21313
21640
  setShouldCenterMentionHighlight(false);
21314
21641
  }
21315
21642
  }, [shouldCenterMentionHighlight, showFileMentionPalette]);
21316
- useEffect11(() => {
21643
+ useEffect12(() => {
21317
21644
  if (!showFileMentionPalette) {
21318
21645
  return;
21319
21646
  }
@@ -21559,17 +21886,6 @@ function AgentComposer({
21559
21886
  }
21560
21887
  await applyReferencePickResult(await onRequestWorkspaceReferences());
21561
21888
  }, [applyReferencePickResult, onRequestWorkspaceReferences]);
21562
- const providerSwitchTargets = useMemo9(
21563
- () => providerTargets.filter((target) => target.disabled !== true),
21564
- [providerTargets]
21565
- );
21566
- const showProviderSelect = providerSwitchTargets.length > 1;
21567
- const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
21568
- const selectedProviderSwitchTarget = providerSwitchTargets.find(
21569
- (target) => target.targetId === selectedProviderTargetId
21570
- ) ?? selectedProviderTarget ?? providerSwitchTargets.find((target) => target.provider === provider) ?? null;
21571
- const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? provider;
21572
- const providerSelectDisabled = previewMode || providerSelectReadonly || !onProviderSelect;
21573
21889
  const applyDroppedFileReferences = useCallback9(
21574
21890
  async (files) => {
21575
21891
  if (!promptFilesSupported || !resolveDroppedFileReferences || files.length === 0) {
@@ -21685,11 +22001,40 @@ function AgentComposer({
21685
22001
  const mentionPaletteHeightPx = mentionPaletteFrame?.height ?? MENTION_PALETTE_MIN_HEIGHT_PX;
21686
22002
  const isHeroLayout = layoutMode === "hero";
21687
22003
  const composerClassName = isHeroLayout ? AgentGUINode_styles_default.composerHero : AgentGUINode_styles_default.composer;
21688
- const inputShellClassName = cn(
21689
- AgentGUINode_styles_default.composerInputShell,
21690
- isHeroLayout && AgentGUINode_styles_default.composerInputShellHero
21691
- );
22004
+ const providerSwitchTargets = useMemo9(
22005
+ () => providerTargets.filter(Boolean),
22006
+ [providerTargets]
22007
+ );
22008
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
22009
+ const selectedProviderSwitchTarget = providerSwitchTargets.find(
22010
+ (target) => target.targetId === selectedProviderTargetId
22011
+ ) ?? providerSwitchTargets.find((target) => target.provider === provider) ?? selectedProviderTarget;
22012
+ const providerMenuTargets = selectedProviderSwitchTarget && !providerSwitchTargets.some(
22013
+ (target) => target.targetId === selectedProviderSwitchTarget.targetId
22014
+ ) ? [selectedProviderSwitchTarget, ...providerSwitchTargets] : providerSwitchTargets;
22015
+ const handoffMenuTargets = selectedProviderSwitchTarget ? providerMenuTargets.filter((target) => {
22016
+ if (target.disabled === true) {
22017
+ return false;
22018
+ }
22019
+ if (target.targetId === selectedProviderSwitchTarget.targetId) {
22020
+ return false;
22021
+ }
22022
+ const selectedAgentTargetId = selectedProviderSwitchTarget.agentTargetId ?? selectedProviderSwitchTarget.targetId;
22023
+ const targetAgentTargetId = target.agentTargetId ?? target.targetId;
22024
+ return targetAgentTargetId !== selectedAgentTargetId;
22025
+ }) : providerMenuTargets;
22026
+ const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? selectedProviderTarget?.label ?? provider;
22027
+ const effectiveHandoffLabel = handoffLabel || labels.handoffConversation;
22028
+ const effectiveHandoffMenuLabel = handoffMenuLabel || labels.handoffConversationMenu;
22029
+ const inputShellClassName = cn(
22030
+ AgentGUINode_styles_default.composerInputShell,
22031
+ isHeroLayout && AgentGUINode_styles_default.composerInputShellHero
22032
+ );
21692
22033
  const inputDisabled = isSelectedProjectMissing || disabled && !canQueueWhileBusy;
22034
+ const providerSelectDisabled = providerSelectReadonly || composerControlsHardDisabled || inputDisabled;
22035
+ const handoffDisabled = composerControlsHardDisabled || inputDisabled || !onHandoffConversation || handoffMenuTargets.length === 0;
22036
+ const showProviderSelect = !isHeroLayout && selectedProviderSwitchTarget !== null && providerMenuTargets.length > 0;
22037
+ const showHandoffSelect = showProviderSelect && providerSelectReadonly && !previewMode;
21693
22038
  const handleMentionPaletteButton = useCallback9(() => {
21694
22039
  if (composerControlsHardDisabled || inputDisabled) {
21695
22040
  return;
@@ -21713,7 +22058,7 @@ function AgentComposer({
21713
22058
  },
21714
22059
  [addDraftImages, scheduleComposerFocus]
21715
22060
  );
21716
- useEffect11(() => {
22061
+ useEffect12(() => {
21717
22062
  const composer = composerRef.current;
21718
22063
  const dropTarget = composer?.closest("#agent-gui-detail") ?? composer;
21719
22064
  if (!dropTarget) {
@@ -21815,7 +22160,7 @@ function AgentComposer({
21815
22160
  promptImagesSupported,
21816
22161
  scheduleComposerFocus
21817
22162
  ]);
21818
- useEffect11(() => {
22163
+ useEffect12(() => {
21819
22164
  if (!isActive) {
21820
22165
  wasActiveRef.current = false;
21821
22166
  return;
@@ -21825,7 +22170,7 @@ function AgentComposer({
21825
22170
  }
21826
22171
  wasActiveRef.current = true;
21827
22172
  }, [isActive, scheduleComposerFocus]);
21828
- useEffect11(() => {
22173
+ useEffect12(() => {
21829
22174
  if (composerFocusRequestSequence === null || composerFocusRequestSequence === lastComposerFocusRequestRef.current) {
21830
22175
  return;
21831
22176
  }
@@ -22026,12 +22371,12 @@ function AgentComposer({
22026
22371
  const sendButtonState = isQueueMode ? "queue" : shouldShowStopButton ? isInterrupting ? "stopping" : "interrupt" : isSendingTurn ? "loading" : "send";
22027
22372
  const sendButtonBusy = isSendingTurn && !isQueueMode;
22028
22373
  const activePromptRequestId = activePrompt?.requestId ?? null;
22029
- const [dismissedPromptRequestId, setDismissedPromptRequestId] = useState10(null);
22374
+ const [dismissedPromptRequestId, setDismissedPromptRequestId] = useState11(null);
22030
22375
  const visibleActivePrompt = activePrompt && dismissedPromptRequestId !== activePromptRequestId ? activePrompt : null;
22031
22376
  const disabledReasonText = disabledReason?.trim() ?? "";
22032
22377
  const effectivePlaceholder = disabledReasonText || placeholder;
22033
22378
  const visibleDraftFiles = draftFiles;
22034
- useEffect11(() => {
22379
+ useEffect12(() => {
22035
22380
  if (previousSelectedProjectPathRef.current === selectedProjectPath) {
22036
22381
  return;
22037
22382
  }
@@ -22047,7 +22392,7 @@ function AgentComposer({
22047
22392
  sessionCwd: selectedProjectPath || null
22048
22393
  });
22049
22394
  }, [currentUserId, fileMentionSuggestion, selectedProjectPath, workspaceId]);
22050
- useEffect11(() => {
22395
+ useEffect12(() => {
22051
22396
  setDismissedPromptRequestId(null);
22052
22397
  }, [activePromptRequestId]);
22053
22398
  const submitInteractivePromptAndDismiss = useCallback9(
@@ -22523,14 +22868,13 @@ function AgentComposer({
22523
22868
  className: cn(
22524
22869
  AgentGUINode_styles_default.composerMenuTrigger,
22525
22870
  AgentGUINode_styles_default.composerReferenceTrigger,
22526
- "w-auto justify-center text-[var(--agent-gui-text-secondary)] [&_svg]:shrink-0"
22871
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)]"
22527
22872
  ),
22528
22873
  children: /* @__PURE__ */ jsx28(
22529
- AddIcon,
22874
+ AgentComposerMaskIcon,
22530
22875
  {
22531
- "aria-hidden": true,
22532
- className: "size-3.5",
22533
- "data-agent-reference-add-icon": "true"
22876
+ iconUrl: add_lined_bold_default,
22877
+ marker: "reference-add"
22534
22878
  }
22535
22879
  )
22536
22880
  }
@@ -22558,17 +22902,17 @@ function AgentComposer({
22558
22902
  {
22559
22903
  size: "sm",
22560
22904
  "aria-label": labels.referenceWorkspaceFiles,
22905
+ title: labels.referenceWorkspaceFiles,
22561
22906
  className: cn(
22562
22907
  AgentGUINode_styles_default.composerMenuTrigger,
22563
22908
  AgentGUINode_styles_default.composerReferenceTrigger,
22564
- "w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden [&_svg]:shrink-0"
22909
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden"
22565
22910
  ),
22566
22911
  children: /* @__PURE__ */ jsx28(
22567
- AddIcon,
22912
+ AgentComposerMaskIcon,
22568
22913
  {
22569
- "aria-hidden": true,
22570
- className: "size-3.5",
22571
- "data-agent-reference-add-icon": "true"
22914
+ iconUrl: add_lined_bold_default,
22915
+ marker: "reference-add"
22572
22916
  }
22573
22917
  )
22574
22918
  }
@@ -22577,50 +22921,120 @@ function AgentComposer({
22577
22921
  ),
22578
22922
  /* @__PURE__ */ jsx28(TooltipContent, { side: "top", children: labels.addContent })
22579
22923
  ] }) }),
22580
- /* @__PURE__ */ jsx28(
22581
- "button",
22582
- {
22583
- type: "button",
22584
- "aria-label": labels.mentionPalette,
22585
- title: labels.mentionPalette,
22586
- disabled: composerControlsHardDisabled || inputDisabled,
22587
- className: cn(
22588
- AgentGUINode_styles_default.composerMenuTrigger,
22589
- AgentGUINode_styles_default.composerReferenceTrigger,
22590
- "group w-auto justify-center text-[var(--agent-gui-text-secondary)] disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0"
22924
+ /* @__PURE__ */ jsx28(TooltipProvider, { delayDuration: 120, children: /* @__PURE__ */ jsxs15(Tooltip, { children: [
22925
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
22926
+ "button",
22927
+ {
22928
+ type: "button",
22929
+ "aria-label": labels.mentionPalette,
22930
+ disabled: composerControlsHardDisabled || inputDisabled,
22931
+ className: cn(
22932
+ AgentGUINode_styles_default.composerMenuTrigger,
22933
+ AgentGUINode_styles_default.composerReferenceTrigger,
22934
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)] disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0"
22935
+ ),
22936
+ onMouseDown: (event) => event.preventDefault(),
22937
+ onClick: handleMentionPaletteButton,
22938
+ children: /* @__PURE__ */ jsx28(
22939
+ "span",
22940
+ {
22941
+ "aria-hidden": true,
22942
+ className: "inline-block size-3.5 bg-[var(--text-secondary)] transition-colors group-hover:bg-[var(--text-primary)] group-focus-visible:bg-[var(--text-primary)]",
22943
+ style: {
22944
+ WebkitMaskImage: `url("${bold_lined_default}")`,
22945
+ WebkitMaskPosition: "center",
22946
+ WebkitMaskRepeat: "no-repeat",
22947
+ WebkitMaskSize: "contain",
22948
+ maskImage: `url("${bold_lined_default}")`,
22949
+ maskPosition: "center",
22950
+ maskRepeat: "no-repeat",
22951
+ maskSize: "contain"
22952
+ }
22953
+ }
22954
+ )
22955
+ }
22956
+ ) }),
22957
+ /* @__PURE__ */ jsx28(TooltipContent, { side: "top", children: labels.mentionPalette })
22958
+ ] }) })
22959
+ ] }),
22960
+ showHandoffSelect ? /* @__PURE__ */ jsxs15(
22961
+ Select2,
22962
+ {
22963
+ value: HANDOFF_SELECT_IDLE_VALUE,
22964
+ disabled: handoffDisabled,
22965
+ onValueChange: (nextTargetId) => {
22966
+ const target = handoffMenuTargets.find(
22967
+ (candidate) => candidate.targetId === nextTargetId
22968
+ );
22969
+ if (!target || target.disabled === true) {
22970
+ return;
22971
+ }
22972
+ onHandoffConversation?.(target);
22973
+ },
22974
+ children: [
22975
+ /* @__PURE__ */ jsx28(
22976
+ SelectTrigger2,
22977
+ {
22978
+ size: "sm",
22979
+ "aria-label": effectiveHandoffLabel,
22980
+ title: effectiveHandoffLabel,
22981
+ className: cn(
22982
+ AgentGUINode_styles_default.composerMenuTrigger,
22983
+ AgentGUINode_styles_default.composerProviderSelect,
22984
+ AgentGUINode_styles_default.composerHandoffTrigger,
22985
+ "w-auto max-w-[180px] [&>svg:last-child]:hidden"
22986
+ ),
22987
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22988
+ /* @__PURE__ */ jsx28(AgentComposerHandoffIcon, {}),
22989
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: effectiveHandoffLabel })
22990
+ ] })
22991
+ }
22591
22992
  ),
22592
- onMouseDown: (event) => event.preventDefault(),
22593
- onClick: handleMentionPaletteButton,
22594
- children: /* @__PURE__ */ jsx28(
22595
- "span",
22993
+ /* @__PURE__ */ jsx28(
22994
+ SelectContent2,
22596
22995
  {
22597
- "aria-hidden": true,
22598
- className: "inline-block size-3.5 bg-[var(--text-secondary)] transition-colors group-hover:bg-[var(--text-primary)] group-focus-visible:bg-[var(--text-primary)]",
22599
- style: {
22600
- WebkitMaskImage: `url("${lined_14px_default}")`,
22601
- WebkitMaskPosition: "center",
22602
- WebkitMaskRepeat: "no-repeat",
22603
- WebkitMaskSize: "contain",
22604
- maskImage: `url("${lined_14px_default}")`,
22605
- maskPosition: "center",
22606
- maskRepeat: "no-repeat",
22607
- maskSize: "contain"
22608
- }
22996
+ align: "start",
22997
+ className: cn(
22998
+ AgentGUINode_styles_default.composerMenuContent,
22999
+ AgentGUINode_styles_default.composerHandoffMenuContent,
23000
+ "min-w-[190px]"
23001
+ ),
23002
+ "aria-label": effectiveHandoffMenuLabel,
23003
+ children: handoffMenuTargets.map((target) => /* @__PURE__ */ jsx28(
23004
+ SelectItem2,
23005
+ {
23006
+ value: target.targetId,
23007
+ className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
23008
+ disabled: target.disabled === true,
23009
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
23010
+ /* @__PURE__ */ jsx28(
23011
+ "img",
23012
+ {
23013
+ alt: "",
23014
+ "aria-hidden": "true",
23015
+ className: "size-4 shrink-0 rounded-[4px]",
23016
+ src: resolveComposerProviderTargetIconUrl(target)
23017
+ }
23018
+ ),
23019
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: target.label })
23020
+ ] })
23021
+ },
23022
+ `${target.provider}:${target.targetId}`
23023
+ ))
22609
23024
  }
22610
23025
  )
22611
- }
22612
- )
22613
- ] }),
22614
- showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
23026
+ ]
23027
+ }
23028
+ ) : showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
22615
23029
  Select2,
22616
23030
  {
22617
- value: selectedProviderTargetId,
23031
+ value: selectedProviderSwitchTarget.targetId,
22618
23032
  disabled: providerSelectDisabled,
22619
23033
  onValueChange: (nextTargetId) => {
22620
- const target = providerSwitchTargets.find(
23034
+ const target = providerMenuTargets.find(
22621
23035
  (candidate) => candidate.targetId === nextTargetId
22622
23036
  );
22623
- if (!target) {
23037
+ if (!target || target.disabled === true) {
22624
23038
  return;
22625
23039
  }
22626
23040
  onProviderSelect?.({
@@ -22633,14 +23047,27 @@ function AgentComposer({
22633
23047
  SelectTrigger2,
22634
23048
  {
22635
23049
  size: "sm",
22636
- "aria-label": labels.providerSwitchLabel,
22637
- title: labels.providerSwitchLabel,
23050
+ "aria-label": providerSelectLabel,
23051
+ title: providerSelectLabel,
22638
23052
  className: cn(
22639
23053
  AgentGUINode_styles_default.composerMenuTrigger,
22640
23054
  AgentGUINode_styles_default.composerProviderSelect,
22641
- "max-w-[160px] text-[var(--agent-gui-text-secondary)]"
23055
+ "w-auto max-w-[180px]"
22642
23056
  ),
22643
- children: /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx28(SelectValue, { placeholder: selectedProviderLabel }) })
23057
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
23058
+ /* @__PURE__ */ jsx28(
23059
+ "img",
23060
+ {
23061
+ alt: "",
23062
+ "aria-hidden": "true",
23063
+ className: "size-4 shrink-0 rounded-[4px]",
23064
+ src: resolveComposerProviderTargetIconUrl(
23065
+ selectedProviderSwitchTarget
23066
+ )
23067
+ }
23068
+ ),
23069
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: selectedProviderLabel })
23070
+ ] })
22644
23071
  }
22645
23072
  ),
22646
23073
  /* @__PURE__ */ jsx28(
@@ -22648,12 +23075,13 @@ function AgentComposer({
22648
23075
  {
22649
23076
  align: "start",
22650
23077
  className: cn(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
22651
- children: providerSwitchTargets.map((target) => /* @__PURE__ */ jsx28(
23078
+ children: providerMenuTargets.map((target) => /* @__PURE__ */ jsx28(
22652
23079
  SelectItem2,
22653
23080
  {
22654
23081
  value: target.targetId,
22655
23082
  className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22656
- children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
23083
+ disabled: target.disabled === true,
23084
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22657
23085
  /* @__PURE__ */ jsx28(
22658
23086
  "img",
22659
23087
  {
@@ -22767,7 +23195,7 @@ function AgentComposer({
22767
23195
  totalTokens: usage.totalTokens,
22768
23196
  tooltipsEnabled: !previewMode,
22769
23197
  compactSupported: compactSupported ?? false,
22770
- compactDisabled: !hasCompactableContext || composerControlsHardDisabled,
23198
+ compactDisabled: !hasCompactableContext || composerControlsHardDisabled || isSendingTurn,
22771
23199
  onCompact: () => onSubmit(textPromptContent("/compact")),
22772
23200
  labels: {
22773
23201
  usageChipLabel: labels.usageChipLabel,
@@ -22888,7 +23316,7 @@ function AgentComposerDraftImagePreview({
22888
23316
  removeLabel,
22889
23317
  onRemove
22890
23318
  }) {
22891
- const [aspectRatio, setAspectRatio] = useState10(1);
23319
+ const [aspectRatio, setAspectRatio] = useState11(1);
22892
23320
  const previewWidth = Math.round(
22893
23321
  Math.min(
22894
23322
  DRAFT_IMAGE_PREVIEW_MAX_WIDTH_PX,
@@ -23384,6 +23812,14 @@ function AttentionGlyph() {
23384
23812
 
23385
23813
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
23386
23814
  import { createRichTextMentionHref as createRichTextMentionHref2 } from "@tutti-os/ui-rich-text/core";
23815
+
23816
+ // app/renderer/assets/icons/agents/claudecode-flat-filled.svg
23817
+ var claudecode_flat_filled_default = "./claudecode-flat-filled-NHO4JCVK.svg";
23818
+
23819
+ // app/renderer/assets/icons/agents/codex-flat-filled.svg
23820
+ var codex_flat_filled_default = "./codex-flat-filled-WYHCF5VR.svg";
23821
+
23822
+ // agent-gui/agentGuiNode/AgentGUINodeView.tsx
23387
23823
  import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
23388
23824
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
23389
23825
  var AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX = 240;
@@ -23404,8 +23840,22 @@ function resolveAgentGUIHeroIconUrl(provider) {
23404
23840
  const normalizedProvider = normalizeManagedAgentProvider(provider);
23405
23841
  return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
23406
23842
  }
23843
+ function agentGUIProviderIconPresentation(provider, iconUrl) {
23844
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
23845
+ return {
23846
+ provider: normalizedProvider,
23847
+ iconUrl: iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
23848
+ };
23849
+ }
23850
+ function agentGUIProviderRailIconPresentation(provider, iconUrl) {
23851
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
23852
+ return {
23853
+ provider: normalizedProvider,
23854
+ iconUrl: iconUrl?.trim() || MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] || resolveAgentGUIHeroIconUrl(normalizedProvider)
23855
+ };
23856
+ }
23407
23857
  function shouldEmphasizeEmptyHeroProvider(label) {
23408
- return !/[\u3400-\u9fff]/u.test(label);
23858
+ return label.trim().length > 0;
23409
23859
  }
23410
23860
  var fallbackWorkspaceFileReferenceCopy = {
23411
23861
  t(key, values) {
@@ -23586,9 +24036,45 @@ function conversationPlainTitle(conversation, labels, uiLanguage) {
23586
24036
  language: uiLanguage
23587
24037
  });
23588
24038
  }
24039
+ function buildAgentConversationHandoffPrompt(input) {
24040
+ const conversation = input.activeConversation;
24041
+ if (!conversation) {
24042
+ return "";
24043
+ }
24044
+ const sourceAgentLabel = input.selectedProviderTarget?.label?.trim() || conversation.provider;
24045
+ const title = conversationPlainTitle(
24046
+ conversation,
24047
+ input.labels,
24048
+ input.uiLanguage
24049
+ );
24050
+ const mentionLabel = `${sourceAgentLabel}${title ? ` ${title}` : ""}`.trim();
24051
+ const href = createRichTextMentionHref2({
24052
+ providerId: "agent-session",
24053
+ entityId: conversation.id,
24054
+ label: mentionLabel,
24055
+ scope: { workspaceId: input.workspaceId }
24056
+ });
24057
+ return `${formatAgentMentionMarkdown({
24058
+ kind: "session",
24059
+ href,
24060
+ workspaceId: input.workspaceId,
24061
+ targetId: conversation.id,
24062
+ name: mentionLabel,
24063
+ title: title || sourceAgentLabel,
24064
+ scope: "my_sessions",
24065
+ initiatorName: input.currentUserId?.trim() || sourceAgentLabel,
24066
+ agentName: sourceAgentLabel,
24067
+ status: conversation.status,
24068
+ updatedAtUnixMs: conversation.updatedAtUnixMs
24069
+ })} `;
24070
+ }
24071
+ function handoffProjectPathForConversation(conversation) {
24072
+ return conversation?.project?.path?.trim() || conversation?.cwd?.trim() || null;
24073
+ }
23589
24074
  function AgentGUINodeView({
23590
24075
  viewModel,
23591
24076
  onLinkAction,
24077
+ onHandoffConversation,
23592
24078
  capabilityMenuState,
23593
24079
  onCapabilitySettingsRequest,
23594
24080
  isActive = true,
@@ -23629,16 +24115,16 @@ function AgentGUINodeView({
23629
24115
  "use memo";
23630
24116
  const layoutElementRef = useRef12(null);
23631
24117
  const railResizeInteractionRef = useRef12(null);
23632
- const [isRailResizing, setIsRailResizing] = useState11(false);
23633
- const [railResizeWidthPx, setRailResizeWidthPx] = useState11(
24118
+ const [isRailResizing, setIsRailResizing] = useState12(false);
24119
+ const [railResizeWidthPx, setRailResizeWidthPx] = useState12(
23634
24120
  null
23635
24121
  );
23636
- const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState11(false);
23637
- const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState11(null);
24122
+ const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState12(false);
24123
+ const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState12(null);
23638
24124
  const [
23639
24125
  localComposerFocusRequestSequence,
23640
24126
  setLocalComposerFocusRequestSequence
23641
- ] = useState11(0);
24127
+ ] = useState12(0);
23642
24128
  const handledNewConversationRequestSequenceRef = useRef12(
23643
24129
  newConversationRequestSequence
23644
24130
  );
@@ -23806,7 +24292,7 @@ function AgentGUINodeView({
23806
24292
  viewModel.composerSettings.selectedProjectPath
23807
24293
  ]
23808
24294
  );
23809
- useEffect12(() => {
24295
+ useEffect13(() => {
23810
24296
  if (newConversationRequestSequence === null || handledNewConversationRequestSequenceRef.current === newConversationRequestSequence) {
23811
24297
  return;
23812
24298
  }
@@ -23896,7 +24382,7 @@ function AgentGUINodeView({
23896
24382
  },
23897
24383
  [onConversationRailWidthChanged]
23898
24384
  );
23899
- useEffect12(() => {
24385
+ useEffect13(() => {
23900
24386
  if (isRailResizing || railResizeWidthPx === null) {
23901
24387
  return;
23902
24388
  }
@@ -23936,13 +24422,22 @@ function AgentGUINodeView({
23936
24422
  ]
23937
24423
  );
23938
24424
  const visualConversationRailWidthPx = isRailResizing ? railResizeInteractionRef.current?.lastWidthPx ?? conversationRailWidthPx : railResizeWidthPx ?? conversationRailWidthPx;
24425
+ const effectiveConversationRailWidthPx = conversationRailCollapsed ? 0 : visualConversationRailWidthPx;
24426
+ const showProviderRail = true;
24427
+ const renderProviderRail = showProviderRail && !conversationRailCollapsed;
23939
24428
  const layoutStyle = {
23940
- "--agent-gui-conversation-rail-width": `${visualConversationRailWidthPx}px`,
24429
+ "--agent-gui-conversation-rail-width": `${effectiveConversationRailWidthPx}px`,
24430
+ "--agent-gui-conversation-rail-content-width": `${visualConversationRailWidthPx}px`,
23941
24431
  "--agent-gui-detail-min-width": `${detailMinWidthPx}px`,
23942
- gridTemplateColumns: conversationRailCollapsed ? "0 minmax(var(--agent-gui-detail-min-width), 1fr)" : "var(--agent-gui-conversation-rail-width) minmax(var(--agent-gui-detail-min-width), 1fr)"
24432
+ "--agent-gui-provider-rail-width": renderProviderRail ? "52px" : "0px",
24433
+ gridTemplateColumns: showProviderRail ? "var(--agent-gui-provider-rail-width) var(--agent-gui-conversation-rail-width) minmax(var(--agent-gui-detail-min-width), 1fr)" : "var(--agent-gui-conversation-rail-width) minmax(var(--agent-gui-detail-min-width), 1fr)"
23943
24434
  };
23944
24435
  const effectiveRailConfigProvider = railConfigProvider === void 0 ? viewModel.data.provider : railConfigProvider;
23945
24436
  const effectiveRailSlashStatusLimits = railSlashStatusLimits ?? slashStatusLimits;
24437
+ const enabledProviderTargets = viewModel.providerTargets.filter(
24438
+ (target) => target.disabled !== true && ((target.agentTargetId?.trim() ?? "") || (target.targetId?.trim() ?? ""))
24439
+ );
24440
+ const sectionAgentTargetFallbackId = enabledProviderTargets.length <= 1 ? viewModel.selectedProviderTarget.agentTargetId?.trim() || viewModel.selectedProviderTarget.targetId?.trim() || null : null;
23946
24441
  const openAgentEnvSetup = useCallback10(() => {
23947
24442
  if (!effectiveRailConfigProvider) {
23948
24443
  return;
@@ -23968,8 +24463,8 @@ function AgentGUINodeView({
23968
24463
  selectedProviderTarget: viewModel.selectedProviderTarget,
23969
24464
  providerTargets: viewModel.providerTargets,
23970
24465
  providerTargetsLoading: viewModel.providerTargetsLoading,
23971
- conversationScope: viewModel.conversationScope,
23972
24466
  conversationFilter: viewModel.conversationFilter,
24467
+ sectionAgentTargetFallbackId,
23973
24468
  onCreateConversation: requestCreateConversation,
23974
24469
  onUpdateConversationFilter: actions.updateConversationFilter,
23975
24470
  onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
@@ -24007,6 +24502,7 @@ function AgentGUINodeView({
24007
24502
  retryOpenclawGateway,
24008
24503
  selectConversation,
24009
24504
  selectProjectDirectory,
24505
+ sectionAgentTargetFallbackId,
24010
24506
  effectiveRailConfigProvider,
24011
24507
  effectiveRailSlashStatusLimits,
24012
24508
  viewModel.selectedProviderTarget,
@@ -24014,7 +24510,6 @@ function AgentGUINodeView({
24014
24510
  viewModel.providerTargetsLoading,
24015
24511
  toggleConversationPinned,
24016
24512
  uiLanguage,
24017
- viewModel.conversationScope,
24018
24513
  viewModel.conversationFilter,
24019
24514
  viewModel.activeConversationId,
24020
24515
  viewModel.isDeletingConversation,
@@ -24062,6 +24557,28 @@ function AgentGUINodeView({
24062
24557
  inert: previewMode ? true : void 0,
24063
24558
  style: layoutStyle,
24064
24559
  children: [
24560
+ showProviderRail ? /* @__PURE__ */ jsx31(
24561
+ "aside",
24562
+ {
24563
+ className: AgentGUINode_styles_default.providerRailPanel,
24564
+ "aria-label": labels.providerSwitchLabel,
24565
+ "aria-hidden": conversationRailCollapsed ? "true" : void 0,
24566
+ inert: conversationRailCollapsed ? true : void 0,
24567
+ children: /* @__PURE__ */ jsx31(
24568
+ AgentGUIProviderRail,
24569
+ {
24570
+ conversationFilter: viewModel.conversationFilter,
24571
+ labels,
24572
+ previewMode,
24573
+ selectedProviderTarget: viewModel.selectedProviderTarget,
24574
+ providerTargets: viewModel.providerTargets,
24575
+ providerTargetsLoading: viewModel.providerTargetsLoading,
24576
+ onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
24577
+ onUpdateConversationFilter: actions.updateConversationFilter
24578
+ }
24579
+ )
24580
+ }
24581
+ ) : null,
24065
24582
  /* @__PURE__ */ jsx31(
24066
24583
  "aside",
24067
24584
  {
@@ -24120,6 +24637,7 @@ function AgentGUINodeView({
24120
24637
  slashStatusLimits,
24121
24638
  slashStatusLimitsLoading,
24122
24639
  onLinkAction,
24640
+ onHandoffConversation,
24123
24641
  capabilityMenuState,
24124
24642
  onCapabilitySettingsRequest,
24125
24643
  onAgentProviderLogin,
@@ -24240,6 +24758,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24240
24758
  slashStatusLimits,
24241
24759
  slashStatusLimitsLoading,
24242
24760
  onLinkAction,
24761
+ onHandoffConversation,
24243
24762
  capabilityMenuState,
24244
24763
  onCapabilitySettingsRequest,
24245
24764
  onAgentProviderLogin,
@@ -24256,18 +24775,20 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24256
24775
  const timelineScrollAnchorRef = useRef12(null);
24257
24776
  const submittedPromptScrollConversationRef = useRef12(null);
24258
24777
  const pendingPrependScrollAnchorRef = useRef12(null);
24259
- const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState11(true);
24778
+ const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState12(true);
24779
+ const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState12(true);
24260
24780
  const [
24261
24781
  bottomDockDismissedPromptRequestId,
24262
24782
  setBottomDockDismissedPromptRequestId
24263
- ] = useState11(null);
24783
+ ] = useState12(null);
24264
24784
  const conversation = useProjectedAgentConversation({
24265
24785
  conversation: viewModel.conversation,
24266
24786
  detail: viewModel.conversationDetail,
24267
24787
  avoidGroupingEdits: viewModel.avoidGroupingEdits
24268
24788
  });
24269
24789
  const hasActiveConversation = viewModel.activeConversationId !== null;
24270
- const emptyProviderReadinessGate = !hasActiveConversation ? viewModel.providerReadinessGate : null;
24790
+ const selectedProviderTargetComingSoon = viewModel.selectedProviderTarget?.disabled === true;
24791
+ const emptyProviderReadinessGate = !hasActiveConversation ? selectedProviderTargetComingSoon ? { status: "coming_soon" } : viewModel.providerReadinessGate : null;
24271
24792
  const activePrompt = viewModel.pendingInteractivePrompt ?? viewModel.pendingApproval;
24272
24793
  const activePromptRequestId = activePrompt?.requestId ?? null;
24273
24794
  const sessionChrome = useMemo10(
@@ -24414,26 +24935,32 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24414
24935
  );
24415
24936
  const goalBannerLabels = useMemo10(
24416
24937
  () => ({
24417
- goalLabel: labels.goalLabel,
24418
- statusActive: labels.goalStatusActive,
24419
- statusPaused: labels.goalStatusPaused,
24420
- statusBlocked: labels.goalStatusBlocked,
24421
- statusUsageLimited: labels.goalStatusUsageLimited,
24422
- statusBudgetLimited: labels.goalStatusBudgetLimited,
24423
- statusComplete: labels.goalStatusComplete,
24938
+ titleActive: labels.goalTitleActive,
24939
+ titlePaused: labels.goalTitlePaused,
24940
+ titleBlocked: labels.goalTitleBlocked,
24941
+ titleUsageLimited: labels.goalTitleUsageLimited,
24942
+ titleBudgetLimited: labels.goalTitleBudgetLimited,
24943
+ titleComplete: labels.goalTitleComplete,
24424
24944
  budgetUsage: labels.goalBudgetUsage,
24425
- clearHint: labels.goalClearHint
24945
+ clearHint: labels.goalClearHint,
24946
+ editAction: labels.goalEditAction,
24947
+ pauseAction: labels.goalPauseAction,
24948
+ resumeAction: labels.goalResumeAction,
24949
+ clearAction: labels.goalClearAction
24426
24950
  }),
24427
24951
  [
24428
- labels.goalLabel,
24429
- labels.goalStatusActive,
24430
- labels.goalStatusPaused,
24431
- labels.goalStatusBlocked,
24432
- labels.goalStatusUsageLimited,
24433
- labels.goalStatusBudgetLimited,
24434
- labels.goalStatusComplete,
24952
+ labels.goalTitleActive,
24953
+ labels.goalTitlePaused,
24954
+ labels.goalTitleBlocked,
24955
+ labels.goalTitleUsageLimited,
24956
+ labels.goalTitleBudgetLimited,
24957
+ labels.goalTitleComplete,
24435
24958
  labels.goalBudgetUsage,
24436
- labels.goalClearHint
24959
+ labels.goalClearHint,
24960
+ labels.goalEditAction,
24961
+ labels.goalPauseAction,
24962
+ labels.goalResumeAction,
24963
+ labels.goalClearAction
24437
24964
  ]
24438
24965
  );
24439
24966
  const interactivePromptLabels = useMemo10(
@@ -24583,6 +25110,8 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24583
25110
  addReference: labels.addReference,
24584
25111
  addContent: labels.addContent,
24585
25112
  referenceWorkspaceFiles: labels.referenceWorkspaceFiles,
25113
+ handoffConversation: labels.handoffConversation,
25114
+ handoffConversationMenu: labels.handoffConversationMenu,
24586
25115
  providerSwitchLabel: labels.providerSwitchLabel,
24587
25116
  projectLocked: labels.projectLocked,
24588
25117
  projectMissingDescription: labels.projectMissingDescription,
@@ -24602,6 +25131,8 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24602
25131
  labels.fileMentionLoading,
24603
25132
  labels.fileMentionPalette,
24604
25133
  labels.fileMentionTabHint,
25134
+ labels.handoffConversation,
25135
+ labels.handoffConversationMenu,
24605
25136
  labels.inheritedUnavailable,
24606
25137
  labels.loadingConversation,
24607
25138
  labels.modelLabel,
@@ -24720,6 +25251,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24720
25251
  actions.updateComposerSettings
24721
25252
  );
24722
25253
  const submitPrompt = useStableEventCallback2(actions.submitPrompt);
25254
+ const goalControl = useStableEventCallback2(actions.goalControl);
24723
25255
  const submitGuidancePrompt = useStableEventCallback2(
24724
25256
  actions.submitGuidancePrompt
24725
25257
  );
@@ -24781,17 +25313,22 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24781
25313
  },
24782
25314
  [submitInteractivePrompt]
24783
25315
  );
24784
- const canSwitchComposerProvider = viewModel.conversationScope === "multi-provider";
24785
- const composerProviderTargets = canSwitchComposerProvider ? viewModel.providerTargets : [viewModel.selectedProviderTarget];
25316
+ const canSwitchComposerProvider = true;
25317
+ const composerProviderTargets = viewModel.providerTargets;
25318
+ const composerProvider = viewModel.activeConversationId === null ? viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider : viewModel.data.provider;
25319
+ const composerSelectedProviderTarget = viewModel.activeConversationId === null ? viewModel.selectedProviderTarget : viewModel.providerTargets.find((target) => {
25320
+ if (target.provider !== viewModel.data.provider) {
25321
+ return false;
25322
+ }
25323
+ const agentTargetId = viewModel.data.agentTargetId;
25324
+ return !agentTargetId || target.targetId === agentTargetId || target.agentTargetId === agentTargetId;
25325
+ }) ?? viewModel.selectedProviderTarget;
24786
25326
  const bottomDockComposerProps = useMemo10(
24787
25327
  () => ({
24788
25328
  workspaceId: viewModel.workspaceId,
24789
25329
  workspacePath: viewModel.workspacePath,
24790
25330
  currentUserId: viewModel.currentUserId,
24791
- provider: viewModel.data.provider,
24792
- selectedProviderTarget: viewModel.selectedProviderTarget,
24793
- providerTargets: composerProviderTargets,
24794
- providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
25331
+ provider: composerProvider,
24795
25332
  slashStatus,
24796
25333
  usage: viewModel.usage,
24797
25334
  draftContent: viewModel.draftContent,
@@ -24799,8 +25336,13 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24799
25336
  hasCompactableContext: viewModel.hasSentUserMessage,
24800
25337
  compactSupported: viewModel.compactSupported,
24801
25338
  availableSkills: viewModel.availableSkills,
25339
+ selectedProviderTarget: composerSelectedProviderTarget,
25340
+ providerTargets: composerProviderTargets,
25341
+ providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
25342
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? actions.selectHomeComposerAgentTarget : void 0,
24802
25343
  disabled: composerDisabled,
24803
25344
  disabledReason: composerDisabledReason,
25345
+ hasActiveConversation: viewModel.activeConversationId !== null,
24804
25346
  submitDisabled,
24805
25347
  composerSettings: viewModel.composerSettings,
24806
25348
  queuedPrompts: viewModel.queuedPrompts,
@@ -24820,6 +25362,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24820
25362
  composerFocusRequestSequence,
24821
25363
  isActive,
24822
25364
  promptImagesSupported: viewModel.promptImagesSupported,
25365
+ providerSelectLabel: labels.providerSwitchLabel,
25366
+ handoffLabel: labels.handoffConversation,
25367
+ handoffMenuLabel: labels.handoffConversationMenu,
24823
25368
  isInterrupting: viewModel.isInterrupting,
24824
25369
  isSendingTurn: isComposerSending,
24825
25370
  isSubmittingPrompt: viewModel.isRespondingApproval,
@@ -24830,7 +25375,6 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24830
25375
  onDraftContentChange: updateDraftContent,
24831
25376
  onProjectPathChange: updateSelectedProjectPath,
24832
25377
  onSettingsChange: updateComposerSettings,
24833
- onProviderSelect: canSwitchComposerProvider ? actions.selectProvider : void 0,
24834
25378
  onSubmit: submitPromptAndScrollToBottom,
24835
25379
  onSubmitGuidance: submitGuidancePromptAndScrollToBottom,
24836
25380
  onPromptImagesUnsupported: showPromptImagesUnsupported,
@@ -24841,6 +25385,21 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24841
25385
  onSubmitInteractivePrompt: submitInteractivePrompt,
24842
25386
  onCapabilitySettingsRequest,
24843
25387
  onLinkAction: stableLinkAction,
25388
+ onHandoffConversation: onHandoffConversation && viewModel.activeConversationId !== null ? (target) => onHandoffConversation({
25389
+ agentTargetId: target.agentTargetId ?? target.targetId,
25390
+ draftPrompt: buildAgentConversationHandoffPrompt({
25391
+ activeConversation: viewModel.activeConversation,
25392
+ currentUserId: viewModel.currentUserId,
25393
+ labels,
25394
+ selectedProviderTarget: composerSelectedProviderTarget,
25395
+ uiLanguage,
25396
+ workspaceId: viewModel.workspaceId
25397
+ }),
25398
+ provider: target.provider,
25399
+ userProjectPath: handoffProjectPathForConversation(
25400
+ viewModel.activeConversation
25401
+ )
25402
+ }) : void 0,
24844
25403
  onRequestWorkspaceReferences: stableRequestWorkspaceReferences,
24845
25404
  resolveDroppedFileReferences,
24846
25405
  selectProjectDirectory: stableSelectProjectDirectory,
@@ -24850,19 +25409,26 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24850
25409
  [
24851
25410
  canQueueWhileBusy,
24852
25411
  backgroundAgentStatusText,
24853
- canSwitchComposerProvider,
25412
+ actions.selectHomeComposerAgentTarget,
24854
25413
  capabilityMenuState,
24855
- composerProviderTargets,
25414
+ canSwitchComposerProvider,
24856
25415
  composerDisabled,
24857
25416
  composerDisabledReason,
24858
25417
  composerFocusRequestSequence,
24859
25418
  composerLabels,
25419
+ composerProviderTargets,
25420
+ composerSelectedProviderTarget,
24860
25421
  handleInterruptCurrentTurn,
24861
25422
  isActive,
24862
25423
  isComposerSending,
24863
25424
  labels.followupPlaceholder,
25425
+ labels.handoffConversation,
25426
+ labels.handoffConversationMenu,
24864
25427
  labels.initialPlaceholder,
24865
25428
  labels.promptTips,
25429
+ labels.providerSwitchLabel,
25430
+ labels,
25431
+ onHandoffConversation,
24866
25432
  previewMode,
24867
25433
  workspaceReferencePickerOpen,
24868
25434
  composerActivePrompt,
@@ -24885,16 +25451,17 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24885
25451
  stableSelectProjectDirectory,
24886
25452
  stableRequestWorkspaceReferences,
24887
25453
  updateComposerSettings,
24888
- actions.selectProvider,
24889
25454
  updateDraftContent,
24890
25455
  updateSelectedProjectPath,
25456
+ viewModel.activeConversationId,
24891
25457
  viewModel.availableCommands,
24892
25458
  viewModel.availableSkills,
24893
25459
  viewModel.compactSupported,
24894
25460
  viewModel.composerSettings,
24895
25461
  viewModel.currentUserId,
24896
- viewModel.data.provider,
24897
- viewModel.selectedProviderTarget,
25462
+ viewModel.activeConversationId,
25463
+ viewModel.activeConversation,
25464
+ composerProvider,
24898
25465
  viewModel.draftContent,
24899
25466
  viewModel.draftPrompt,
24900
25467
  viewModel.drainingQueuedPromptId,
@@ -24918,6 +25485,12 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24918
25485
  [bottomDockComposerProps]
24919
25486
  );
24920
25487
  const emptyHeroProvider = viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider;
25488
+ const emptyHeroProviderLabel = labels.emptyProviderForProvider?.(emptyHeroProvider) ?? labels.emptyProvider ?? "";
25489
+ const emptyHeroLabel = labels.emptyForProvider?.(emptyHeroProvider) ?? labels.empty;
25490
+ const emptyHeroIconPresentations = useMemo10(
25491
+ () => viewModel.conversationFilter.kind === "all" ? agentGUILaunchpadIconPresentations() : [agentGUIProviderIconPresentation(emptyHeroProvider)],
25492
+ [emptyHeroProvider, viewModel.conversationFilter]
25493
+ );
24921
25494
  const bottomDockStoreState = useMemo10(
24922
25495
  () => ({
24923
25496
  // The lifted prompt is rendered from props on the pane; the store still
@@ -24954,7 +25527,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24954
25527
  viewModel.drainingQueuedPromptId ?? "",
24955
25528
  viewModel.isRespondingApproval ? "1" : "0"
24956
25529
  ].join("|");
24957
- useEffect12(() => {
25530
+ useEffect13(() => {
24958
25531
  setBottomDockDismissedPromptRequestId(null);
24959
25532
  }, [activePromptRequestId]);
24960
25533
  useLayoutEffect4(() => {
@@ -24968,6 +25541,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24968
25541
  pendingPrependScrollAnchorRef.current = null;
24969
25542
  submittedPromptScrollConversationRef.current = null;
24970
25543
  setIsTimelineScrolledToTop(true);
25544
+ setIsTimelineScrolledToBottom(true);
24971
25545
  return;
24972
25546
  }
24973
25547
  const maxScrollTop = Math.max(
@@ -25018,6 +25592,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25018
25592
  setIsTimelineScrolledToTop(
25019
25593
  nextScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
25020
25594
  );
25595
+ setIsTimelineScrolledToBottom(
25596
+ maxScrollTop - nextScrollTop <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX
25597
+ );
25021
25598
  }, [
25022
25599
  conversation,
25023
25600
  showTimelineSkeleton,
@@ -25036,6 +25613,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25036
25613
  const bottomDockRect = bottomDock.getBoundingClientRect();
25037
25614
  let visualTop = bottomDockRect.top;
25038
25615
  bottomDock.querySelectorAll("*").forEach((element) => {
25616
+ if (element.closest(`.${AgentGUINode_styles_default.bottomDockScrollToBottom}`)) {
25617
+ return;
25618
+ }
25039
25619
  const rect = element.getBoundingClientRect();
25040
25620
  if (rect.width > 0 && rect.height > 0) {
25041
25621
  visualTop = Math.min(visualTop, rect.top);
@@ -25049,6 +25629,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25049
25629
  "--agent-gui-bottom-dock-safe-area",
25050
25630
  `${overflowHeight}px`
25051
25631
  );
25632
+ bottomDock.style.setProperty(
25633
+ "--agent-gui-bottom-dock-floating-safe-area",
25634
+ `${overflowHeight}px`
25635
+ );
25052
25636
  };
25053
25637
  const syncBottomDockSpace = () => {
25054
25638
  syncBottomDockSafeArea();
@@ -25079,12 +25663,16 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25079
25663
  setIsTimelineScrolledToTop(
25080
25664
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
25081
25665
  );
25666
+ setIsTimelineScrolledToBottom(true);
25082
25667
  });
25083
25668
  };
25084
25669
  syncBottomDockSpace();
25085
25670
  if (typeof ResizeObserver === "undefined") {
25086
25671
  return () => {
25087
25672
  timeline.style.removeProperty("--agent-gui-bottom-dock-safe-area");
25673
+ bottomDock.style.removeProperty(
25674
+ "--agent-gui-bottom-dock-floating-safe-area"
25675
+ );
25088
25676
  if (animationFrameId !== null) {
25089
25677
  window.cancelAnimationFrame(animationFrameId);
25090
25678
  }
@@ -25100,13 +25688,16 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25100
25688
  }
25101
25689
  return () => {
25102
25690
  timeline.style.removeProperty("--agent-gui-bottom-dock-safe-area");
25691
+ bottomDock.style.removeProperty(
25692
+ "--agent-gui-bottom-dock-floating-safe-area"
25693
+ );
25103
25694
  if (animationFrameId !== null) {
25104
25695
  window.cancelAnimationFrame(animationFrameId);
25105
25696
  }
25106
25697
  observer.disconnect();
25107
25698
  };
25108
25699
  }, [bottomDockStoreRevision, viewModel.activeConversationId]);
25109
- useEffect12(() => {
25700
+ useEffect13(() => {
25110
25701
  const timeline = timelineRef.current;
25111
25702
  const activeConversationId = viewModel.activeConversationId;
25112
25703
  if (!timeline || !activeConversationId) {
@@ -25123,6 +25714,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25123
25714
  setIsTimelineScrolledToTop(
25124
25715
  scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
25125
25716
  );
25717
+ setIsTimelineScrolledToBottom(
25718
+ timeline.scrollHeight - scrollTop - timeline.clientHeight <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX
25719
+ );
25126
25720
  if (viewModel.hasOlderMessages && !viewModel.isLoadingOlderMessages && scrollTop <= AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX) {
25127
25721
  pendingPrependScrollAnchorRef.current = {
25128
25722
  conversationId: activeConversationId,
@@ -25143,6 +25737,28 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25143
25737
  viewModel.hasOlderMessages,
25144
25738
  viewModel.isLoadingOlderMessages
25145
25739
  ]);
25740
+ const scrollTimelineToBottom = useCallback10(() => {
25741
+ const timeline = timelineRef.current;
25742
+ const activeConversationId = viewModel.activeConversationId;
25743
+ if (!timeline || !activeConversationId) {
25744
+ return;
25745
+ }
25746
+ const maxScrollTop = Math.max(
25747
+ 0,
25748
+ timeline.scrollHeight - timeline.clientHeight
25749
+ );
25750
+ setTimelineScrollTopWithUserTransition(timeline, maxScrollTop);
25751
+ timelineScrollAnchorRef.current = {
25752
+ conversationId: activeConversationId,
25753
+ scrollHeight: timeline.scrollHeight,
25754
+ scrollTop: maxScrollTop,
25755
+ clientHeight: timeline.clientHeight
25756
+ };
25757
+ setIsTimelineScrolledToTop(
25758
+ maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
25759
+ );
25760
+ setIsTimelineScrolledToBottom(true);
25761
+ }, [viewModel.activeConversationId]);
25146
25762
  return /* @__PURE__ */ jsxs17("main", { className: AgentGUINode_styles_default.detail, children: [
25147
25763
  /* @__PURE__ */ jsx31(
25148
25764
  AgentGUIDetailHeader,
@@ -25194,7 +25810,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25194
25810
  ScrollArea,
25195
25811
  {
25196
25812
  scrollbarMode: "native",
25197
- className: "min-h-0 flex-1 [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
25813
+ className: "flex h-full min-h-0 flex-1 flex-col [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
25198
25814
  viewportRef: timelineRef,
25199
25815
  viewportTestId: "agent-gui-timeline",
25200
25816
  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(),
@@ -25204,22 +25820,28 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25204
25820
  {
25205
25821
  provider: emptyHeroProvider,
25206
25822
  gate: emptyProviderReadinessGate,
25823
+ showAllProviders: viewModel.conversationFilter.kind === "all",
25207
25824
  labels
25208
25825
  }
25209
25826
  ) : /* @__PURE__ */ jsx31(
25210
25827
  AgentGUIEmptyHeroPane,
25211
25828
  {
25212
25829
  provider: emptyHeroProvider,
25213
- emptyLabel: labels.empty,
25214
- emptyProvider: labels.emptyProvider ?? "",
25830
+ emptyLabel: emptyHeroLabel,
25831
+ emptyProvider: emptyHeroProviderLabel,
25832
+ iconPresentations: emptyHeroIconPresentations,
25215
25833
  inlineNoticeChrome,
25216
25834
  isRespondingApproval: viewModel.isRespondingApproval,
25217
25835
  onSubmitApprovalOption: submitApprovalOption,
25218
25836
  onRetryActivation: retryActivation,
25219
25837
  onAuthLogin: authLogin,
25220
25838
  onContinueInNewConversation: continueInNewConversation,
25839
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? actions.selectHomeComposerAgentTarget : void 0,
25840
+ providerTargets: composerProviderTargets,
25841
+ selectedProviderTarget: viewModel.selectedProviderTarget,
25221
25842
  chromeLabels,
25222
- composerProps: emptyHeroComposerProps
25843
+ composerProps: emptyHeroComposerProps,
25844
+ providerSelectLabel: labels.providerSwitchLabel
25223
25845
  }
25224
25846
  ) : /* @__PURE__ */ jsx31(
25225
25847
  AgentGUIConversationTimelinePane,
@@ -25243,6 +25865,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25243
25865
  AgentGUIBottomDockPane,
25244
25866
  {
25245
25867
  bottomDockRef,
25868
+ showScrollToBottom: !isTimelineScrolledToBottom,
25869
+ scrollToBottomLabel: labels.scrollToBottom,
25870
+ onScrollToBottom: scrollTimelineToBottom,
25246
25871
  bottomDockLiftedPrompt,
25247
25872
  bottomDockReplacementPrompt,
25248
25873
  store: bottomDockStore,
@@ -25255,7 +25880,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25255
25880
  onRetryActivation: retryActivation,
25256
25881
  onAuthLogin: authLogin,
25257
25882
  onContinueInNewConversation: continueInNewConversation,
25258
- onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt
25883
+ onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt,
25884
+ onGoalControl: goalControl,
25885
+ goalPauseSupported: viewModel.goalPauseSupported
25259
25886
  }
25260
25887
  ) : null
25261
25888
  ] });
@@ -25357,29 +25984,52 @@ var AgentGUIEmptyHeroPane = memo(function AgentGUIEmptyHeroPane2({
25357
25984
  provider,
25358
25985
  emptyLabel,
25359
25986
  emptyProvider,
25987
+ iconPresentations,
25360
25988
  inlineNoticeChrome,
25361
25989
  isRespondingApproval,
25362
25990
  onSubmitApprovalOption,
25363
25991
  onAuthLogin,
25364
25992
  onRetryActivation,
25365
25993
  onContinueInNewConversation,
25994
+ onProviderSelect,
25995
+ providerTargets,
25996
+ selectedProviderTarget,
25366
25997
  chromeLabels,
25367
- composerProps
25998
+ composerProps,
25999
+ providerSelectLabel
25368
26000
  }) {
25369
26001
  "use memo";
25370
- const heroIconUrl = resolveAgentGUIHeroIconUrl(provider);
26002
+ const heroIconPresentations = iconPresentations.length > 0 ? iconPresentations : [agentGUIProviderIconPresentation(provider)];
26003
+ const heroIconAnimationKey = heroIconPresentations.map((icon) => `${icon.provider}:${icon.iconUrl}`).join("|");
25371
26004
  return /* @__PURE__ */ jsx31("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.emptyHeroBody, children: [
25372
- /* @__PURE__ */ jsx31(
25373
- "img",
26005
+ heroIconPresentations.length > 1 ? /* @__PURE__ */ jsx31(
26006
+ AgentGUIAllProviderGridIcon,
25374
26007
  {
25375
- "aria-hidden": "true",
25376
- className: AgentGUINode_styles_default.emptyHeroIconEffect,
25377
- draggable: false,
25378
- src: heroIconUrl,
25379
- alt: ""
25380
- }
26008
+ activeProvider: provider,
26009
+ className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
26010
+ icons: heroIconPresentations
26011
+ },
26012
+ heroIconAnimationKey
26013
+ ) : /* @__PURE__ */ jsx31(
26014
+ AgentGUIProviderIconVisual,
26015
+ {
26016
+ ariaHidden: true,
26017
+ imageClassName: AgentGUINode_styles_default.emptyHeroIconEffect,
26018
+ icon: heroIconPresentations[0]
26019
+ },
26020
+ heroIconAnimationKey
25381
26021
  ),
25382
- /* @__PURE__ */ jsx31("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: /* @__PURE__ */ jsx31(EmptyHeroTitle, { label: emptyLabel, providerLabel: emptyProvider }) }),
26022
+ /* @__PURE__ */ jsx31("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: /* @__PURE__ */ jsx31(
26023
+ EmptyHeroTitle,
26024
+ {
26025
+ label: emptyLabel,
26026
+ providerLabel: emptyProvider,
26027
+ providerSelectLabel,
26028
+ providerTargets,
26029
+ selectedProviderTarget,
26030
+ onProviderSelect
26031
+ }
26032
+ ) }),
25383
26033
  inlineNoticeChrome ? /* @__PURE__ */ jsx31(
25384
26034
  AgentSessionChrome,
25385
26035
  {
@@ -25399,13 +26049,21 @@ var AgentGUIProviderReadinessGatePane = memo(
25399
26049
  function AgentGUIProviderReadinessGatePane2({
25400
26050
  provider,
25401
26051
  gate,
26052
+ showAllProviders = false,
25402
26053
  labels
25403
26054
  }) {
25404
26055
  "use memo";
25405
26056
  const heroIconUrl = resolveAgentGUIHeroIconUrl(provider);
26057
+ const launchpadIconPresentations = useMemo10(
26058
+ () => agentGUILaunchpadIconPresentations(),
26059
+ []
26060
+ );
25406
26061
  const pendingAction = gate.pendingAction ?? null;
25407
26062
  const isPending = pendingAction !== null;
25408
- const content = providerGateContent(gate.status, labels);
26063
+ const showAllProvidersChecking = showAllProviders && gate.status === "checking";
26064
+ const content = providerGateContent(gate.status, labels, {
26065
+ showAllProviders: showAllProvidersChecking
26066
+ });
25409
26067
  const action = providerGateAction(gate.status);
25410
26068
  const pendingLabel = pendingAction === "install" ? labels.providerGatePendingInstall : pendingAction === "login" ? labels.providerGatePendingLogin : pendingAction === "refresh" ? labels.providerGatePendingRefresh : null;
25411
26069
  return /* @__PURE__ */ jsx31("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs17(
@@ -25415,7 +26073,13 @@ var AgentGUIProviderReadinessGatePane = memo(
25415
26073
  "data-testid": "agent-gui-provider-readiness-gate",
25416
26074
  role: "status",
25417
26075
  children: [
25418
- /* @__PURE__ */ jsx31(
26076
+ showAllProvidersChecking ? /* @__PURE__ */ jsx31(
26077
+ AgentGUIAllProviderGridIcon,
26078
+ {
26079
+ className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
26080
+ icons: launchpadIconPresentations
26081
+ }
26082
+ ) : /* @__PURE__ */ jsx31(
25419
26083
  "img",
25420
26084
  {
25421
26085
  "aria-hidden": "true",
@@ -25435,7 +26099,7 @@ var AgentGUIProviderReadinessGatePane = memo(
25435
26099
  children: pendingLabel
25436
26100
  }
25437
26101
  ) : null,
25438
- action ? /* @__PURE__ */ jsxs17(
26102
+ action ? /* @__PURE__ */ jsx31(
25439
26103
  Button,
25440
26104
  {
25441
26105
  type: "button",
@@ -25452,10 +26116,20 @@ var AgentGUIProviderReadinessGatePane = memo(
25452
26116
  }
25453
26117
  gate.onAction?.(provider, action);
25454
26118
  },
25455
- children: [
25456
- /* @__PURE__ */ jsx31(Wrench, { size: 16, strokeWidth: 2, "aria-hidden": "true" }),
25457
- isPending && pendingLabel ? pendingLabel : content.actionLabel
25458
- ]
26119
+ children: isPending && pendingLabel ? pendingLabel : content.actionLabel
26120
+ }
26121
+ ) : content.actionLabel ? /* @__PURE__ */ jsx31(
26122
+ Button,
26123
+ {
26124
+ type: "button",
26125
+ className: cn3(
26126
+ AgentGUINode_styles_default.emptyProviderGateAction,
26127
+ "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]"
26128
+ ),
26129
+ "data-testid": "agent-gui-provider-readiness-gate-action",
26130
+ disabled: true,
26131
+ onPointerDown: (event) => event.stopPropagation(),
26132
+ children: content.actionLabel
25459
26133
  }
25460
26134
  ) : null
25461
26135
  ]
@@ -25463,12 +26137,12 @@ var AgentGUIProviderReadinessGatePane = memo(
25463
26137
  ) });
25464
26138
  }
25465
26139
  );
25466
- function providerGateContent(status, labels) {
26140
+ function providerGateContent(status, labels, options = {}) {
25467
26141
  switch (status) {
25468
26142
  case "checking":
25469
26143
  return {
25470
26144
  title: labels.providerGateCheckingTitle,
25471
- description: labels.providerGateCheckingDescription
26145
+ description: options.showAllProviders === true ? labels.providerGateCheckingAgentsDescription : labels.providerGateCheckingDescription
25472
26146
  };
25473
26147
  case "not_installed":
25474
26148
  return {
@@ -25482,6 +26156,12 @@ function providerGateContent(status, labels) {
25482
26156
  description: labels.providerGateLoginDescription,
25483
26157
  actionLabel: labels.providerGateLoginAction
25484
26158
  };
26159
+ case "coming_soon":
26160
+ return {
26161
+ title: labels.providerGateComingSoonTitle,
26162
+ description: labels.providerGateComingSoonDescription,
26163
+ actionLabel: labels.providerGateComingSoonAction
26164
+ };
25485
26165
  case "unavailable":
25486
26166
  return {
25487
26167
  title: labels.providerGateUnavailableTitle,
@@ -25498,27 +26178,167 @@ function providerGateAction(status) {
25498
26178
  return "login";
25499
26179
  case "unavailable":
25500
26180
  return "refresh";
26181
+ case "coming_soon":
25501
26182
  case "checking":
25502
26183
  return null;
25503
26184
  }
25504
26185
  }
26186
+ function AgentGUIAllProviderGridIcon({
26187
+ activeProvider,
26188
+ className,
26189
+ icons
26190
+ }) {
26191
+ return /* @__PURE__ */ jsx31(
26192
+ "span",
26193
+ {
26194
+ "aria-hidden": "true",
26195
+ className: [AgentGUINode_styles_default.providerRailAvatar, className].filter(Boolean).join(" "),
26196
+ children: /* @__PURE__ */ jsx31(
26197
+ AgentGUILaunchpadIconGrid,
26198
+ {
26199
+ activeProvider,
26200
+ icons
26201
+ }
26202
+ )
26203
+ }
26204
+ );
26205
+ }
26206
+ function AgentGUILaunchpadIconGrid({
26207
+ activeProvider,
26208
+ icons
26209
+ }) {
26210
+ const normalizedActiveProvider = activeProvider ? normalizeManagedAgentProvider(activeProvider) : null;
26211
+ return /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map((icon) => {
26212
+ return /* @__PURE__ */ jsx31(
26213
+ "span",
26214
+ {
26215
+ className: AgentGUINode_styles_default.providerRailLaunchpadItem,
26216
+ "data-provider-active": normalizedActiveProvider === null ? void 0 : normalizeManagedAgentProvider(icon.provider) === normalizedActiveProvider,
26217
+ children: /* @__PURE__ */ jsx31(AgentGUIProviderIconVisual, { imageClassName: "", icon })
26218
+ },
26219
+ `${icon.provider}:${icon.iconUrl}`
26220
+ );
26221
+ }) });
26222
+ }
26223
+ function AgentGUIProviderIconVisual({
26224
+ ariaHidden = false,
26225
+ icon,
26226
+ imageClassName
26227
+ }) {
26228
+ return /* @__PURE__ */ jsx31(
26229
+ "img",
26230
+ {
26231
+ alt: "",
26232
+ "aria-hidden": ariaHidden ? "true" : void 0,
26233
+ className: imageClassName,
26234
+ draggable: false,
26235
+ src: icon.iconUrl
26236
+ }
26237
+ );
26238
+ }
25505
26239
  function EmptyHeroTitle({
25506
26240
  label,
25507
- providerLabel
26241
+ providerLabel,
26242
+ providerSelectLabel,
26243
+ providerTargets = [],
26244
+ selectedProviderTarget = null,
26245
+ onProviderSelect
25508
26246
  }) {
25509
26247
  const providerStart = providerLabel ? label.indexOf(providerLabel) : -1;
25510
26248
  if (!shouldEmphasizeEmptyHeroProvider(label) || providerStart < 0) {
25511
26249
  return /* @__PURE__ */ jsx31(Fragment8, { children: label });
25512
26250
  }
25513
26251
  const providerEnd = providerStart + providerLabel.length;
26252
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${selectedProviderTarget?.provider ?? ""}`;
26253
+ const canSwitchProvider = providerTargets.length > 1 && selectedProviderTarget && onProviderSelect;
26254
+ const providerName = label.slice(providerStart, providerEnd);
25514
26255
  return /* @__PURE__ */ jsxs17(Fragment8, { children: [
25515
26256
  label.slice(0, providerStart),
25516
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: label.slice(providerStart, providerEnd) }),
26257
+ canSwitchProvider ? /* @__PURE__ */ jsxs17(
26258
+ Select3,
26259
+ {
26260
+ value: selectedProviderTargetId,
26261
+ onValueChange: (nextTargetId) => {
26262
+ const target = providerTargets.find(
26263
+ (candidate) => candidate.targetId === nextTargetId
26264
+ );
26265
+ if (!target || target.disabled === true) {
26266
+ return;
26267
+ }
26268
+ onProviderSelect({
26269
+ provider: target.provider,
26270
+ providerTargetId: target.targetId
26271
+ });
26272
+ },
26273
+ children: [
26274
+ /* @__PURE__ */ jsx31(
26275
+ SelectTrigger3,
26276
+ {
26277
+ size: "sm",
26278
+ "aria-label": providerSelectLabel,
26279
+ title: providerSelectLabel,
26280
+ className: AgentGUINode_styles_default.emptyHeroProviderSelect,
26281
+ children: /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName })
26282
+ }
26283
+ ),
26284
+ /* @__PURE__ */ jsx31(
26285
+ SelectContent3,
26286
+ {
26287
+ align: "center",
26288
+ className: cn3(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
26289
+ children: providerTargets.map((target) => /* @__PURE__ */ jsx31(
26290
+ SelectItem3,
26291
+ {
26292
+ value: target.targetId,
26293
+ className: cn3(
26294
+ AgentGUINode_styles_default.composerMenuItem,
26295
+ "gap-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-30 data-[disabled]:text-[var(--text-disabled,var(--text-tertiary))]",
26296
+ target.disabled === true ? "cursor-not-allowed opacity-30" : null
26297
+ ),
26298
+ disabled: target.disabled === true,
26299
+ children: /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 items-center gap-1.5", children: [
26300
+ /* @__PURE__ */ jsx31(
26301
+ "img",
26302
+ {
26303
+ alt: "",
26304
+ "aria-hidden": "true",
26305
+ className: cn3(
26306
+ "size-4 shrink-0 rounded-[4px]",
26307
+ target.disabled === true ? "grayscale opacity-30" : null
26308
+ ),
26309
+ src: agentGUIProviderIconPresentation(
26310
+ target.provider,
26311
+ target.iconUrl
26312
+ ).iconUrl
26313
+ }
26314
+ ),
26315
+ /* @__PURE__ */ jsx31(
26316
+ "span",
26317
+ {
26318
+ className: cn3(
26319
+ "min-w-0 truncate",
26320
+ target.disabled === true ? "text-[var(--text-disabled,var(--text-tertiary))]" : null
26321
+ ),
26322
+ children: target.label
26323
+ }
26324
+ )
26325
+ ] })
26326
+ },
26327
+ `${target.provider}:${target.targetId}`
26328
+ ))
26329
+ }
26330
+ )
26331
+ ]
26332
+ }
26333
+ ) : /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName }),
25517
26334
  label.slice(providerEnd)
25518
26335
  ] });
25519
26336
  }
25520
26337
  var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25521
26338
  bottomDockRef,
26339
+ showScrollToBottom,
26340
+ scrollToBottomLabel,
26341
+ onScrollToBottom,
25522
26342
  bottomDockLiftedPrompt,
25523
26343
  bottomDockReplacementPrompt,
25524
26344
  store,
@@ -25531,7 +26351,9 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25531
26351
  onAuthLogin,
25532
26352
  onRetryActivation,
25533
26353
  onContinueInNewConversation,
25534
- onSubmitBottomDockInteractivePrompt
26354
+ onSubmitBottomDockInteractivePrompt,
26355
+ onGoalControl,
26356
+ goalPauseSupported
25535
26357
  }) {
25536
26358
  "use memo";
25537
26359
  const state = useSnapshot(store);
@@ -25547,6 +26369,7 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25547
26369
  const goalStatus = goal ? stringValue2(goal.status) : "";
25548
26370
  const goalTokenBudget = goal ? numberValue2(goal.tokenBudget) : null;
25549
26371
  const goalTokensUsed = goal ? numberValue2(goal.tokensUsed) : null;
26372
+ const goalTimeUsedSeconds = goal ? numberValue2(goal.timeUsedSeconds) : null;
25550
26373
  const showGoalBanner = isGoalBannerVisible(goalObjective, goalStatus);
25551
26374
  return /* @__PURE__ */ jsxs17(
25552
26375
  "div",
@@ -25555,6 +26378,22 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25555
26378
  className: AgentGUINode_styles_default.bottomDock,
25556
26379
  "data-testid": "agent-gui-bottom-dock",
25557
26380
  children: [
26381
+ showScrollToBottom ? /* @__PURE__ */ jsx31(
26382
+ "button",
26383
+ {
26384
+ type: "button",
26385
+ className: cn3(
26386
+ AgentGUINode_styles_default.bottomDockScrollToBottom,
26387
+ "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]"
26388
+ ),
26389
+ "data-testid": "agent-gui-scroll-to-bottom",
26390
+ "aria-label": scrollToBottomLabel,
26391
+ title: scrollToBottomLabel,
26392
+ onPointerDown: (event) => event.stopPropagation(),
26393
+ onClick: onScrollToBottom,
26394
+ children: /* @__PURE__ */ jsx31(ChevronsDown, { "aria-hidden": "true", size: 15, strokeWidth: 2.2 })
26395
+ }
26396
+ ) : null,
25558
26397
  bottomDockLiftedPrompt ? /* @__PURE__ */ jsx31(
25559
26398
  "div",
25560
26399
  {
@@ -25606,7 +26445,12 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25606
26445
  status: goalStatus,
25607
26446
  tokenBudget: goalTokenBudget ?? void 0,
25608
26447
  tokensUsed: goalTokensUsed ?? void 0,
25609
- labels: goalBannerLabels
26448
+ timeUsedSeconds: goalTimeUsedSeconds ?? void 0,
26449
+ labels: goalBannerLabels,
26450
+ onEditObjective: (objective) => onGoalControl("set", objective),
26451
+ onPauseGoal: goalPauseSupported ? () => onGoalControl("pause") : void 0,
26452
+ onResumeGoal: goalPauseSupported ? () => onGoalControl("resume") : void 0,
26453
+ onClearGoal: () => onGoalControl("clear")
25610
26454
  }
25611
26455
  ) : null,
25612
26456
  bottomDockReplacementPrompt ? /* @__PURE__ */ jsx31(
@@ -25643,7 +26487,7 @@ function syncAgentGUIConversationRailStore(store, next) {
25643
26487
  Object.assign(store, next);
25644
26488
  }
25645
26489
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
25646
- return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.isLoadingConversations === next.isLoadingConversations && current.isDeletingConversation === next.isDeletingConversation && current.isDeletingProjectConversations === next.isDeletingProjectConversations && current.labels === next.labels && current.workspaceUserProjectI18n === next.workspaceUserProjectI18n && current.uiLanguage === next.uiLanguage && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && current.railConfigProvider === next.railConfigProvider && current.slashStatusLimits === next.slashStatusLimits && current.selectedProviderTarget === next.selectedProviderTarget && current.providerTargets === next.providerTargets && current.providerTargetsLoading === next.providerTargetsLoading && current.conversationScope === next.conversationScope && current.conversationFilter === next.conversationFilter && current.onUpdateConversationFilter === next.onUpdateConversationFilter && current.onSelectConversationFilterTarget === next.onSelectConversationFilterTarget && current.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
26490
+ return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.isLoadingConversations === next.isLoadingConversations && current.isDeletingConversation === next.isDeletingConversation && current.isDeletingProjectConversations === next.isDeletingProjectConversations && current.labels === next.labels && current.workspaceUserProjectI18n === next.workspaceUserProjectI18n && current.uiLanguage === next.uiLanguage && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && current.railConfigProvider === next.railConfigProvider && current.slashStatusLimits === next.slashStatusLimits && current.selectedProviderTarget === next.selectedProviderTarget && current.providerTargets === next.providerTargets && current.providerTargetsLoading === next.providerTargetsLoading && current.conversationFilter === next.conversationFilter && current.sectionAgentTargetFallbackId === next.sectionAgentTargetFallbackId && current.onUpdateConversationFilter === next.onUpdateConversationFilter && current.onSelectConversationFilterTarget === next.onSelectConversationFilterTarget && current.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
25647
26491
  }
25648
26492
  var AgentGUIConversationRailStorePane = memo(
25649
26493
  function AgentGUIConversationRailStorePane2({
@@ -25868,18 +26712,51 @@ function conversationProjectsRenderEqual2(left, right) {
25868
26712
  return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.label === right.label && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs);
25869
26713
  }
25870
26714
  var agentGUIProviderRailOrder = [
25871
- "nexight",
25872
- "claude-code",
25873
26715
  "codex",
25874
- "openclaw",
26716
+ "claude-code",
26717
+ "nexight",
25875
26718
  "hermes",
26719
+ "openclaw",
25876
26720
  "gemini"
25877
26721
  ];
26722
+ var agentGUIProviderRailDefaultProviders = [
26723
+ "codex",
26724
+ "claude-code",
26725
+ "nexight",
26726
+ "hermes",
26727
+ "openclaw"
26728
+ ];
26729
+ var agentGUIProviderRailDisabledProviders = /* @__PURE__ */ new Set([
26730
+ "nexight",
26731
+ "hermes",
26732
+ "openclaw"
26733
+ ]);
25878
26734
  function agentGUIProviderRailOrderIndex(provider) {
25879
26735
  const index = agentGUIProviderRailOrder.indexOf(provider);
25880
26736
  return index < 0 ? agentGUIProviderRailOrder.length : index;
25881
26737
  }
26738
+ function agentGUILaunchpadIconPresentations() {
26739
+ return [
26740
+ agentGUIProviderRailIconPresentation("codex"),
26741
+ agentGUIProviderRailIconPresentation("claude-code"),
26742
+ agentGUIProviderRailIconPresentation("tutti"),
26743
+ agentGUIProviderRailIconPresentation("hermes")
26744
+ ];
26745
+ }
26746
+ function agentGUIConversationProviderIconUrl(provider) {
26747
+ switch (normalizeManagedAgentProvider(provider)) {
26748
+ case "claude-code":
26749
+ return claudecode_flat_filled_default;
26750
+ case "codex":
26751
+ return codex_flat_filled_default;
26752
+ default:
26753
+ return null;
26754
+ }
26755
+ }
25882
26756
  function agentGUIProviderRailLabel(provider, targetLabel, labels) {
26757
+ if (provider === "nexight" && targetLabel === "Tutti Agent") {
26758
+ return labels.conversationFilterTutti;
26759
+ }
25883
26760
  if (targetLabel.trim() && targetLabel !== provider) {
25884
26761
  return targetLabel;
25885
26762
  }
@@ -25894,21 +26771,51 @@ function agentGUIProviderRailLabel(provider, targetLabel, labels) {
25894
26771
  function agentGUIProviderTargetMatchesConversationFilter(target, filter) {
25895
26772
  return filter.kind === "agentTarget" && (target.agentTargetId?.trim() ?? "") === filter.agentTargetId;
25896
26773
  }
26774
+ function agentGUIProviderRailTargets(providerTargets, providerTargetsLoading) {
26775
+ if (providerTargetsLoading) {
26776
+ return [];
26777
+ }
26778
+ const source = providerTargets.length > 0 && !agentGUIProviderRailTargetsAreFullLocalFallback(providerTargets) ? providerTargets : [];
26779
+ const seenProviders = new Set(source.map((target) => target.provider));
26780
+ const missingDefaultProviders = agentGUIProviderRailDefaultProviders.filter(
26781
+ (provider) => !seenProviders.has(provider)
26782
+ );
26783
+ if (source.length > 0 && missingDefaultProviders.length === 0) {
26784
+ return source;
26785
+ }
26786
+ return [
26787
+ ...source,
26788
+ ...missingDefaultProviders.map(
26789
+ (provider) => agentGUIProviderRailDisabledProviders.has(provider) ? createDisabledPlaceholderAgentGUIProviderTarget(provider) : createLocalAgentGUIProviderTarget(provider)
26790
+ )
26791
+ ];
26792
+ }
26793
+ function agentGUIProviderRailTargetsAreFullLocalFallback(providerTargets) {
26794
+ if (providerTargets.length !== agentGUIProviderRailOrder.length) {
26795
+ return false;
26796
+ }
26797
+ const fallbackProviders = new Set(agentGUIProviderRailOrder);
26798
+ return providerTargets.every(
26799
+ (target) => fallbackProviders.has(target.provider) && target.ref.kind === "local" && target.ref.provider === target.provider && target.targetId === `local:${target.provider}`
26800
+ );
26801
+ }
25897
26802
  var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25898
26803
  conversationFilter,
25899
26804
  labels,
25900
26805
  previewMode,
26806
+ selectedProviderTarget,
25901
26807
  providerTargets,
25902
26808
  providerTargetsLoading,
25903
26809
  onSelectConversationFilterTarget,
25904
26810
  onUpdateConversationFilter
25905
26811
  }) {
25906
26812
  "use memo";
26813
+ const railProviderTargets = useMemo10(
26814
+ () => agentGUIProviderRailTargets(providerTargets, providerTargetsLoading),
26815
+ [providerTargets, providerTargetsLoading]
26816
+ );
25907
26817
  const providerTiles = useMemo10(() => {
25908
- const enabledTargets = providerTargets.filter(
25909
- (target) => target.disabled !== true
25910
- );
25911
- const targets = [...enabledTargets];
26818
+ const targets = [...railProviderTargets];
25912
26819
  const originalIndexByTarget = /* @__PURE__ */ new Map();
25913
26820
  targets.forEach((target, index) => {
25914
26821
  originalIndexByTarget.set(
@@ -25925,12 +26832,31 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25925
26832
  `${right.provider}\0${right.targetId}`
25926
26833
  ) ?? 0);
25927
26834
  });
25928
- }, [providerTargets]);
25929
- const allTileSelected = conversationFilter.kind === "all";
26835
+ }, [railProviderTargets]);
26836
+ const launchpadIconPresentations = useMemo10(
26837
+ () => agentGUILaunchpadIconPresentations(),
26838
+ []
26839
+ );
26840
+ const selectedProviderTargetIsPlaceholder = selectedProviderTarget?.disabled === true;
26841
+ const allTileSelected = conversationFilter.kind === "all" && !selectedProviderTargetIsPlaceholder;
25930
26842
  const selectAllProviders = useCallback10(() => {
25931
26843
  onUpdateConversationFilter({ kind: "all" });
25932
- }, [onUpdateConversationFilter]);
25933
- const selectProviderTile = useCallback10(
26844
+ if (selectedProviderTargetIsPlaceholder) {
26845
+ const fallbackTarget = railProviderTargets.find((target) => target.disabled !== true) ?? null;
26846
+ if (fallbackTarget) {
26847
+ onSelectConversationFilterTarget({
26848
+ provider: fallbackTarget.provider,
26849
+ providerTargetId: fallbackTarget.targetId
26850
+ });
26851
+ }
26852
+ }
26853
+ }, [
26854
+ onSelectConversationFilterTarget,
26855
+ onUpdateConversationFilter,
26856
+ railProviderTargets,
26857
+ selectedProviderTargetIsPlaceholder
26858
+ ]);
26859
+ const selectAgentTargetTile = useCallback10(
25934
26860
  (target) => {
25935
26861
  onSelectConversationFilterTarget({
25936
26862
  provider: target.provider,
@@ -25947,23 +26873,22 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25947
26873
  "aria-label": labels.providerSwitchLabel,
25948
26874
  "aria-busy": providerTargetsLoading,
25949
26875
  children: [
25950
- /* @__PURE__ */ jsxs17(
26876
+ /* @__PURE__ */ jsx31(
25951
26877
  "button",
25952
26878
  {
25953
26879
  type: "button",
25954
26880
  role: "tab",
26881
+ "aria-label": labels.conversationFilterAll,
25955
26882
  "aria-selected": allTileSelected,
25956
26883
  className: AgentGUINode_styles_default.providerRailTile,
25957
26884
  "data-selected": allTileSelected ? "true" : "false",
25958
26885
  disabled: previewMode,
25959
26886
  onClick: selectAllProviders,
25960
- children: [
25961
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(LayoutGrid, { "aria-hidden": true, className: AgentGUINode_styles_default.providerRailAvatarIcon }) }),
25962
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: labels.conversationFilterAll })
25963
- ]
26887
+ children: /* @__PURE__ */ jsx31(AgentGUIAllProviderGridIcon, { icons: launchpadIconPresentations })
25964
26888
  }
25965
26889
  ),
25966
- providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsxs17(
26890
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailSeparator }),
26891
+ providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsx31(
25967
26892
  "button",
25968
26893
  {
25969
26894
  type: "button",
@@ -25973,49 +26898,54 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25973
26898
  "data-loading": "true",
25974
26899
  "data-selected": "false",
25975
26900
  disabled: true,
25976
- children: [
25977
- /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar }),
25978
- /* @__PURE__ */ jsx31(
25979
- "span",
25980
- {
25981
- "aria-hidden": "true",
25982
- className: AgentGUINode_styles_default.providerRailTileLabel
25983
- }
25984
- )
25985
- ]
26901
+ children: /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar })
25986
26902
  },
25987
26903
  `provider-target-loading-${index}`
25988
26904
  )) : null,
25989
26905
  providerTiles.map((target) => {
25990
- const providerSelected = agentGUIProviderTargetMatchesConversationFilter(
26906
+ const providerSelected = target.disabled === true ? selectedProviderTarget?.provider === target.provider && selectedProviderTarget?.targetId === target.targetId : agentGUIProviderTargetMatchesConversationFilter(
25991
26907
  target,
25992
26908
  conversationFilter
25993
26909
  );
25994
- return /* @__PURE__ */ jsxs17(
26910
+ const label = agentGUIProviderRailLabel(
26911
+ target.provider,
26912
+ target.label,
26913
+ labels
26914
+ );
26915
+ const tile = /* @__PURE__ */ jsx31(
25995
26916
  "button",
25996
26917
  {
25997
26918
  type: "button",
25998
26919
  role: "tab",
26920
+ "aria-label": label,
25999
26921
  "aria-selected": providerSelected,
26000
26922
  className: AgentGUINode_styles_default.providerRailTile,
26923
+ "data-disabled": target.disabled === true ? "true" : void 0,
26924
+ "data-provider-tile": "true",
26001
26925
  "data-selected": providerSelected ? "true" : "false",
26002
- disabled: previewMode,
26003
- onClick: () => selectProviderTile(target),
26004
- children: [
26005
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
26006
- "img",
26007
- {
26008
- alt: "",
26009
- "aria-hidden": "true",
26010
- className: AgentGUINode_styles_default.providerRailAvatarImage,
26011
- src: target.iconUrl || resolveAgentGUIHeroIconUrl(target.provider)
26012
- }
26013
- ) }),
26014
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: agentGUIProviderRailLabel(target.provider, target.label, labels) })
26015
- ]
26926
+ disabled: previewMode || target.disabled === true,
26927
+ onClick: () => selectAgentTargetTile(target),
26928
+ children: /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
26929
+ AgentGUIProviderIconVisual,
26930
+ {
26931
+ ariaHidden: true,
26932
+ imageClassName: AgentGUINode_styles_default.providerRailAvatarImage,
26933
+ icon: agentGUIProviderRailIconPresentation(
26934
+ target.provider,
26935
+ target.iconUrl
26936
+ )
26937
+ }
26938
+ ) })
26016
26939
  },
26017
26940
  `${target.provider}:${target.targetId}`
26018
26941
  );
26942
+ if (previewMode) {
26943
+ return tile;
26944
+ }
26945
+ return /* @__PURE__ */ jsxs17(Tooltip3, { children: [
26946
+ /* @__PURE__ */ jsx31(TooltipTrigger3, { asChild: true, children: tile }),
26947
+ /* @__PURE__ */ jsx31(TooltipContent3, { side: "right", sideOffset: -4, children: label })
26948
+ ] }, `${target.provider}:${target.targetId}:tooltip`);
26019
26949
  })
26020
26950
  ]
26021
26951
  }
@@ -26027,18 +26957,19 @@ function useAgentGUIConversationRail({
26027
26957
  conversations,
26028
26958
  labels,
26029
26959
  previewMode,
26960
+ sectionAgentTargetFallbackId,
26030
26961
  userProjects,
26031
26962
  workspaceId
26032
26963
  }) {
26033
26964
  const agentActivityRuntime = useAgentActivityRuntime();
26034
- const [runtimeRailSections, setRuntimeRailSections] = useState11(null);
26035
- const [sectionPageStates, setSectionPageStates] = useState11(() => /* @__PURE__ */ new Map());
26965
+ const [runtimeRailSections, setRuntimeRailSections] = useState12(null);
26966
+ const [sectionPageStates, setSectionPageStates] = useState12(() => /* @__PURE__ */ new Map());
26036
26967
  const pagingRequestSequenceRef = useRef12(0);
26037
26968
  const pagingAbortControllersRef = useRef12(/* @__PURE__ */ new Map());
26038
26969
  const runtimeListSessionSections = agentActivityRuntime.listSessionSections;
26039
26970
  const runtimeListSessionSectionPage = agentActivityRuntime.listSessionSectionPage;
26040
26971
  const runtimeSectionsEnabled = !previewMode && Boolean(runtimeListSessionSections) && Boolean(runtimeListSessionSectionPage);
26041
- const sectionAgentTargetId = conversationFilter.kind === "agentTarget" ? conversationFilter.agentTargetId.trim() : "";
26972
+ const sectionAgentTargetId = conversationFilter.kind === "agentTarget" ? conversationFilter.agentTargetId.trim() : sectionAgentTargetFallbackId?.trim() ?? "";
26042
26973
  const userProjectPaths = useMemo10(
26043
26974
  () => userProjects.map((project) => project.path.trim()).filter((path) => path.length > 0),
26044
26975
  [userProjects]
@@ -26054,7 +26985,7 @@ function useAgentGUIConversationRail({
26054
26985
  }),
26055
26986
  [labels.sectionConversations, labels.sectionPinned]
26056
26987
  );
26057
- useEffect12(() => {
26988
+ useEffect13(() => {
26058
26989
  pagingRequestSequenceRef.current += 1;
26059
26990
  for (const controller of pagingAbortControllersRef.current.values()) {
26060
26991
  controller.abort();
@@ -26076,7 +27007,7 @@ function useAgentGUIConversationRail({
26076
27007
  ).join("|"),
26077
27008
  [conversations]
26078
27009
  );
26079
- useEffect12(() => {
27010
+ useEffect13(() => {
26080
27011
  if (!runtimeSectionsEnabled || !runtimeListSessionSections) {
26081
27012
  return;
26082
27013
  }
@@ -26130,7 +27061,7 @@ function useAgentGUIConversationRail({
26130
27061
  userProjectPathKey,
26131
27062
  workspaceId
26132
27063
  ]);
26133
- useEffect12(() => {
27064
+ useEffect13(() => {
26134
27065
  if (!runtimeSectionsEnabled) {
26135
27066
  return;
26136
27067
  }
@@ -26269,12 +27200,8 @@ var AgentGUIConversationRailPane = memo(
26269
27200
  isCollapsed,
26270
27201
  railConfigProvider,
26271
27202
  slashStatusLimits,
26272
- providerTargets,
26273
- providerTargetsLoading,
26274
- conversationScope,
26275
27203
  conversationFilter,
26276
- onUpdateConversationFilter,
26277
- onSelectConversationFilterTarget,
27204
+ sectionAgentTargetFallbackId,
26278
27205
  onCreateConversation,
26279
27206
  onOpenAgentEnvSetup,
26280
27207
  onRetryOpenclawGateway,
@@ -26291,17 +27218,10 @@ var AgentGUIConversationRailPane = memo(
26291
27218
  onConfirmDeleteConversation
26292
27219
  }) {
26293
27220
  "use memo";
26294
- const showProviderRail = conversationScope === "multi-provider";
26295
- const [conversationQuery, setConversationQuery] = useState11("");
26296
- const updateConversationFilter = useStableEventCallback2(
26297
- onUpdateConversationFilter
26298
- );
26299
- const selectConversationFilterTarget = useStableEventCallback2(
26300
- onSelectConversationFilterTarget
26301
- );
26302
- const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState11(() => /* @__PURE__ */ new Set());
26303
- const [currentTimeMs, setCurrentTimeMs] = useState11(() => Date.now());
26304
- const [pendingProjectAction, setPendingProjectAction] = useState11(null);
27221
+ const [conversationQuery, setConversationQuery] = useState12("");
27222
+ const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState12(() => /* @__PURE__ */ new Set());
27223
+ const [currentTimeMs, setCurrentTimeMs] = useState12(() => Date.now());
27224
+ const [pendingProjectAction, setPendingProjectAction] = useState12(null);
26305
27225
  const railElementRef = useRef12(null);
26306
27226
  const conversationListRef = useRef12(null);
26307
27227
  const conversationItemElementsRef = useRef12(
@@ -26321,10 +27241,11 @@ var AgentGUIConversationRailPane = memo(
26321
27241
  conversations,
26322
27242
  labels,
26323
27243
  previewMode,
27244
+ sectionAgentTargetFallbackId,
26324
27245
  userProjects,
26325
27246
  workspaceId
26326
27247
  });
26327
- useEffect12(() => {
27248
+ useEffect13(() => {
26328
27249
  const timer = window.setInterval(() => {
26329
27250
  setCurrentTimeMs(Date.now());
26330
27251
  }, 6e4);
@@ -26476,18 +27397,6 @@ var AgentGUIConversationRailPane = memo(
26476
27397
  }
26477
27398
  )
26478
27399
  ] }),
26479
- showProviderRail ? /* @__PURE__ */ jsx31(
26480
- AgentGUIProviderRail,
26481
- {
26482
- conversationFilter,
26483
- labels,
26484
- previewMode,
26485
- providerTargets,
26486
- providerTargetsLoading,
26487
- onSelectConversationFilterTarget: selectConversationFilterTarget,
26488
- onUpdateConversationFilter: updateConversationFilter
26489
- }
26490
- ) : null,
26491
27400
  openclawGateway?.status === "starting" ? /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.gatewayStatus, "data-state": "starting", children: [
26492
27401
  /* @__PURE__ */ jsx31(
26493
27402
  StatusDot,
@@ -26721,7 +27630,7 @@ var AgentGUIConversationRailSection = memo(
26721
27630
  }) {
26722
27631
  "use memo";
26723
27632
  const isProjectSection = section.kind === "project";
26724
- const [visibleItemLimit, setVisibleItemLimit] = useState11(
27633
+ const [visibleItemLimit, setVisibleItemLimit] = useState12(
26725
27634
  AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
26726
27635
  );
26727
27636
  const visibleItemCount = isSectionCollapsed ? 0 : Math.min(visibleItemLimit, section.items.length);
@@ -27084,6 +27993,7 @@ var AgentGUIConversationRailItem = memo(
27084
27993
  }) {
27085
27994
  "use memo";
27086
27995
  const pinned = (item.pinnedAtUnixMs ?? 0) > 0;
27996
+ const providerIconUrl = agentGUIConversationProviderIconUrl(item.provider);
27087
27997
  const setItemElement = useCallback10(
27088
27998
  (element) => {
27089
27999
  registerItemElement(item.id, element);
@@ -27125,7 +28035,19 @@ var AgentGUIConversationRailItem = memo(
27125
28035
  className: AgentGUINode_styles_default.conversationSelect,
27126
28036
  onClick: handleSelect,
27127
28037
  children: [
27128
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.conversationTitle, children: conversationPlainTitle(item, labels, uiLanguage) }),
28038
+ /* @__PURE__ */ jsxs17("span", { className: AgentGUINode_styles_default.conversationTitleRow, children: [
28039
+ providerIconUrl ? /* @__PURE__ */ jsx31(
28040
+ "span",
28041
+ {
28042
+ "aria-hidden": "true",
28043
+ className: AgentGUINode_styles_default.conversationProviderIcon,
28044
+ style: {
28045
+ "--agent-gui-conversation-provider-icon-url": `url("${providerIconUrl}")`
28046
+ }
28047
+ }
28048
+ ) : null,
28049
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.conversationTitle, children: conversationPlainTitle(item, labels, uiLanguage) })
28050
+ ] }),
27129
28051
  /* @__PURE__ */ jsx31(ConversationMeta, { item, nowMs: currentTimeMs, labels })
27130
28052
  ]
27131
28053
  }
@@ -27336,6 +28258,17 @@ var AgentGUIConversationTimelinePane = memo(
27336
28258
  function setTimelineScrollTopInstantly(element, top) {
27337
28259
  element.scrollTop = top;
27338
28260
  }
28261
+ function setTimelineScrollTopWithUserTransition(element, top) {
28262
+ const reducedMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
28263
+ if (typeof element.scrollTo === "function") {
28264
+ element.scrollTo({
28265
+ top,
28266
+ behavior: reducedMotion ? "auto" : "smooth"
28267
+ });
28268
+ return;
28269
+ }
28270
+ element.scrollTop = top;
28271
+ }
27339
28272
 
27340
28273
  // agent-gui/workspaceDesktop/view/desktopDockAgentProbeTooltipModel.ts
27341
28274
  function findWorkspaceAgentProbeForDockProvider(snapshot3, provider) {
@@ -27344,35 +28277,6 @@ function findWorkspaceAgentProbeForDockProvider(snapshot3, provider) {
27344
28277
  }
27345
28278
  return snapshot3.providers.find((p) => p.provider === provider) ?? null;
27346
28279
  }
27347
- function quotaRenderStateEquals(left, right) {
27348
- return left?.quotaType === right?.quotaType && left?.percentRemaining === right?.percentRemaining && left?.resetsAtUnixMs === right?.resetsAtUnixMs && left?.resetText === right?.resetText && left?.dollarRemaining === right?.dollarRemaining && left?.modelName === right?.modelName;
27349
- }
27350
- function agentProbeProviderRenderStateEquals(left, right) {
27351
- if (left === right) {
27352
- return true;
27353
- }
27354
- if (!left || !right) {
27355
- return left === right;
27356
- }
27357
- return left.provider === right.provider && left.availability.status === right.availability.status && left.availability.detailsVisible === right.availability.detailsVisible && (left.availability.checks?.length ?? 0) === (right.availability.checks?.length ?? 0) && (left.availability.checks ?? []).every((check, index) => {
27358
- const next = right.availability.checks?.[index];
27359
- return check.name === next?.name && check.passed === next?.passed && check.detail === next?.detail;
27360
- }) && (left.usage?.accountTier ?? null) === (right.usage?.accountTier ?? null) && (left.usage?.costUsage?.dollarUsed ?? null) === (right.usage?.costUsage?.dollarUsed ?? null) && (left.usage?.costUsage?.dollarLimit ?? null) === (right.usage?.costUsage?.dollarLimit ?? null) && (left.usage?.quotas?.length ?? 0) === (right.usage?.quotas?.length ?? 0) && (left.usage?.quotas ?? []).every(
27361
- (quota, index) => quotaRenderStateEquals(quota, right.usage?.quotas?.[index])
27362
- ) && (left.attempts?.length ?? 0) === (right.attempts?.length ?? 0) && (left.attempts ?? []).every((attempt, index) => {
27363
- const next = right.attempts?.[index];
27364
- return attempt.strategy === next?.strategy && attempt.success === next?.success && attempt.errorCode === next?.errorCode && attempt.errorMessage === next?.errorMessage;
27365
- }) && left.lastError?.code === right.lastError?.code && left.lastError?.message === right.lastError?.message;
27366
- }
27367
- function workspaceAgentProbeRenderStateEqualsForProvider(left, right, provider) {
27368
- if (left === right) {
27369
- return true;
27370
- }
27371
- return (left?.isLoadingAvailability ?? false) === (right?.isLoadingAvailability ?? false) && (left?.isLoadingUsage ?? false) === (right?.isLoadingUsage ?? false) && agentProbeProviderRenderStateEquals(
27372
- findWorkspaceAgentProbeForDockProvider(left?.snapshot ?? null, provider),
27373
- findWorkspaceAgentProbeForDockProvider(right?.snapshot ?? null, provider)
27374
- );
27375
- }
27376
28280
  function buildDockAgentProbeTooltipLines(probe, isLoadingAvailability, t, popupOpts) {
27377
28281
  if (isLoadingAvailability && !probe) {
27378
28282
  return [t("agentHost.workspaceAgentProbeDockChecking")];
@@ -27540,10 +28444,10 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
27540
28444
  import { Info as Info3 } from "lucide-react";
27541
28445
  import {
27542
28446
  useCallback as useCallback11,
27543
- useEffect as useEffect13,
28447
+ useEffect as useEffect14,
27544
28448
  useLayoutEffect as useLayoutEffect5,
27545
28449
  useRef as useRef13,
27546
- useState as useState12
28450
+ useState as useState13
27547
28451
  } from "react";
27548
28452
  import { createPortal as createPortal4 } from "react-dom";
27549
28453
  import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -27582,8 +28486,8 @@ function AgentProbeInfoPopover({
27582
28486
  "use memo";
27583
28487
  const anchorRef = useRef13(null);
27584
28488
  const popoverRef = useRef13(null);
27585
- const [isOpen, setIsOpen] = useState12(false);
27586
- const [popoverStyle, setPopoverStyle] = useState12(null);
28489
+ const [isOpen, setIsOpen] = useState13(false);
28490
+ const [popoverStyle, setPopoverStyle] = useState13(null);
27587
28491
  const openPopover = useCallback11(() => {
27588
28492
  if (!isOpen) {
27589
28493
  onOpen?.();
@@ -27623,7 +28527,7 @@ function AgentProbeInfoPopover({
27623
28527
  maxWidth: availableWidth
27624
28528
  });
27625
28529
  }, []);
27626
- useEffect13(() => {
28530
+ useEffect14(() => {
27627
28531
  if (!isOpen) {
27628
28532
  return;
27629
28533
  }
@@ -28019,9 +28923,6 @@ function normalizeSlashStatusModelName(value) {
28019
28923
  return value?.trim().toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") ?? "";
28020
28924
  }
28021
28925
  function resolveAgentGUIRailStatusProvider(input) {
28022
- if (input.conversationScope !== "multi-provider") {
28023
- return input.activeProvider;
28024
- }
28025
28926
  const filter = input.conversationFilter;
28026
28927
  if (filter.kind !== "agentTarget") {
28027
28928
  return null;
@@ -28073,11 +28974,7 @@ function composerOverridesByAgentTargetIdEqual(left, right) {
28073
28974
  return true;
28074
28975
  }
28075
28976
  function areAgentGUINodePropsEqual(previous, next) {
28076
- return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.providerReadinessGates === next.providerReadinessGates && previous.defaultProviderTargetId === next.defaultProviderTargetId && previous.conversationScope === next.conversationScope && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onRememberComposerDefaults === next.onRememberComposerDefaults && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && (previous.conversationScope === "multi-provider" || next.conversationScope === "multi-provider" ? previous.workspaceAgentProbes === next.workspaceAgentProbes : workspaceAgentProbeRenderStateEqualsForProvider(
28077
- previous.workspaceAgentProbes,
28078
- next.workspaceAgentProbes,
28079
- previous.state.provider
28080
- )) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
28977
+ return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onHandoffConversation === next.onHandoffConversation && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.providerReadinessGates === next.providerReadinessGates && previous.defaultProviderTargetId === next.defaultProviderTargetId && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onRememberComposerDefaults === next.onRememberComposerDefaults && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && previous.workspaceAgentProbes === next.workspaceAgentProbes && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
28081
28978
  }
28082
28979
  var AgentGUINode = memo2(function AgentGUINode2({
28083
28980
  nodeId,
@@ -28100,6 +28997,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28100
28997
  height,
28101
28998
  desktopSize,
28102
28999
  onLinkAction,
29000
+ onHandoffConversation,
28103
29001
  capabilityMenuState,
28104
29002
  onCapabilitySettingsRequest,
28105
29003
  onAgentProviderLogin,
@@ -28107,7 +29005,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
28107
29005
  providerTargetsLoading = false,
28108
29006
  providerReadinessGates = null,
28109
29007
  defaultProviderTargetId = null,
28110
- conversationScope = "single-provider",
28111
29008
  onWorkspaceFileReferencesAdded,
28112
29009
  onOpenConversationWindow,
28113
29010
  onClose,
@@ -28264,7 +29161,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
28264
29161
  workspacePath,
28265
29162
  avoidGroupingEdits: agentSettings.avoidGroupingEdits,
28266
29163
  data: state,
28267
- conversationScope,
28268
29164
  openSessionRequest,
28269
29165
  prefillPromptRequest,
28270
29166
  providerTargets,
@@ -28303,13 +29199,8 @@ var AgentGUINode = memo2(function AgentGUINode2({
28303
29199
  const activeReadinessProvider = viewModel.activeConversationId !== null ? activeProvider : viewModel.selectedProviderTarget.provider;
28304
29200
  const selectedProviderTargetLabel = viewModel.selectedProviderTarget?.label ?? resolveAgentGUIProviderDisplayLabel(state.provider, fallbackAgentTitle);
28305
29201
  const displayProviderLabel = viewModel.activeConversation ? resolveAgentGUIProviderDisplayLabel(activeProvider, fallbackAgentTitle) : selectedProviderTargetLabel;
28306
- const windowAgentTitle = viewModel.activeConversation ? getAgentHostManagedToolchainAgentByName(activeProvider)?.label ?? displayProviderLabel : displayProviderLabel;
28307
29202
  const activeConversationDockTitle = viewModel.activeConversation ? resolveAgentGUIDockConversationTitle(viewModel.activeConversation) : null;
28308
- const activeConversationWindowTitle = viewModel.activeConversation ? formatAgentGUIConversationPlainTitle(viewModel.activeConversation, {
28309
- fallbackAgentLabel: fallbackAgentTitle,
28310
- language: locale
28311
- }) : null;
28312
- useEffect14(() => {
29203
+ useEffect15(() => {
28313
29204
  if (previewMode || !viewModel.activeConversation) {
28314
29205
  return;
28315
29206
  }
@@ -28361,6 +29252,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
28361
29252
  "agentHost.agentGui.providerGateCheckingDescription",
28362
29253
  { provider: displayProviderLabel }
28363
29254
  ),
29255
+ providerGateCheckingAgentsDescription: t(
29256
+ "agentHost.agentGui.providerGateCheckingAgentsDescription"
29257
+ ),
28364
29258
  providerGateInstallTitle: t(
28365
29259
  "agentHost.agentGui.providerGateInstallTitle",
28366
29260
  { provider: displayProviderLabel }
@@ -28380,6 +29274,17 @@ var AgentGUINode = memo2(function AgentGUINode2({
28380
29274
  { provider: displayProviderLabel }
28381
29275
  ),
28382
29276
  providerGateLoginAction: t("agentHost.agentGui.providerGateLoginAction"),
29277
+ providerGateComingSoonTitle: t(
29278
+ "agentHost.agentGui.providerGateComingSoonTitle",
29279
+ { provider: displayProviderLabel }
29280
+ ),
29281
+ providerGateComingSoonDescription: t(
29282
+ "agentHost.agentGui.providerGateComingSoonDescription",
29283
+ { provider: displayProviderLabel }
29284
+ ),
29285
+ providerGateComingSoonAction: t(
29286
+ "agentHost.agentGui.providerGateComingSoonAction"
29287
+ ),
28383
29288
  providerGateUnavailableTitle: t(
28384
29289
  "agentHost.agentGui.providerGateUnavailableTitle",
28385
29290
  { provider: displayProviderLabel }
@@ -28504,7 +29409,14 @@ var AgentGUINode = memo2(function AgentGUINode2({
28504
29409
  planImplementationSkip: t("agentHost.agentGui.planImplementationSkip"),
28505
29410
  noRunningResponse: t("agentHost.agentGui.noRunningResponse"),
28506
29411
  empty: t("agentHost.agentGui.empty", { provider: displayProviderLabel }),
29412
+ emptyForProvider: (provider) => t("agentHost.agentGui.empty", {
29413
+ provider: resolveAgentGUIProviderDisplayLabel(
29414
+ provider,
29415
+ fallbackAgentTitle
29416
+ )
29417
+ }),
28507
29418
  emptyProvider: displayProviderLabel,
29419
+ emptyProviderForProvider: (provider) => resolveAgentGUIProviderDisplayLabel(provider, fallbackAgentTitle),
28508
29420
  conversations: t("agentHost.agentGui.conversations"),
28509
29421
  newConversation: t("agentHost.agentGui.newConversation"),
28510
29422
  agentConfig: t("agentHost.agentGui.agentConfig"),
@@ -28518,11 +29430,13 @@ var AgentGUINode = memo2(function AgentGUINode2({
28518
29430
  conversationFilterClaudeCode: t(
28519
29431
  "agentHost.agentGui.conversationFilterClaudeCode"
28520
29432
  ),
29433
+ conversationFilterTutti: t("agentHost.agentGui.conversationFilterTutti"),
28521
29434
  providerSwitchLabel: t("agentHost.agentGui.providerSwitchLabel"),
28522
29435
  startConversation: t("agentHost.agentGui.startConversation"),
28523
29436
  selectConversation: t("agentHost.agentGui.selectConversation"),
28524
29437
  loadingConversations: t("agentHost.agentGui.loadingConversations"),
28525
29438
  loadingConversation: t("agentHost.agentGui.loadingConversation"),
29439
+ scrollToBottom: t("agentHost.agentGui.scrollToBottom"),
28526
29440
  searchNoConversations: t("agentHost.agentGui.searchNoConversations"),
28527
29441
  conversationUnavailable: t("agentHost.agentGui.conversationUnavailable"),
28528
29442
  fallbackAgentTitle,
@@ -28591,14 +29505,18 @@ var AgentGUINode = memo2(function AgentGUINode2({
28591
29505
  "agentHost.agentGui.continueInNewConversation"
28592
29506
  ),
28593
29507
  goalLabel: t("agentHost.agentGui.goalLabel"),
28594
- goalStatusActive: t("agentHost.agentGui.goalStatusActive"),
28595
- goalStatusPaused: t("agentHost.agentGui.goalStatusPaused"),
28596
- goalStatusBlocked: t("agentHost.agentGui.goalStatusBlocked"),
28597
- goalStatusUsageLimited: t("agentHost.agentGui.goalStatusUsageLimited"),
28598
- goalStatusBudgetLimited: t("agentHost.agentGui.goalStatusBudgetLimited"),
28599
- goalStatusComplete: t("agentHost.agentGui.goalStatusComplete"),
29508
+ goalTitleActive: t("agentHost.agentGui.goalTitleActive"),
29509
+ goalTitlePaused: t("agentHost.agentGui.goalTitlePaused"),
29510
+ goalTitleBlocked: t("agentHost.agentGui.goalTitleBlocked"),
29511
+ goalTitleUsageLimited: t("agentHost.agentGui.goalTitleUsageLimited"),
29512
+ goalTitleBudgetLimited: t("agentHost.agentGui.goalTitleBudgetLimited"),
29513
+ goalTitleComplete: t("agentHost.agentGui.goalTitleComplete"),
28600
29514
  goalBudgetUsage: (used, budget) => t("agentHost.agentGui.goalBudgetUsage", { used, budget }),
28601
29515
  goalClearHint: t("agentHost.agentGui.goalClearHint"),
29516
+ goalEditAction: t("agentHost.agentGui.goalEditAction"),
29517
+ goalPauseAction: t("agentHost.agentGui.goalPauseAction"),
29518
+ goalResumeAction: t("agentHost.agentGui.goalResumeAction"),
29519
+ goalClearAction: t("agentHost.agentGui.goalClearAction"),
28602
29520
  processing: t("agentHost.agentGui.processing"),
28603
29521
  turnSummary: t("agentHost.agentGui.turnSummary"),
28604
29522
  userMessageLocator: t("agentHost.agentGui.userMessageLocator"),
@@ -28836,7 +29754,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
28836
29754
  removeMention: t("common.remove"),
28837
29755
  addReference: t("agentHost.agentGui.addReference"),
28838
29756
  addContent: t("agentHost.agentGui.addContent"),
28839
- referenceWorkspaceFiles: t("agentHost.issue.referenceWorkspaceFiles")
29757
+ referenceWorkspaceFiles: t("agentHost.issue.referenceWorkspaceFiles"),
29758
+ handoffConversation: t("agentHost.agentGui.handoffConversation"),
29759
+ handoffConversationMenu: t("agentHost.agentGui.handoffConversationMenu")
28840
29760
  }),
28841
29761
  [displayProviderLabel, fallbackAgentTitle, t]
28842
29762
  );
@@ -28849,23 +29769,14 @@ var AgentGUINode = memo2(function AgentGUINode2({
28849
29769
  }),
28850
29770
  [t]
28851
29771
  );
28852
- const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle : null;
28853
- const windowTitle = collapsedWindowConversationTitle || (isConversationRailCollapsed ? activeConversationWindowTitle : null) || windowAgentTitle || title;
28854
- const windowTitleIconUrl = agentGuiDockIconUrls[activeProvider] ?? null;
29772
+ const windowTitle = title;
28855
29773
  const activeProbeProvider = activeProvider;
28856
29774
  const railStatusProvider = useMemo11(
28857
29775
  () => resolveAgentGUIRailStatusProvider({
28858
- activeProvider: activeProbeProvider,
28859
29776
  conversationFilter: viewModel.conversationFilter,
28860
- conversationScope: viewModel.conversationScope,
28861
29777
  providerTargets: viewModel.providerTargets
28862
29778
  }),
28863
- [
28864
- activeProbeProvider,
28865
- viewModel.conversationFilter,
28866
- viewModel.conversationScope,
28867
- viewModel.providerTargets
28868
- ]
29779
+ [viewModel.conversationFilter, viewModel.providerTargets]
28869
29780
  );
28870
29781
  const activeAgentProbe = useMemo11(
28871
29782
  () => findWorkspaceAgentProbeForDockProvider(
@@ -28937,7 +29848,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28937
29848
  workspaceAgentProbes?.isLoadingUsage,
28938
29849
  t
28939
29850
  ]);
28940
- useEffect14(() => {
29851
+ useEffect15(() => {
28941
29852
  if (previewMode || !onAgentProbeDemandChange) {
28942
29853
  return;
28943
29854
  }
@@ -28947,7 +29858,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28947
29858
  onAgentProbeDemandChange(null, probeSourceId);
28948
29859
  };
28949
29860
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
28950
- useEffect14(() => {
29861
+ useEffect15(() => {
28951
29862
  if (previewMode || !onAgentProbeDemandChange || !railStatusProvider || railStatusProvider === activeProbeProvider) {
28952
29863
  return;
28953
29864
  }
@@ -28975,17 +29886,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28975
29886
  nodeId,
28976
29887
  kind: "agentGui",
28977
29888
  title: windowTitle,
28978
- titleIcon: windowTitleIconUrl ? /* @__PURE__ */ jsx33(
28979
- "img",
28980
- {
28981
- src: windowTitleIconUrl,
28982
- alt: "",
28983
- draggable: false,
28984
- "aria-hidden": "true",
28985
- className: "size-4 rounded-[4px]",
28986
- "data-agent-gui-window-provider-icon": "true"
28987
- }
28988
- ) : null,
29889
+ titleIcon: null,
28989
29890
  position,
28990
29891
  width,
28991
29892
  height,
@@ -29053,6 +29954,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
29053
29954
  railSlashStatusLimits,
29054
29955
  previewMode,
29055
29956
  onLinkAction: handleLinkAction,
29957
+ onHandoffConversation,
29056
29958
  capabilityMenuState,
29057
29959
  onCapabilitySettingsRequest,
29058
29960
  onAgentProviderLogin: onAgentProviderLogin ? handleAgentProviderLogin : void 0,
@@ -29137,6 +30039,7 @@ export {
29137
30039
  getAgentActivityRuntime,
29138
30040
  getAgentCustomMentionKind,
29139
30041
  getOptionalAgentActivityRuntime,
30042
+ localAgentGUIAgentTargetId,
29140
30043
  localAgentGUIProviderTargetId,
29141
30044
  normalizeAgentGUIProviderTargets,
29142
30045
  preloadAgentMentionBrowse,