@tutti-os/agent-gui 0.0.58 → 0.0.60

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 (102) 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 +5 -5
  5. package/dist/agent-conversation/index.js +7 -7
  6. package/dist/agent-message-center/index.d.ts +2 -2
  7. package/dist/agent-message-center/index.js +17 -11
  8. package/dist/agent-message-center/index.js.map +1 -1
  9. package/dist/{agentConversationVM-Qbz9GBwR.d.ts → agentConversationVM-DPAgUJlR.d.ts} +1 -1
  10. package/dist/{agentGuiNodeTypes-BRU6P22B.d.ts → agentGuiNodeTypes-CC52zXAV.d.ts} +9 -6
  11. package/dist/app/renderer/agentactivity.css +533 -56
  12. package/dist/app/renderer/assets/icons/@-bold-lined.svg +10 -0
  13. package/dist/app/renderer/assets/icons/@-lined.svg +10 -0
  14. package/dist/app/renderer/assets/icons/add-lined-bold.svg +3 -0
  15. package/dist/app/renderer/assets/icons/add-lined-icon.svg +3 -0
  16. package/dist/app/renderer/assets/icons/add-lined.svg +3 -0
  17. package/dist/app/renderer/assets/icons/agents/claudecode-flat-filled.svg +10 -0
  18. package/dist/app/renderer/assets/icons/agents/codex-flat-filled.svg +10 -0
  19. package/dist/app/renderer/assets/icons/agents/provider-rail-claude-code-colorful.png +0 -0
  20. package/dist/app/renderer/assets/icons/agents/provider-rail-codex-colorful.png +0 -0
  21. package/dist/app/renderer/assets/icons/agents/provider-rail-hermes-colorful.png +0 -0
  22. package/dist/app/renderer/assets/icons/agents/provider-rail-tutti.png +0 -0
  23. package/dist/app/renderer/assets/icons/handoff-lined.png +0 -0
  24. package/dist/app/renderer/assets/icons/handoff-lined.svg +11 -0
  25. package/dist/{chunk-5SRRKWE4.js → chunk-24CUBQKJ.js} +2 -2
  26. package/dist/{chunk-NX6T3DDS.js → chunk-2LGUBUEJ.js} +3 -3
  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-N756UO52.js → chunk-AWIZJQXW.js} +68 -65
  34. package/dist/chunk-AWIZJQXW.js.map +1 -0
  35. package/dist/{chunk-SLT5Q37C.js → chunk-B6YDXIZW.js} +5 -3
  36. package/dist/{chunk-SLT5Q37C.js.map → chunk-B6YDXIZW.js.map} +1 -1
  37. package/dist/{chunk-7GM7UQXD.js → chunk-BB2SVMEV.js} +46 -8
  38. package/dist/chunk-BB2SVMEV.js.map +1 -0
  39. package/dist/{chunk-BT5WEZO5.js → chunk-CUMZV32B.js} +5 -5
  40. package/dist/chunk-CUMZV32B.js.map +1 -0
  41. package/dist/{chunk-OFMORNBO.js → chunk-CZSMZRAV.js} +23 -6
  42. package/dist/chunk-CZSMZRAV.js.map +1 -0
  43. package/dist/{chunk-HVU46DDA.js → chunk-FRCIPTUD.js} +13 -2
  44. package/dist/chunk-FRCIPTUD.js.map +1 -0
  45. package/dist/{chunk-CEMXB7LA.js → chunk-I5ZIKJVN.js} +2 -2
  46. package/dist/{chunk-4PSDYKZQ.js → chunk-K3UBSTJ5.js} +12 -9
  47. package/dist/chunk-K3UBSTJ5.js.map +1 -0
  48. package/dist/{chunk-Z2BTIAOC.js → chunk-MPZ3CW5C.js} +1 -1
  49. package/dist/chunk-MPZ3CW5C.js.map +1 -0
  50. package/dist/{chunk-MTFSQWZ6.js → chunk-V4JGVBUN.js} +22 -2
  51. package/dist/chunk-V4JGVBUN.js.map +1 -0
  52. package/dist/{chunk-OQJSZSYB.js → chunk-WNVIKTJK.js} +2 -2
  53. package/dist/{chunk-BEFNWUOZ.js → chunk-YZ3POK7G.js} +374 -316
  54. package/dist/chunk-YZ3POK7G.js.map +1 -0
  55. package/dist/claudecode-flat-filled-NHO4JCVK.svg +10 -0
  56. package/dist/codex-flat-filled-WYHCF5VR.svg +10 -0
  57. package/dist/context-mention-palette/index.js +8 -8
  58. package/dist/handoff-lined-4WQUBVG3.svg +11 -0
  59. package/dist/i18n/index.d.ts +43 -19
  60. package/dist/i18n/index.js +2 -2
  61. package/dist/index.d.ts +42 -18
  62. package/dist/index.js +1512 -494
  63. package/dist/index.js.map +1 -1
  64. package/dist/plan-decision-ops.d.ts +2 -2
  65. package/dist/queued-prompt-runtime.d.ts +4 -4
  66. package/dist/{types-BsHvTjIZ.d.ts → types-DSc2ta3s.d.ts} +1 -1
  67. package/dist/workbench/contribution.d.ts +4 -8
  68. package/dist/workbench/contribution.js +9 -7
  69. package/dist/workbench/index.d.ts +4 -4
  70. package/dist/workbench/index.js +10 -12
  71. package/dist/workbench/launch.d.ts +6 -7
  72. package/dist/workbench/launch.js +2 -4
  73. package/dist/workbench/providerCatalog.d.ts +1 -1
  74. package/dist/workbench/sessionTitle.d.ts +1 -1
  75. package/dist/workbench/sessionTitle.js +3 -3
  76. package/dist/workbench/state.d.ts +1 -1
  77. package/dist/workbench/state.js +2 -2
  78. package/dist/workbench/types.d.ts +3 -1
  79. package/dist/workbench/types.js +1 -1
  80. package/dist/workspace-agent-generated-files.d.ts +1 -1
  81. package/dist/workspace-agent-generated-files.js +3 -3
  82. package/dist/{workspaceAgentActivityListViewModel-B5viw5Da.d.ts → workspaceAgentActivityListViewModel-DJvAqZso.d.ts} +1 -0
  83. package/package.json +12 -12
  84. package/dist/@-lined-14px-64O2KKB4.svg +0 -3
  85. package/dist/chunk-4PSDYKZQ.js.map +0 -1
  86. package/dist/chunk-7GM7UQXD.js.map +0 -1
  87. package/dist/chunk-BEFNWUOZ.js.map +0 -1
  88. package/dist/chunk-BT5WEZO5.js.map +0 -1
  89. package/dist/chunk-HVU46DDA.js.map +0 -1
  90. package/dist/chunk-IS6JUDDY.js.map +0 -1
  91. package/dist/chunk-MTFSQWZ6.js.map +0 -1
  92. package/dist/chunk-N756UO52.js.map +0 -1
  93. package/dist/chunk-OFMORNBO.js.map +0 -1
  94. package/dist/chunk-Z2BTIAOC.js.map +0 -1
  95. /package/dist/{chunk-5SRRKWE4.js.map → chunk-24CUBQKJ.js.map} +0 -0
  96. /package/dist/{chunk-NX6T3DDS.js.map → chunk-2LGUBUEJ.js.map} +0 -0
  97. /package/dist/{chunk-UCCUIUGK.js.map → chunk-4OPTXOOZ.js.map} +0 -0
  98. /package/dist/{chunk-Q75AK47T.js.map → chunk-5WB3NGIN.js.map} +0 -0
  99. /package/dist/{chunk-2WUDORCV.js.map → chunk-6TEPDMX6.js.map} +0 -0
  100. /package/dist/{chunk-OLI2A3EM.js.map → chunk-74TIEA6X.js.map} +0 -0
  101. /package/dist/{chunk-CEMXB7LA.js.map → chunk-I5ZIKJVN.js.map} +0 -0
  102. /package/dist/{chunk-OQJSZSYB.js.map → chunk-WNVIKTJK.js.map} +0 -0
package/dist/index.js CHANGED
@@ -9,20 +9,21 @@ 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,
18
19
  localAgentGUIProviderTargetId,
19
20
  normalizeAgentGUIProviderTargets,
20
21
  resolveAgentGUIProviderTarget
21
- } from "./chunk-7GM7UQXD.js";
22
+ } from "./chunk-BB2SVMEV.js";
22
23
  import {
23
24
  AgentInteractivePromptSurface,
24
25
  approvalOptionDisplayLabel
25
- } from "./chunk-OFMORNBO.js";
26
+ } from "./chunk-CZSMZRAV.js";
26
27
  import {
27
28
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
28
29
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -41,7 +42,7 @@ import {
41
42
  resolveAgentGUIExplicitConversationTitle,
42
43
  resolveAgentGUIProviderDisplayLabel,
43
44
  resolveAgentGUIProviderIdentity
44
- } from "./chunk-UCCUIUGK.js";
45
+ } from "./chunk-4OPTXOOZ.js";
45
46
  import {
46
47
  AgentConversationFlow,
47
48
  Button,
@@ -62,14 +63,14 @@ import {
62
63
  skillTriggerForPrefix,
63
64
  toLocalShortDateTime,
64
65
  useProjectedAgentConversation
65
- } from "./chunk-BEFNWUOZ.js";
66
+ } from "./chunk-YZ3POK7G.js";
66
67
  import {
67
68
  AgentMessageMarkdown,
68
69
  AgentTargetPresentationProvider,
69
70
  ZoomableImage,
70
71
  cn,
71
72
  resolveWorkspaceLinkAction
72
- } from "./chunk-SLT5Q37C.js";
73
+ } from "./chunk-B6YDXIZW.js";
73
74
  import {
74
75
  openAgentEnvPanel
75
76
  } from "./chunk-PSLAWU25.js";
@@ -80,7 +81,7 @@ import {
80
81
  DEFAULT_AGENT_MENTION_FILTER,
81
82
  agentMentionItemKey,
82
83
  preloadAgentMentionBrowse
83
- } from "./chunk-BT5WEZO5.js";
84
+ } from "./chunk-CUMZV32B.js";
84
85
  import {
85
86
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
86
87
  buildWorkspaceAgentActivityListViewModel,
@@ -90,10 +91,10 @@ import {
90
91
  isWorkspaceAgentUntitledTask,
91
92
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
92
93
  selectWorkspaceAgentActivityOverlayMessages
93
- } from "./chunk-CEMXB7LA.js";
94
+ } from "./chunk-I5ZIKJVN.js";
94
95
  import {
95
96
  Spinner
96
- } from "./chunk-OLI2A3EM.js";
97
+ } from "./chunk-74TIEA6X.js";
97
98
  import {
98
99
  resolveWorkspaceAgentSessionSortTimeUnixMs
99
100
  } from "./chunk-IBIMGLCD.js";
@@ -104,7 +105,7 @@ import {
104
105
  mentionItemToAttrs,
105
106
  normalizeAgentSessionMentionTitle,
106
107
  parseMentionItemFromHref
107
- } from "./chunk-NX6T3DDS.js";
108
+ } from "./chunk-2LGUBUEJ.js";
108
109
  import "./chunk-Y35GDLP2.js";
109
110
  import "./chunk-LUGELG5V.js";
110
111
  import {
@@ -112,6 +113,7 @@ import {
112
113
  AgentActivityRuntimeProvider,
113
114
  MANAGED_AGENT_ICON_FALLBACK_URL,
114
115
  MANAGED_AGENT_ICON_URLS,
116
+ MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS,
115
117
  getAgentActivityRuntime,
116
118
  getAgentCustomMentionKind,
117
119
  getOptionalAgentActivityRuntime,
@@ -126,7 +128,7 @@ import {
126
128
  useAgentHostApi,
127
129
  useOptionalAgentActivityRuntime,
128
130
  useOptionalAgentHostApi
129
- } from "./chunk-HVU46DDA.js";
131
+ } from "./chunk-FRCIPTUD.js";
130
132
  import "./chunk-TYGL25EL.js";
131
133
  import {
132
134
  AgentGuiI18nProvider,
@@ -134,10 +136,10 @@ import {
134
136
  agentGuiI18nResources,
135
137
  translate,
136
138
  useTranslation
137
- } from "./chunk-5SRRKWE4.js";
139
+ } from "./chunk-24CUBQKJ.js";
138
140
  import "./chunk-PJP5BUU6.js";
139
- import "./chunk-MTFSQWZ6.js";
140
- import "./chunk-IS6JUDDY.js";
141
+ import "./chunk-V4JGVBUN.js";
142
+ import "./chunk-6VVBG4BF.js";
141
143
  import {
142
144
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
143
145
  } from "./chunk-JM24HADP.js";
@@ -310,7 +312,7 @@ import { memo as memo3 } from "react";
310
312
  import { TooltipProvider as TooltipProvider3 } from "@tutti-os/ui-system";
311
313
 
312
314
  // agent-gui/agentGuiNode/AgentGUINode.tsx
313
- import { memo as memo2, useCallback as useCallback12, useEffect as useEffect14, useMemo as useMemo11 } from "react";
315
+ import { memo as memo2, useCallback as useCallback12, useEffect as useEffect15, useMemo as useMemo11 } from "react";
314
316
  import { createWorkspaceUserProjectI18nRuntime } from "@tutti-os/workspace-user-project/i18n";
315
317
  import { createWorkspaceFileManagerI18nRuntime } from "@tutti-os/workspace-file-manager";
316
318
 
@@ -4903,6 +4905,13 @@ function conversationFilterKey(filter, provider) {
4903
4905
  }
4904
4906
  return `agent-target:${normalized.agentTargetId}`;
4905
4907
  }
4908
+ function conversationRetainableForQueryFilter(conversation, filter) {
4909
+ if (!conversation || !filter || filter.kind !== "agentTarget") {
4910
+ return true;
4911
+ }
4912
+ const agentTargetId = conversation.agentTargetId?.trim() ?? "";
4913
+ return agentTargetId.length === 0 || agentTargetId === filter.agentTargetId;
4914
+ }
4906
4915
  function createAgentGUIConversationListQueryKey(input) {
4907
4916
  const normalized = normalizeQuery(input);
4908
4917
  if (!normalized) {
@@ -5703,24 +5712,53 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5703
5712
  ...dirtySessionIds,
5704
5713
  ...baseConversations.map((conversation) => conversation.id)
5705
5714
  ]) : null;
5706
- const retainedSessionIds = new Set(retainedSnapshotSessionIds);
5715
+ const currentConversationsById = new Map(
5716
+ currentConversations.map((conversation) => [
5717
+ conversation.id,
5718
+ conversation
5719
+ ])
5720
+ );
5721
+ const snapshotSessionAgentTargetIdById = new Map(
5722
+ workspaceAgentSnapshot.sessions.flatMap((session) => {
5723
+ const agentSessionId = session.agentSessionId.trim();
5724
+ const agentTargetId = session.agentTargetId?.trim() ?? "";
5725
+ return agentSessionId && agentTargetId ? [[agentSessionId, agentTargetId]] : [];
5726
+ })
5727
+ );
5728
+ const retainableForQueryFilter = (agentSessionId) => {
5729
+ const filter = state.query.conversationFilter;
5730
+ if (!filter || filter.kind !== "agentTarget") {
5731
+ return true;
5732
+ }
5733
+ const snapshotAgentTargetId = snapshotSessionAgentTargetIdById.get(agentSessionId);
5734
+ if (snapshotAgentTargetId) {
5735
+ return snapshotAgentTargetId === filter.agentTargetId;
5736
+ }
5737
+ return conversationRetainableForQueryFilter(
5738
+ currentConversationsById.get(agentSessionId),
5739
+ filter
5740
+ );
5741
+ };
5742
+ const retainedSessionIds = new Set(
5743
+ [...retainedSnapshotSessionIds].filter(retainableForQueryFilter)
5744
+ );
5707
5745
  if (reason === "workspace-agent-update") {
5708
5746
  for (const conversation of currentConversations) {
5709
- if (!nextDeletedConversationIds.has(conversation.id)) {
5747
+ if (!nextDeletedConversationIds.has(conversation.id) && retainableForQueryFilter(conversation.id)) {
5710
5748
  retainedSessionIds.add(conversation.id);
5711
5749
  }
5712
5750
  }
5713
5751
  }
5714
5752
  if (retainedSnapshotSessionIds.size > 0) {
5715
5753
  for (const agentSessionId of localCreatedConversationIds) {
5716
- if (!nextDeletedConversationIds.has(agentSessionId)) {
5754
+ if (!nextDeletedConversationIds.has(agentSessionId) && retainableForQueryFilter(agentSessionId)) {
5717
5755
  retainedSessionIds.add(agentSessionId);
5718
5756
  }
5719
5757
  }
5720
5758
  }
5721
5759
  if (canApplyDirtySessionProjection) {
5722
5760
  for (const conversation of currentConversations) {
5723
- if (!nextDeletedConversationIds.has(conversation.id)) {
5761
+ if (!nextDeletedConversationIds.has(conversation.id) && retainableForQueryFilter(conversation.id)) {
5724
5762
  retainedSessionIds.add(conversation.id);
5725
5763
  }
5726
5764
  }
@@ -6617,6 +6655,28 @@ function nodeDataFromComposerSettings(current, settings) {
6617
6655
  };
6618
6656
  }
6619
6657
 
6658
+ // agent-gui/agentGuiNode/controller/agentGuiController.sessionHelpers.ts
6659
+ function mergeAgentSessionControlStateSnapshot(current, snapshot3) {
6660
+ const incomingUsage = recordValue2(snapshot3.runtimeContext?.usage);
6661
+ if (incomingUsage || !current) {
6662
+ return snapshot3;
6663
+ }
6664
+ const previousUsage = recordValue2(current.runtimeContext?.usage);
6665
+ if (!previousUsage) {
6666
+ return snapshot3;
6667
+ }
6668
+ return {
6669
+ ...snapshot3,
6670
+ runtimeContext: {
6671
+ ...snapshot3.runtimeContext ?? {},
6672
+ usage: previousUsage
6673
+ }
6674
+ };
6675
+ }
6676
+ function recordValue2(value) {
6677
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
6678
+ }
6679
+
6620
6680
  // agent-gui/agentGuiNode/controller/useAgentGUINodeController.ts
6621
6681
  var EMPTY_AGENT_GUI_MESSAGES = [];
6622
6682
  var EMPTY_AGENT_GUI_AVAILABLE_COMMANDS = [];
@@ -6789,6 +6849,30 @@ function reportAgentGUIRuntimeError(input) {
6789
6849
  } catch {
6790
6850
  }
6791
6851
  }
6852
+ function reportAgentGUIConversationFilterTargetUnresolved(input) {
6853
+ const reportDiagnostic = input.runtime.reportDiagnostic;
6854
+ if (!reportDiagnostic) {
6855
+ return;
6856
+ }
6857
+ try {
6858
+ void Promise.resolve(
6859
+ reportDiagnostic.call(input.runtime, {
6860
+ details: {
6861
+ provider: input.provider,
6862
+ providerTargetCount: input.providerTargetCount,
6863
+ providerTargetId: input.providerTargetId,
6864
+ reason: input.reason
6865
+ },
6866
+ event: "agent.gui.conversation_filter.target_unresolved",
6867
+ level: "warn",
6868
+ source: "agent-gui",
6869
+ workspaceId: input.workspaceId
6870
+ })
6871
+ ).catch(() => {
6872
+ });
6873
+ } catch {
6874
+ }
6875
+ }
6792
6876
  function reportAgentGUIMessagePageDiagnostic(input) {
6793
6877
  const reportDiagnostic = input.runtime.reportDiagnostic;
6794
6878
  if (!reportDiagnostic) {
@@ -7789,7 +7873,7 @@ function hasRejectedApprovalDecision(timelineItems) {
7789
7873
  if (status !== "completed") {
7790
7874
  return false;
7791
7875
  }
7792
- const output = recordValue2(payload.output);
7876
+ const output = recordValue3(payload.output);
7793
7877
  return isRejectedApprovalDecision(output);
7794
7878
  });
7795
7879
  }
@@ -7922,7 +8006,7 @@ function normalizeAgentGUIOpenSessionRequest(request) {
7922
8006
  sequence: request.sequence
7923
8007
  };
7924
8008
  }
7925
- function recordValue2(value) {
8009
+ function recordValue3(value) {
7926
8010
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
7927
8011
  }
7928
8012
  function numberValue(value) {
@@ -7936,7 +8020,7 @@ function numberValue(value) {
7936
8020
  return null;
7937
8021
  }
7938
8022
  function activeBackgroundAgentCount(runtimeContext) {
7939
- const backgroundAgents = recordValue2(runtimeContext?.backgroundAgents);
8023
+ const backgroundAgents = recordValue3(runtimeContext?.backgroundAgents);
7940
8024
  if (!backgroundAgents) {
7941
8025
  return 0;
7942
8026
  }
@@ -7946,7 +8030,7 @@ function activeBackgroundAgentCount(runtimeContext) {
7946
8030
  return count === null ? 0 : Math.max(0, Math.floor(count));
7947
8031
  }
7948
8032
  return items.filter((item) => {
7949
- const record = recordValue2(item);
8033
+ const record = recordValue3(item);
7950
8034
  if (!record) {
7951
8035
  return false;
7952
8036
  }
@@ -7961,7 +8045,7 @@ function activeBackgroundAgentCount(runtimeContext) {
7961
8045
  }).length;
7962
8046
  }
7963
8047
  function appServerStartupMetadata(runtimeContext) {
7964
- return recordValue2(runtimeContext?.appServerStartup);
8048
+ return recordValue3(runtimeContext?.appServerStartup);
7965
8049
  }
7966
8050
  function isAppServerStartupLoading(runtimeContext, key) {
7967
8051
  return appServerStartupMetadata(runtimeContext)?.[key] === "loading";
@@ -7983,6 +8067,24 @@ function modelSelectionFromComposerOptions(options, currentValue) {
7983
8067
  currentValue
7984
8068
  };
7985
8069
  }
8070
+ function configOptionCurrentValue(runtimeContext, ids) {
8071
+ const rawConfigOptions = Array.isArray(runtimeContext?.configOptions) ? runtimeContext.configOptions : [];
8072
+ const idSet = new Set(ids);
8073
+ for (const rawOption of rawConfigOptions) {
8074
+ const option = recordValue3(rawOption);
8075
+ if (!option) {
8076
+ continue;
8077
+ }
8078
+ const id = normalizeOptionalText2(option.id);
8079
+ if (!id || !idSet.has(id)) {
8080
+ continue;
8081
+ }
8082
+ return normalizeOptionalText2(
8083
+ option.currentValue ?? option.current_value
8084
+ );
8085
+ }
8086
+ return null;
8087
+ }
7986
8088
  function reasoningSelectionFromComposerOptions(options, currentValue) {
7987
8089
  if (!options) {
7988
8090
  return null;
@@ -8681,7 +8783,6 @@ function useAgentGUINodeController({
8681
8783
  workspacePath,
8682
8784
  avoidGroupingEdits,
8683
8785
  data,
8684
- conversationScope = "single-provider",
8685
8786
  providerTargets,
8686
8787
  providerTargetsLoading = false,
8687
8788
  providerReadinessGates = null,
@@ -8699,23 +8800,35 @@ function useAgentGUINodeController({
8699
8800
  const agentActivitySnapshot = useAgentActivitySnapshot(workspaceId);
8700
8801
  const normalizedExplicitProviderTargets = useMemo4(
8701
8802
  () => normalizeAgentGUIProviderTargets(providerTargets, {
8702
- fallbackToLocal: false
8803
+ includeDisabledPlaceholders: true,
8804
+ useStaticCatalog: false
8703
8805
  }),
8704
8806
  [providerTargets]
8705
8807
  );
8706
- const normalizedProviderTargets = useMemo4(
8707
- () => providerTargetsLoading ? [] : providerTargets === void 0 ? normalizeAgentGUIProviderTargets(null) : normalizedExplicitProviderTargets,
8708
- [normalizedExplicitProviderTargets, providerTargets, providerTargetsLoading]
8709
- );
8710
- const shouldFallbackToLocalProviderTargets = providerTargets === void 0 && !providerTargetsLoading;
8808
+ const normalizedProviderTargets = useMemo4(() => {
8809
+ if (providerTargetsLoading) {
8810
+ return [];
8811
+ }
8812
+ if (providerTargets === void 0 || normalizedExplicitProviderTargets.length === 0) {
8813
+ return normalizeAgentGUIProviderTargets(null, {
8814
+ includeDisabledPlaceholders: true
8815
+ });
8816
+ }
8817
+ return normalizedExplicitProviderTargets;
8818
+ }, [
8819
+ normalizedExplicitProviderTargets,
8820
+ providerTargets,
8821
+ providerTargetsLoading
8822
+ ]);
8823
+ const shouldUseStaticProviderTargets = !providerTargetsLoading && (providerTargets === void 0 || normalizedExplicitProviderTargets.length === 0);
8711
8824
  const selectedProviderTarget = useMemo4(() => {
8712
8825
  const resolved = resolveAgentGUIProviderTarget({
8713
8826
  agentTargetId: data.agentTargetId,
8714
8827
  defaultProviderTargetId,
8715
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
8716
8828
  provider: data.provider,
8717
8829
  providerTargetId: data.providerTargetId,
8718
- providerTargets: normalizedProviderTargets
8830
+ providerTargets: normalizedProviderTargets,
8831
+ useStaticCatalog: shouldUseStaticProviderTargets
8719
8832
  });
8720
8833
  return resolved ?? {
8721
8834
  targetId: data.agentTargetId ?? "__loading__",
@@ -8733,7 +8846,7 @@ function useAgentGUINodeController({
8733
8846
  data.providerTargetId,
8734
8847
  defaultProviderTargetId,
8735
8848
  normalizedProviderTargets,
8736
- shouldFallbackToLocalProviderTargets
8849
+ shouldUseStaticProviderTargets
8737
8850
  ]);
8738
8851
  const selectedProviderTargetIsExplicit = useMemo4(
8739
8852
  () => normalizedExplicitProviderTargets.some(
@@ -8808,14 +8921,8 @@ function useAgentGUINodeController({
8808
8921
  const [conversationFilter, setConversationFilter] = useState4(
8809
8922
  () => createAgentGUIConversationFilterState().filter
8810
8923
  );
8811
- const canUseConversationTargetFilter = conversationScope === "multi-provider";
8812
- const queryConversationFilter = canUseConversationTargetFilter ? conversationFilter : null;
8813
- useEffect4(() => {
8814
- if (canUseConversationTargetFilter || conversationFilter.kind === "all") {
8815
- return;
8816
- }
8817
- setConversationFilter({ kind: "all" });
8818
- }, [canUseConversationTargetFilter, conversationFilter]);
8924
+ const conversationFilterRef = useRef4(conversationFilter);
8925
+ conversationFilterRef.current = conversationFilter;
8819
8926
  const conversationListQuery = useMemo4(() => {
8820
8927
  const userId = currentUserId?.trim() ?? "";
8821
8928
  const provider = data.provider?.trim() ?? "";
@@ -8823,13 +8930,13 @@ function useAgentGUINodeController({
8823
8930
  return null;
8824
8931
  }
8825
8932
  return {
8826
- ...queryConversationFilter ? { conversationFilter: queryConversationFilter } : {},
8933
+ conversationFilter,
8827
8934
  workspaceId,
8828
8935
  userId,
8829
8936
  provider: data.provider,
8830
8937
  sessionOrigin: AGENT_GUI_RUNTIME_SESSION_ORIGIN
8831
8938
  };
8832
- }, [currentUserId, data.provider, queryConversationFilter, workspaceId]);
8939
+ }, [currentUserId, data.provider, conversationFilter, workspaceId]);
8833
8940
  const conversationListState = useAgentGuiConversationList(
8834
8941
  conversationListQuery
8835
8942
  );
@@ -8940,6 +9047,10 @@ function useAgentGUINodeController({
8940
9047
  composerOptions: providerComposerOptions,
8941
9048
  sessionRuntimeContext: activeSessionState?.runtimeContext
8942
9049
  });
9050
+ const goalPauseSupported = resolveAgentActivityCapability2("goalPause", {
9051
+ composerOptions: providerComposerOptions,
9052
+ sessionRuntimeContext: activeSessionState?.runtimeContext
9053
+ }) ?? false;
8943
9054
  const activeSessionRuntimeContext = activeSessionState?.runtimeContext;
8944
9055
  const backgroundAgentCount = useMemo4(
8945
9056
  () => activeBackgroundAgentCount(activeSessionRuntimeContext),
@@ -10191,9 +10302,9 @@ function useAgentGUINodeController({
10191
10302
  ...sessionStateSnapshotCauseBySessionIdRef.current,
10192
10303
  [agentSessionId]: cause ? { source: cause.source } : void 0
10193
10304
  };
10194
- setAgentSessionViewControlState(
10305
+ updateAgentSessionViewControlState(
10195
10306
  sessionViewRef(agentSessionId),
10196
- snapshot3
10307
+ (current) => mergeAgentSessionControlStateSnapshot(current, snapshot3)
10197
10308
  );
10198
10309
  } catch (error) {
10199
10310
  if (!isMountedRef.current || cause?.allowInactive !== true && activeConversationIdRef.current !== agentSessionId) {
@@ -11669,14 +11780,25 @@ function useAgentGUINodeController({
11669
11780
  activatedConversationIdsRef.current.add(conversation2.id);
11670
11781
  setTransientConversation(conversation2);
11671
11782
  if (conversationListQuery) {
11783
+ const createdAgentTargetId = normalizeOptionalText2(conversation2.agentTargetId) ?? targetData.agentTargetId;
11784
+ const currentQueryFilter = conversationListQuery.conversationFilter;
11785
+ const filterExcludesCreatedConversation = currentQueryFilter?.kind === "agentTarget" && currentQueryFilter.agentTargetId !== (createdAgentTargetId ?? "");
11786
+ const createdConversationFilter = createdAgentTargetId ? { kind: "agentTarget", agentTargetId: createdAgentTargetId } : { kind: "all" };
11787
+ const createdConversationQuery = filterExcludesCreatedConversation ? {
11788
+ ...conversationListQuery,
11789
+ conversationFilter: createdConversationFilter
11790
+ } : conversationListQuery;
11672
11791
  upsertLocalCreatedAgentGUIConversation({
11673
- query: conversationListQuery,
11792
+ query: createdConversationQuery,
11674
11793
  conversation: conversation2
11675
11794
  });
11676
11795
  scheduleAgentGUIConversationListProjection(
11677
- conversationListQuery,
11796
+ createdConversationQuery,
11678
11797
  "local-create"
11679
11798
  );
11799
+ if (filterExcludesCreatedConversation) {
11800
+ setConversationFilter(createdConversationFilter);
11801
+ }
11680
11802
  }
11681
11803
  setAgentSessionViewMessagesLoading(
11682
11804
  sessionViewRef(conversation2.id),
@@ -11850,12 +11972,27 @@ function useAgentGUINodeController({
11850
11972
  setIsLoadingMessages(false);
11851
11973
  setDetailError(null);
11852
11974
  persistActiveConversation(null);
11975
+ const filter = conversationFilterRef.current;
11976
+ if (filter.kind === "agentTarget") {
11977
+ const filterTarget = resolveAgentGUIProviderTarget({
11978
+ agentTargetId: filter.agentTargetId,
11979
+ defaultProviderTargetId,
11980
+ provider: dataRef.current.provider,
11981
+ providerTargets: normalizedProviderTargets,
11982
+ useStaticCatalog: false
11983
+ });
11984
+ if (filterTarget && filterTarget.disabled !== true && (filterTarget.agentTargetId?.trim() ?? "") === filter.agentTargetId) {
11985
+ setHomeComposerTargetOverride(filterTarget);
11986
+ }
11987
+ }
11853
11988
  loadDraftComposerOptions();
11854
11989
  },
11855
11990
  [
11856
11991
  activation,
11857
11992
  agentActivityRuntime,
11993
+ defaultProviderTargetId,
11858
11994
  loadDraftComposerOptions,
11995
+ normalizedProviderTargets,
11859
11996
  persistActiveConversation,
11860
11997
  workspaceId
11861
11998
  ]
@@ -11898,13 +12035,12 @@ function useAgentGUINodeController({
11898
12035
  setActiveConversationId(null);
11899
12036
  setIsLoadingMessages(false);
11900
12037
  setDetailError(null);
11901
- const targetData = selectedComposerTargetDataRef.current;
12038
+ const selectedTargetData = selectedComposerTargetDataRef.current;
12039
+ const targetProvider = prefillPromptRequest.provider ?? selectedTargetData.provider;
12040
+ const targetAgentTargetId = prefillPromptRequest.agentTargetId ?? selectedTargetData.agentTargetId;
11902
12041
  setDraftBySessionId((current) => ({
11903
12042
  ...current,
11904
- [nodeDefaultDraftContentKey(
11905
- targetData.provider,
11906
- targetData.agentTargetId
11907
- )]: {
12043
+ [nodeDefaultDraftContentKey(targetProvider, targetAgentTargetId)]: {
11908
12044
  ...emptyAgentComposerDraft(),
11909
12045
  prompt: draftPrompt2
11910
12046
  }
@@ -12425,6 +12561,36 @@ function useAgentGUINodeController({
12425
12561
  shouldQueuePromptLocally
12426
12562
  ]
12427
12563
  );
12564
+ const goalControl = useCallback4(
12565
+ (action, objective) => {
12566
+ if (previewMode) {
12567
+ return;
12568
+ }
12569
+ const agentSessionId = activeConversationIdRef.current;
12570
+ if (!agentSessionId) {
12571
+ return;
12572
+ }
12573
+ setDetailError(null);
12574
+ void agentActivityRuntime.goalControl({
12575
+ workspaceId,
12576
+ agentSessionId,
12577
+ action,
12578
+ ...objective !== void 0 ? { objective } : {}
12579
+ }).catch((error) => {
12580
+ if (!isCurrentConversation(agentSessionId)) {
12581
+ return;
12582
+ }
12583
+ setDetailError(getAgentGUIErrorMessage(error));
12584
+ });
12585
+ },
12586
+ [
12587
+ agentActivityRuntime,
12588
+ isCurrentConversation,
12589
+ previewMode,
12590
+ setDetailError,
12591
+ workspaceId
12592
+ ]
12593
+ );
12428
12594
  const submitPrompt = useCallback4(
12429
12595
  (content, displayPrompt) => {
12430
12596
  if (previewMode) {
@@ -12786,10 +12952,12 @@ function useAgentGUINodeController({
12786
12952
  }).then((result) => {
12787
12953
  const queuedUpdate = queuedComposerSettingsUpdatesRef.current[agentSessionId] ?? null;
12788
12954
  const optimisticSettings = queuedUpdate?.sessionSettingsPatch ?? null;
12789
- const nextAppliedSettings = optimisticSettings ? {
12955
+ const pendingClaudeModelRefreshSettings = dataRef.current.provider === "claude-code" && sessionSettingsPatch.model !== void 0 ? { model: sessionSettingsPatch.model } : null;
12956
+ const nextAppliedSettings = {
12790
12957
  ...result.settings,
12791
- ...optimisticSettings
12792
- } : result.settings;
12958
+ ...pendingClaudeModelRefreshSettings ?? {},
12959
+ ...optimisticSettings ?? {}
12960
+ };
12793
12961
  updateAgentSessionViewControlState(
12794
12962
  sessionViewRef(agentSessionId),
12795
12963
  (existing) => existing ? {
@@ -13677,6 +13845,66 @@ function useAgentGUINodeController({
13677
13845
  userProjects,
13678
13846
  workspacePath
13679
13847
  ]);
13848
+ useEffect4(() => {
13849
+ if (previewMode || providerTargetsLoading || !activeConversationId) {
13850
+ return;
13851
+ }
13852
+ const summary = resolveConversationSummaryById(
13853
+ conversations,
13854
+ activeConversationId,
13855
+ transientConversationRef.current
13856
+ );
13857
+ if (!summary || summary.provider === "unknown") {
13858
+ return;
13859
+ }
13860
+ const summaryAgentTargetId = normalizeOptionalText2(summary.agentTargetId);
13861
+ const providerMismatch = dataRef.current.provider !== summary.provider;
13862
+ const agentTargetMismatch = summaryAgentTargetId !== null && normalizeOptionalText2(dataRef.current.agentTargetId) !== summaryAgentTargetId;
13863
+ if (!providerMismatch && !agentTargetMismatch) {
13864
+ return;
13865
+ }
13866
+ const sessionTarget = resolveAgentGUIProviderTarget({
13867
+ agentTargetId: summaryAgentTargetId,
13868
+ defaultProviderTargetId,
13869
+ provider: summary.provider,
13870
+ providerTargets: normalizedProviderTargets,
13871
+ useStaticCatalog: shouldUseStaticProviderTargets
13872
+ });
13873
+ if (!sessionTarget || sessionTarget.provider !== summary.provider) {
13874
+ return;
13875
+ }
13876
+ if (!providerMismatch && summaryAgentTargetId !== null && (sessionTarget.agentTargetId?.trim() ?? "") !== summaryAgentTargetId) {
13877
+ return;
13878
+ }
13879
+ setHomeComposerTargetOverride(null);
13880
+ const sessionTargetIsExplicit = normalizedExplicitProviderTargets.some(
13881
+ (target) => target.provider === sessionTarget.provider && target.targetId === sessionTarget.targetId && agentGUIProviderTargetRefsEqual(target.ref, sessionTarget.ref)
13882
+ );
13883
+ onDataChangeRef.current((current) => {
13884
+ const targetData = composerTargetDataFromProviderTarget({
13885
+ current,
13886
+ isExplicit: sessionTargetIsExplicit,
13887
+ target: sessionTarget
13888
+ });
13889
+ if (current.provider === targetData.provider && normalizeOptionalText2(current.agentTargetId) === targetData.agentTargetId && (current.providerTargetId ?? null) === targetData.providerTargetId && agentGUIProviderTargetRefsEqual(
13890
+ current.providerTargetRef,
13891
+ targetData.providerTargetRef
13892
+ )) {
13893
+ return current;
13894
+ }
13895
+ dataRef.current = targetData.data;
13896
+ return targetData.data;
13897
+ });
13898
+ }, [
13899
+ activeConversationId,
13900
+ conversations,
13901
+ defaultProviderTargetId,
13902
+ normalizedExplicitProviderTargets,
13903
+ normalizedProviderTargets,
13904
+ previewMode,
13905
+ providerTargetsLoading,
13906
+ shouldUseStaticProviderTargets
13907
+ ]);
13680
13908
  const visibleConversationsRef = useRef4(
13681
13909
  null
13682
13910
  );
@@ -13999,7 +14227,8 @@ function useAgentGUINodeController({
13999
14227
  )
14000
14228
  });
14001
14229
  const draftSettings = activeConversationId ? sessionSettings ?? defaultConversationDraftSettings : homeComposerSettings;
14002
- const draftModel = normalizeOptionalText2(draftSettings.model);
14230
+ const liveConfigModel = activeConversationId !== null ? configOptionCurrentValue(activeSessionRuntimeContext, ["model"]) : null;
14231
+ const draftModel = liveConfigModel ?? normalizeOptionalText2(draftSettings.model);
14003
14232
  const draftReasoningEffort = normalizeOptionalText2(
14004
14233
  draftSettings.reasoningEffort
14005
14234
  );
@@ -14262,15 +14491,11 @@ function useAgentGUINodeController({
14262
14491
  const stableComposerSettings = useStableComposerSettingsVM(composerSettings);
14263
14492
  const updateConversationFilter = useCallback4(
14264
14493
  (filter) => {
14265
- if (!canUseConversationTargetFilter) {
14266
- setConversationFilter({ kind: "all" });
14267
- return;
14268
- }
14269
14494
  setConversationFilter(normalizeAgentGUIConversationFilter(filter));
14270
14495
  },
14271
- [canUseConversationTargetFilter]
14496
+ []
14272
14497
  );
14273
- const selectProvider = useCallback4(
14498
+ const selectHomeComposerAgentTarget = useCallback4(
14274
14499
  (input) => {
14275
14500
  if (previewMode) {
14276
14501
  return;
@@ -14278,17 +14503,14 @@ function useAgentGUINodeController({
14278
14503
  const nextProvider = input.provider;
14279
14504
  const nextTarget = resolveAgentGUIProviderTarget({
14280
14505
  defaultProviderTargetId,
14281
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
14282
14506
  provider: nextProvider,
14283
14507
  providerTargetId: input.providerTargetId,
14284
- providerTargets: normalizedProviderTargets
14508
+ providerTargets: normalizedProviderTargets,
14509
+ useStaticCatalog: shouldUseStaticProviderTargets
14285
14510
  });
14286
14511
  if (!nextTarget) {
14287
14512
  return;
14288
14513
  }
14289
- if (nextTarget.disabled === true) {
14290
- return;
14291
- }
14292
14514
  const nextTargetIsExplicit = normalizedExplicitProviderTargets.some(
14293
14515
  (target) => target.provider === nextTarget.provider && target.targetId === nextTarget.targetId && agentGUIProviderTargetRefsEqual(target.ref, nextTarget.ref)
14294
14516
  );
@@ -14332,7 +14554,9 @@ function useAgentGUINodeController({
14332
14554
  dataRef.current = nextData;
14333
14555
  return nextData;
14334
14556
  });
14335
- loadComposerOptionsForTarget(nextTargetData, { force: true });
14557
+ if (nextTarget.disabled !== true) {
14558
+ loadComposerOptionsForTarget(nextTargetData, { force: true });
14559
+ }
14336
14560
  },
14337
14561
  [
14338
14562
  activation,
@@ -14342,43 +14566,55 @@ function useAgentGUINodeController({
14342
14566
  normalizedProviderTargets,
14343
14567
  persistActiveConversation,
14344
14568
  previewMode,
14345
- shouldFallbackToLocalProviderTargets
14569
+ shouldUseStaticProviderTargets
14346
14570
  ]
14347
14571
  );
14348
14572
  const selectConversationFilterTarget = useCallback4(
14349
14573
  (input) => {
14350
- if (!canUseConversationTargetFilter) {
14351
- setConversationFilter({ kind: "all" });
14352
- return;
14353
- }
14354
14574
  const nextTarget = resolveAgentGUIProviderTarget({
14355
14575
  defaultProviderTargetId,
14356
- fallbackToLocal: shouldFallbackToLocalProviderTargets,
14357
14576
  provider: input.provider,
14358
14577
  providerTargetId: input.providerTargetId,
14359
- providerTargets: normalizedProviderTargets
14578
+ providerTargets: normalizedProviderTargets,
14579
+ useStaticCatalog: shouldUseStaticProviderTargets
14360
14580
  });
14361
14581
  if (!nextTarget || nextTarget.disabled === true) {
14582
+ reportAgentGUIConversationFilterTargetUnresolved({
14583
+ provider: input.provider,
14584
+ providerTargetId: input.providerTargetId ?? null,
14585
+ providerTargetCount: normalizedProviderTargets.length,
14586
+ reason: nextTarget ? "disabled" : "unresolved",
14587
+ runtime: agentActivityRuntime,
14588
+ workspaceId
14589
+ });
14362
14590
  return;
14363
14591
  }
14364
14592
  const agentTargetId = nextTarget.agentTargetId?.trim() ?? "";
14365
14593
  const nextFilter = agentTargetId ? { kind: "agentTarget", agentTargetId } : { kind: "all" };
14366
14594
  setConversationFilter(nextFilter);
14595
+ if (activeConversationIdRef.current === null) {
14596
+ selectHomeComposerAgentTarget(input);
14597
+ }
14367
14598
  },
14368
14599
  [
14369
- canUseConversationTargetFilter,
14600
+ agentActivityRuntime,
14370
14601
  defaultProviderTargetId,
14371
14602
  normalizedProviderTargets,
14372
- shouldFallbackToLocalProviderTargets
14603
+ selectHomeComposerAgentTarget,
14604
+ shouldUseStaticProviderTargets,
14605
+ workspaceId
14373
14606
  ]
14374
14607
  );
14375
14608
  const stableCreateConversation = useStableControllerEventCallback(createConversation);
14376
- const stableSelectProvider = useStableControllerEventCallback(selectProvider);
14609
+ const stableSelectHomeComposerAgentTarget = useStableControllerEventCallback(
14610
+ selectHomeComposerAgentTarget
14611
+ );
14377
14612
  const stableSelectConversationFilterTarget = useStableControllerEventCallback(
14378
14613
  selectConversationFilterTarget
14379
14614
  );
14380
14615
  const stableSelectConversation = useStableControllerEventCallback(selectConversation);
14381
14616
  const stableSubmitPrompt = useStableControllerEventCallback(submitPrompt);
14617
+ const stableGoalControl = useStableControllerEventCallback(goalControl);
14382
14618
  const stableSubmitGuidancePrompt = useStableControllerEventCallback(submitGuidancePrompt);
14383
14619
  const stableShowPromptImagesUnsupported = useStableControllerEventCallback(
14384
14620
  showPromptImagesUnsupported
@@ -14436,10 +14672,11 @@ function useAgentGUINodeController({
14436
14672
  () => ({
14437
14673
  updateConversationFilter: stableUpdateConversationFilter,
14438
14674
  selectConversationFilterTarget: stableSelectConversationFilterTarget,
14439
- selectProvider: stableSelectProvider,
14675
+ selectHomeComposerAgentTarget: stableSelectHomeComposerAgentTarget,
14440
14676
  createConversation: stableCreateConversation,
14441
14677
  selectConversation: stableSelectConversation,
14442
14678
  submitPrompt: stableSubmitPrompt,
14679
+ goalControl: stableGoalControl,
14443
14680
  submitGuidancePrompt: stableSubmitGuidancePrompt,
14444
14681
  loadOlderConversationMessages: stableLoadOlderConversationMessages,
14445
14682
  showPromptImagesUnsupported: stableShowPromptImagesUnsupported,
@@ -14484,13 +14721,14 @@ function useAgentGUINodeController({
14484
14721
  stableRetryOpenclawGateway,
14485
14722
  stableSelectConversation,
14486
14723
  stableSelectConversationFilterTarget,
14487
- stableSelectProvider,
14724
+ stableSelectHomeComposerAgentTarget,
14488
14725
  stableSendQueuedPromptNext,
14489
14726
  stableSubmitGuidancePrompt,
14490
14727
  stableShowPromptImagesUnsupported,
14491
14728
  stableSubmitApprovalOption,
14492
14729
  stableSubmitInteractivePrompt,
14493
14730
  stableSubmitPrompt,
14731
+ stableGoalControl,
14494
14732
  stableToggleConversationPinned,
14495
14733
  stableUpdateConversationFilter,
14496
14734
  stableUpdateComposerSettings,
@@ -14508,7 +14746,6 @@ function useAgentGUINodeController({
14508
14746
  selectedProviderTarget: effectiveSelectedProviderTarget,
14509
14747
  providerTargets: normalizedProviderTargets,
14510
14748
  providerTargetsLoading,
14511
- conversationScope,
14512
14749
  conversationFilter,
14513
14750
  conversations: visibleConversations,
14514
14751
  userProjects,
@@ -14529,6 +14766,7 @@ function useAgentGUINodeController({
14529
14766
  isRespondingApproval,
14530
14767
  promptImagesSupported,
14531
14768
  compactSupported,
14769
+ goalPauseSupported,
14532
14770
  usage,
14533
14771
  backgroundAgentCount,
14534
14772
  listError,
@@ -14573,7 +14811,6 @@ function useAgentGUINodeController({
14573
14811
  canSubmit,
14574
14812
  canQueueWhileBusy,
14575
14813
  conversation,
14576
- conversationScope,
14577
14814
  conversationFilter,
14578
14815
  conversationDetail,
14579
14816
  controllerActions,
@@ -14589,6 +14826,7 @@ function useAgentGUINodeController({
14589
14826
  openclawGateway,
14590
14827
  promptImagesSupported,
14591
14828
  compactSupported,
14829
+ goalPauseSupported,
14592
14830
  usage,
14593
14831
  backgroundAgentCount,
14594
14832
  isInterrupting,
@@ -14805,19 +15043,19 @@ import {
14805
15043
  Fragment as Fragment7,
14806
15044
  memo,
14807
15045
  useCallback as useCallback10,
14808
- useEffect as useEffect12,
15046
+ useEffect as useEffect13,
14809
15047
  useLayoutEffect as useLayoutEffect4,
14810
15048
  useMemo as useMemo10,
14811
15049
  useRef as useRef12,
14812
- useState as useState11
15050
+ useState as useState12
14813
15051
  } from "react";
14814
15052
  import { useSnapshot } from "valtio";
14815
15053
  import { proxy as proxy2 } from "valtio/vanilla";
14816
15054
  import {
14817
15055
  ChevronRight as ChevronRight2,
15056
+ ChevronsDown,
14818
15057
  ExternalLink,
14819
15058
  Info as Info2,
14820
- LayoutGrid,
14821
15059
  Wrench
14822
15060
  } from "lucide-react";
14823
15061
 
@@ -14889,6 +15127,10 @@ import {
14889
15127
  TooltipContent as TooltipContent3,
14890
15128
  TooltipProvider as TooltipProvider2,
14891
15129
  TooltipTrigger as TooltipTrigger3,
15130
+ Select as Select3,
15131
+ SelectContent as SelectContent3,
15132
+ SelectItem as SelectItem3,
15133
+ SelectTrigger as SelectTrigger3,
14892
15134
  NewWorkspaceLinedIcon as NewWorkspaceLinedIcon2,
14893
15135
  ConfirmationDialog,
14894
15136
  toastVariants,
@@ -15568,7 +15810,9 @@ var styles2 = {
15568
15810
  chromeActions: "agent-gui-chrome__actions",
15569
15811
  chromeMetaRow: "agent-gui-chrome__meta-row",
15570
15812
  chromeDangerGhostButton: "agent-gui-chrome__danger-ghost-button",
15571
- chromeGoalHint: "agent-gui-chrome__goal-hint"
15813
+ chromeGoalHint: "agent-gui-chrome__goal-hint",
15814
+ chromeGoalActions: "agent-gui-chrome__goal-actions",
15815
+ chromeGoalEditInput: "agent-gui-chrome__goal-edit-input"
15572
15816
  };
15573
15817
  var AgentGUIChrome_styles_default = styles2;
15574
15818
 
@@ -15769,8 +16013,15 @@ function AgentSessionChrome({
15769
16013
  }
15770
16014
 
15771
16015
  // agent-gui/agentGuiNode/AgentGoalBanner.tsx
15772
- import { Target } from "lucide-react";
16016
+ import { useEffect as useEffect6, useState as useState5 } from "react";
16017
+ import { CirclePause, CirclePlay, Pencil, Target, Trash2 } from "lucide-react";
15773
16018
  import { jsx as jsx20, jsxs as jsxs8 } from "react/jsx-runtime";
16019
+ var RESUMABLE_GOAL_STATUSES = /* @__PURE__ */ new Set([
16020
+ "paused",
16021
+ "blocked",
16022
+ "usagelimited",
16023
+ "budgetlimited"
16024
+ ]);
15774
16025
  var TERMINAL_GOAL_STATUSES = /* @__PURE__ */ new Set(["complete", "completed", "done"]);
15775
16026
  function normalizeGoalStatus(status) {
15776
16027
  return (status ?? "").trim().toLowerCase();
@@ -15781,49 +16032,98 @@ function isGoalBannerVisible(objective, status) {
15781
16032
  }
15782
16033
  return !TERMINAL_GOAL_STATUSES.has(normalizeGoalStatus(status));
15783
16034
  }
15784
- function goalStatusLabel(status, labels) {
16035
+ function goalStatusTitle(status, labels) {
15785
16036
  switch (normalizeGoalStatus(status)) {
15786
16037
  case "paused":
15787
- return labels.statusPaused;
16038
+ return labels.titlePaused;
15788
16039
  case "blocked":
15789
- return labels.statusBlocked;
16040
+ return labels.titleBlocked;
15790
16041
  case "usagelimited":
15791
- return labels.statusUsageLimited;
16042
+ return labels.titleUsageLimited;
15792
16043
  case "budgetlimited":
15793
- return labels.statusBudgetLimited;
16044
+ return labels.titleBudgetLimited;
15794
16045
  case "complete":
15795
16046
  case "completed":
15796
16047
  case "done":
15797
- return labels.statusComplete;
16048
+ return labels.titleComplete;
15798
16049
  default:
15799
- return labels.statusActive;
16050
+ return labels.titleActive;
16051
+ }
16052
+ }
16053
+ function formatGoalElapsed(totalSeconds) {
16054
+ const seconds = Math.max(0, Math.floor(totalSeconds));
16055
+ if (seconds < 60) {
16056
+ return `${seconds}s`;
16057
+ }
16058
+ const minutes = Math.floor(seconds / 60);
16059
+ if (minutes < 60) {
16060
+ const rest = seconds % 60;
16061
+ return rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`;
15800
16062
  }
16063
+ const hours = Math.floor(minutes / 60);
16064
+ const restMinutes = minutes % 60;
16065
+ return restMinutes > 0 ? `${hours}h ${restMinutes}m` : `${hours}h`;
15801
16066
  }
15802
16067
  function describeGoal(input) {
15803
- const trimmedObjective = input.objective.trim();
15804
- const detailParts = [goalStatusLabel(input.status, input.labels)];
16068
+ const detailParts = [input.objective.trim()];
16069
+ if (typeof input.elapsedSeconds === "number") {
16070
+ detailParts.push(formatGoalElapsed(input.elapsedSeconds));
16071
+ }
15805
16072
  if (typeof input.tokenBudget === "number" && input.tokenBudget > 0) {
15806
16073
  const used = typeof input.tokensUsed === "number" && input.tokensUsed >= 0 ? input.tokensUsed : 0;
15807
16074
  detailParts.push(input.labels.budgetUsage(used, input.tokenBudget));
15808
16075
  }
15809
- return `${trimmedObjective} \xB7 ${detailParts.join(" \xB7 ")}`;
16076
+ return detailParts.join(" \xB7 ");
15810
16077
  }
15811
16078
  function AgentGoalBanner({
15812
16079
  objective,
15813
16080
  status,
15814
16081
  tokenBudget,
15815
16082
  tokensUsed,
15816
- labels
16083
+ timeUsedSeconds,
16084
+ labels,
16085
+ onEditObjective,
16086
+ onPauseGoal,
16087
+ onResumeGoal,
16088
+ onClearGoal
15817
16089
  }) {
15818
16090
  "use memo";
16091
+ const [editDraft, setEditDraft] = useState5(null);
16092
+ const normalizedStatus = normalizeGoalStatus(status);
16093
+ const isActive = normalizedStatus === "" || normalizedStatus === "active";
16094
+ const serverSeconds = typeof timeUsedSeconds === "number" && timeUsedSeconds >= 0 ? Math.floor(timeUsedSeconds) : null;
16095
+ const [localElapsed, setLocalElapsed] = useState5(0);
16096
+ useEffect6(() => {
16097
+ setLocalElapsed(0);
16098
+ if (!isActive || serverSeconds === null) {
16099
+ return;
16100
+ }
16101
+ const startedAtMs = Date.now();
16102
+ const timer = window.setInterval(() => {
16103
+ setLocalElapsed(Math.floor((Date.now() - startedAtMs) / 1e3));
16104
+ }, 1e3);
16105
+ return () => window.clearInterval(timer);
16106
+ }, [isActive, serverSeconds]);
16107
+ const elapsedSeconds = serverSeconds === null ? null : serverSeconds + (isActive ? localElapsed : 0);
16108
+ const title = goalStatusTitle(status, labels);
15819
16109
  const description = describeGoal({
15820
16110
  objective,
15821
- status,
16111
+ elapsedSeconds,
15822
16112
  tokenBudget,
15823
16113
  tokensUsed,
15824
16114
  labels
15825
16115
  });
15826
- const fullMessage = `${labels.goalLabel} ${description}`;
16116
+ const fullMessage = `${title} ${description}`;
16117
+ const showPause = onPauseGoal !== void 0 && isActive;
16118
+ const showResume = onResumeGoal !== void 0 && RESUMABLE_GOAL_STATUSES.has(normalizedStatus);
16119
+ const hasActions = onEditObjective !== void 0 || showPause || showResume || onClearGoal !== void 0;
16120
+ const commitEdit = () => {
16121
+ const next = (editDraft ?? "").trim();
16122
+ setEditDraft(null);
16123
+ if (next !== "" && next !== objective.trim()) {
16124
+ onEditObjective?.(next);
16125
+ }
16126
+ };
15827
16127
  return /* @__PURE__ */ jsx20("div", { className: AgentGUIChrome_styles_default.sessionChrome, children: /* @__PURE__ */ jsx20(
15828
16128
  "section",
15829
16129
  {
@@ -15833,19 +16133,91 @@ function AgentGoalBanner({
15833
16133
  children: /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeMetaRow, children: [
15834
16134
  /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: [
15835
16135
  /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeIcon, children: /* @__PURE__ */ jsx20(Target, { "aria-hidden": true, className: "size-3.5" }) }),
15836
- /* @__PURE__ */ jsxs8(
16136
+ editDraft !== null ? /* @__PURE__ */ jsx20(
16137
+ "input",
16138
+ {
16139
+ className: AgentGUIChrome_styles_default.chromeGoalEditInput,
16140
+ value: editDraft,
16141
+ autoFocus: true,
16142
+ "aria-label": labels.editAction,
16143
+ "data-testid": "agent-gui-goal-banner-edit-input",
16144
+ onChange: (event) => setEditDraft(event.target.value),
16145
+ onKeyDown: (event) => {
16146
+ if (event.key === "Enter") {
16147
+ event.preventDefault();
16148
+ commitEdit();
16149
+ } else if (event.key === "Escape") {
16150
+ event.preventDefault();
16151
+ setEditDraft(null);
16152
+ }
16153
+ },
16154
+ onBlur: () => setEditDraft(null)
16155
+ }
16156
+ ) : /* @__PURE__ */ jsxs8(
15837
16157
  "p",
15838
16158
  {
15839
16159
  className: cn(AgentGUIChrome_styles_default.chromeMessage, AgentGUIChrome_styles_default.chromeNoticeMessage),
15840
16160
  title: fullMessage,
15841
16161
  children: [
15842
- /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeTitle, children: labels.goalLabel }),
15843
- /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeDescription, children: description })
16162
+ /* @__PURE__ */ jsx20("span", { className: AgentGUIChrome_styles_default.chromeNoticeTitle, children: title }),
16163
+ /* @__PURE__ */ jsx20(
16164
+ "span",
16165
+ {
16166
+ className: AgentGUIChrome_styles_default.chromeNoticeDescription,
16167
+ "data-testid": "agent-gui-goal-banner-description",
16168
+ children: description
16169
+ }
16170
+ )
15844
16171
  ]
15845
16172
  }
15846
16173
  )
15847
16174
  ] }),
15848
- /* @__PURE__ */ jsx20(
16175
+ hasActions ? /* @__PURE__ */ jsxs8("div", { className: AgentGUIChrome_styles_default.chromeGoalActions, children: [
16176
+ onEditObjective !== void 0 && editDraft === null ? /* @__PURE__ */ jsx20(
16177
+ "button",
16178
+ {
16179
+ type: "button",
16180
+ onClick: () => setEditDraft(objective),
16181
+ title: labels.editAction,
16182
+ "aria-label": labels.editAction,
16183
+ "data-testid": "agent-gui-goal-banner-edit",
16184
+ children: /* @__PURE__ */ jsx20(Pencil, { "aria-hidden": true, className: "size-3.5" })
16185
+ }
16186
+ ) : null,
16187
+ showPause ? /* @__PURE__ */ jsx20(
16188
+ "button",
16189
+ {
16190
+ type: "button",
16191
+ onClick: onPauseGoal,
16192
+ title: labels.pauseAction,
16193
+ "aria-label": labels.pauseAction,
16194
+ "data-testid": "agent-gui-goal-banner-pause",
16195
+ children: /* @__PURE__ */ jsx20(CirclePause, { "aria-hidden": true, className: "size-3.5" })
16196
+ }
16197
+ ) : null,
16198
+ showResume ? /* @__PURE__ */ jsx20(
16199
+ "button",
16200
+ {
16201
+ type: "button",
16202
+ onClick: onResumeGoal,
16203
+ title: labels.resumeAction,
16204
+ "aria-label": labels.resumeAction,
16205
+ "data-testid": "agent-gui-goal-banner-resume",
16206
+ children: /* @__PURE__ */ jsx20(CirclePlay, { "aria-hidden": true, className: "size-3.5" })
16207
+ }
16208
+ ) : null,
16209
+ onClearGoal !== void 0 ? /* @__PURE__ */ jsx20(
16210
+ "button",
16211
+ {
16212
+ type: "button",
16213
+ onClick: onClearGoal,
16214
+ title: labels.clearAction,
16215
+ "aria-label": labels.clearAction,
16216
+ "data-testid": "agent-gui-goal-banner-clear",
16217
+ children: /* @__PURE__ */ jsx20(Trash2, { "aria-hidden": true, className: "size-3.5" })
16218
+ }
16219
+ ) : null
16220
+ ] }) : /* @__PURE__ */ jsx20(
15849
16221
  "span",
15850
16222
  {
15851
16223
  className: AgentGUIChrome_styles_default.chromeGoalHint,
@@ -15861,21 +16233,19 @@ function AgentGoalBanner({
15861
16233
  // agent-gui/agentGuiNode/AgentComposer.tsx
15862
16234
  import {
15863
16235
  useCallback as useCallback9,
15864
- useEffect as useEffect11,
16236
+ useEffect as useEffect12,
15865
16237
  useLayoutEffect as useLayoutEffect3,
15866
16238
  useMemo as useMemo9,
15867
16239
  useRef as useRef11,
15868
- useState as useState10
16240
+ useState as useState11
15869
16241
  } from "react";
15870
16242
  import { createPortal as createPortal3, flushSync } from "react-dom";
15871
16243
  import {
15872
- AddIcon,
15873
16244
  Button as Button3,
15874
16245
  Select as Select2,
15875
16246
  SelectContent as SelectContent2,
15876
16247
  SelectItem as SelectItem2,
15877
- SelectTrigger as SelectTrigger2,
15878
- SelectValue
16248
+ SelectTrigger as SelectTrigger2
15879
16249
  } from "@tutti-os/ui-system";
15880
16250
  import { ListChecks as ListChecks2, Target as Target3, X } from "lucide-react";
15881
16251
  import {
@@ -16319,7 +16689,7 @@ function filterUnavailableSlashCommands(commands, input) {
16319
16689
  }
16320
16690
 
16321
16691
  // agent-gui/agentGuiNode/AgentSlashCommandPalette.tsx
16322
- import { Fragment as Fragment3, useEffect as useEffect6, useRef as useRef6 } from "react";
16692
+ import { Fragment as Fragment3, useEffect as useEffect7, useRef as useRef6 } from "react";
16323
16693
  import {
16324
16694
  Globe,
16325
16695
  Info,
@@ -16363,7 +16733,7 @@ function AgentSlashCommandPalette({
16363
16733
  }) {
16364
16734
  "use memo";
16365
16735
  const highlightedOptionRef = useRef6(null);
16366
- useEffect6(() => {
16736
+ useEffect7(() => {
16367
16737
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
16368
16738
  }, [highlightedIndex]);
16369
16739
  if (entries.length === 0) {
@@ -16521,7 +16891,7 @@ function slashPaletteEntryIcon(entry) {
16521
16891
  import {
16522
16892
  useLayoutEffect,
16523
16893
  useRef as useRef7,
16524
- useState as useState5
16894
+ useState as useState6
16525
16895
  } from "react";
16526
16896
  import { ChevronRight } from "lucide-react";
16527
16897
 
@@ -16529,6 +16899,7 @@ import { ChevronRight } from "lucide-react";
16529
16899
  var styles3 = {
16530
16900
  bottomDock: "agent-gui-node__bottom-dock",
16531
16901
  bottomDockPrompt: "agent-gui-node__bottom-dock-prompt",
16902
+ bottomDockScrollToBottom: "agent-gui-node__bottom-dock-scroll-to-bottom",
16532
16903
  body: "agent-gui-node__body",
16533
16904
  composer: "agent-gui-node__composer",
16534
16905
  composerChip: "agent-gui-node__composer-chip",
@@ -16538,6 +16909,10 @@ var styles3 = {
16538
16909
  composerFooterRight: "agent-gui-node__composer-footer-right",
16539
16910
  composerHero: "agent-gui-node__composer-hero",
16540
16911
  composerFloatingPrompt: "agent-gui-node__composer-floating-prompt",
16912
+ composerHandoffIcon: "agent-gui-node__composer-handoff-icon",
16913
+ composerHandoffMenuContent: "agent-gui-node__composer-handoff-menu-content",
16914
+ composerHandoffStaticIcon: "agent-gui-node__composer-handoff-icon-static",
16915
+ composerHandoffTrigger: "agent-gui-node__composer-handoff-trigger",
16541
16916
  composerQueuedPromptFloating: "agent-gui-node__composer-floating-prompt--queued",
16542
16917
  composerInputGroup: "agent-gui-node__composer-input-group",
16543
16918
  composerInputGroupHero: "agent-gui-node__composer-input-group-hero",
@@ -16583,6 +16958,7 @@ var styles3 = {
16583
16958
  conversationItem: "agent-gui-node__conversation-item",
16584
16959
  conversationList: "agent-gui-node__conversation-list",
16585
16960
  conversationMeta: "agent-gui-node__conversation-meta",
16961
+ conversationProviderIcon: "agent-gui-node__conversation-provider-icon",
16586
16962
  conversationOpenWindowButton: "agent-gui-node__conversation-open-window-button",
16587
16963
  conversationPinButton: "agent-gui-node__conversation-pin-button",
16588
16964
  conversationSection: "agent-gui-node__conversation-section",
@@ -16604,6 +16980,7 @@ var styles3 = {
16604
16980
  conversationStatusGlyph: "agent-gui-node__conversation-status-glyph",
16605
16981
  conversationTime: "agent-gui-node__conversation-time",
16606
16982
  conversationTitle: "agent-gui-node__conversation-title",
16983
+ conversationTitleRow: "agent-gui-node__conversation-title-row",
16607
16984
  conversationUnreadLamp: "agent-gui-node__conversation-unread-lamp",
16608
16985
  detailHeader: "agent-gui-node__detail-header",
16609
16986
  detailHeaderPathInfo: "agent-gui-node__detail-header-path-info",
@@ -16619,7 +16996,11 @@ var styles3 = {
16619
16996
  emptyHero: "agent-gui-node__empty-hero",
16620
16997
  emptyHeroBody: "agent-gui-node__empty-hero-body",
16621
16998
  emptyHeroIconEffect: "agent-gui-node__empty-hero-icon-effect",
16999
+ emptyHeroIconRail: "agent-gui-node__empty-hero-icon-rail",
17000
+ emptyHeroIconRailItem: "agent-gui-node__empty-hero-icon-rail-item",
17001
+ emptyHeroIconRailScroller: "agent-gui-node__empty-hero-icon-rail-scroller",
16622
17002
  emptyHeroProvider: "agent-gui-node__empty-hero-provider",
17003
+ emptyHeroProviderSelect: "agent-gui-node__empty-hero-provider-select",
16623
17004
  emptyHeroTitle: "agent-gui-node__empty-hero-title",
16624
17005
  emptyProviderGate: "agent-gui-node__empty-provider-gate",
16625
17006
  emptyProviderGateAction: "agent-gui-node__empty-provider-gate-action",
@@ -16643,6 +17024,11 @@ var styles3 = {
16643
17024
  providerRailAvatar: "agent-gui-node__provider-rail-avatar",
16644
17025
  providerRailAvatarIcon: "agent-gui-node__provider-rail-avatar-icon",
16645
17026
  providerRailAvatarImage: "agent-gui-node__provider-rail-avatar-image",
17027
+ providerRailLaunchpadIcon: "agent-gui-node__provider-rail-launchpad-icon",
17028
+ emptyHeroLaunchpadIcon: "agent-gui-node__empty-hero-launchpad-icon",
17029
+ providerRailLaunchpadItem: "agent-gui-node__provider-rail-launchpad-item",
17030
+ providerRailPanel: "agent-gui-node__provider-rail-panel",
17031
+ providerRailSeparator: "agent-gui-node__provider-rail-separator",
16646
17032
  providerRailTile: "agent-gui-node__provider-rail-tile",
16647
17033
  providerRailTileLabel: "agent-gui-node__provider-rail-tile-label",
16648
17034
  rail: "agent-gui-node__rail",
@@ -16698,12 +17084,12 @@ function AgentQueuedPromptPanel({
16698
17084
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS
16699
17085
  }) {
16700
17086
  "use memo";
16701
- const [isExpanded, setIsExpanded] = useState5(false);
17087
+ const [isExpanded, setIsExpanded] = useState6(false);
16702
17088
  const singlePromptTextRef = useRef7(null);
16703
17089
  const queuedPromptListRef = useRef7(null);
16704
17090
  const pointerHandledEditPromptIdRef = useRef7(null);
16705
- const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState5(false);
16706
- const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState5(280);
17091
+ const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState6(false);
17092
+ const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState6(280);
16707
17093
  const singlePromptHasImages = queuedPrompts.length === 1 && queuedPromptImages(queuedPrompts[0]).length > 0;
16708
17094
  const canExpand = queuedPrompts.length > 1 || singlePromptHasImages || isSinglePromptOverflowing;
16709
17095
  const panelStyle = {
@@ -16942,9 +17328,9 @@ function AgentQueuedPromptPanel({
16942
17328
  // agent-gui/agentGuiNode/AgentComposerSettingsMenus.tsx
16943
17329
  import {
16944
17330
  cloneElement,
16945
- useEffect as useEffect7,
17331
+ useEffect as useEffect8,
16946
17332
  useMemo as useMemo5,
16947
- useState as useState6
17333
+ useState as useState7
16948
17334
  } from "react";
16949
17335
  import { ChevronDown, ZapIcon as ZapIcon2 } from "lucide-react";
16950
17336
  import {
@@ -17417,7 +17803,7 @@ function AgentPermissionModeDropdown({
17417
17803
  onSettingsChange
17418
17804
  }) {
17419
17805
  "use memo";
17420
- const [isSelectOpen, setIsSelectOpen] = useState6(false);
17806
+ const [isSelectOpen, setIsSelectOpen] = useState7(false);
17421
17807
  const isLoading = composerSettings.isSettingsLoading || composerSettings.isModelOptionsLoading === true;
17422
17808
  const availableOptions = composerSettings.availablePermissionModes ?? [];
17423
17809
  const selectedValue = composerSettings.selectedPermissionModeValue ?? composerSettings.draftSettings.permissionModeId;
@@ -17556,7 +17942,7 @@ function AgentProjectMissingStatusProbe({
17556
17942
  "use memo";
17557
17943
  const agentHostApi = useAgentHostApi();
17558
17944
  const selectedPath = composerSettings.selectedProjectPath?.trim() ?? "";
17559
- useEffect7(() => {
17945
+ useEffect8(() => {
17560
17946
  let canceled = false;
17561
17947
  const userProjects = agentHostApi.userProjects;
17562
17948
  if (!userProjects || !composerSettings.projectLocked || !selectedPath) {
@@ -17647,7 +18033,7 @@ function AgentModelReasoningDropdown({
17647
18033
  onSettingsChange
17648
18034
  }) {
17649
18035
  "use memo";
17650
- const [menuOpen, setMenuOpen] = useState6(false);
18036
+ const [menuOpen, setMenuOpen] = useState7(false);
17651
18037
  const menu = buildComposerModelMenuModel(composerSettings, labels);
17652
18038
  const menuDisabled = disabled || menu.disabled;
17653
18039
  const isModelLoading = composerSettings.isModelOptionsLoading || composerSettings.isSettingsLoading;
@@ -17902,7 +18288,7 @@ function ComposerModelOptionTooltip({
17902
18288
  "data-agent-model-option-tooltip": "true",
17903
18289
  children: [
17904
18290
  /* @__PURE__ */ jsx23("span", { className: "block text-[15px] font-semibold leading-[1.2]", children: option.tooltip.title }),
17905
- option.tooltip.description ? /* @__PURE__ */ jsx23("span", { className: "mt-1.5 block text-[13px] leading-[1.35]", children: option.tooltip.description }) : null,
18291
+ 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,
17906
18292
  option.tooltip.contextWindow ? /* @__PURE__ */ jsx23("span", { className: "mt-4 block", children: option.tooltip.contextWindow }) : null,
17907
18293
  option.tooltip.version ? /* @__PURE__ */ jsx23("span", { className: "mt-4 block italic", children: option.tooltip.version }) : null
17908
18294
  ]
@@ -17915,11 +18301,11 @@ function ComposerModelOptionTooltip({
17915
18301
  import {
17916
18302
  forwardRef as forwardRef3,
17917
18303
  useCallback as useCallback6,
17918
- useEffect as useEffect8,
18304
+ useEffect as useEffect9,
17919
18305
  useImperativeHandle as useImperativeHandle2,
17920
18306
  useMemo as useMemo6,
17921
18307
  useRef as useRef8,
17922
- useState as useState7
18308
+ useState as useState8
17923
18309
  } from "react";
17924
18310
  import { createPortal } from "react-dom";
17925
18311
  import { Extension } from "@tiptap/core";
@@ -18515,7 +18901,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
18515
18901
  const availableCapabilitiesRef = useRef8(availableCapabilities);
18516
18902
  const suppressPastedAtSuggestionRef = useRef8(false);
18517
18903
  const scrollFrameRef = useRef8(null);
18518
- const [contextMenu, setContextMenu] = useState7(null);
18904
+ const [contextMenu, setContextMenu] = useState8(null);
18519
18905
  const closeContextMenu = useCallback6(() => {
18520
18906
  setContextMenu(null);
18521
18907
  }, []);
@@ -18988,10 +19374,10 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
18988
19374
  }
18989
19375
  onSubmitRef.current();
18990
19376
  };
18991
- useEffect8(() => {
19377
+ useEffect9(() => {
18992
19378
  editorRef.current = editor;
18993
19379
  }, [editor]);
18994
- useEffect8(
19380
+ useEffect9(
18995
19381
  () => () => {
18996
19382
  if (scrollFrameRef.current !== null && typeof window.cancelAnimationFrame === "function") {
18997
19383
  window.cancelAnimationFrame(scrollFrameRef.current);
@@ -18999,7 +19385,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
18999
19385
  },
19000
19386
  []
19001
19387
  );
19002
- useEffect8(() => {
19388
+ useEffect9(() => {
19003
19389
  if (!contextMenu) {
19004
19390
  return;
19005
19391
  }
@@ -19105,7 +19491,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19105
19491
  }),
19106
19492
  []
19107
19493
  );
19108
- useEffect8(() => {
19494
+ useEffect9(() => {
19109
19495
  if (!editor) {
19110
19496
  return;
19111
19497
  }
@@ -19116,7 +19502,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
19116
19502
  editor.state.tr.setMeta("agentRichTextPlaceholder", placeholder)
19117
19503
  );
19118
19504
  }, [disabled, editor, placeholder]);
19119
- useEffect8(() => {
19505
+ useEffect9(() => {
19120
19506
  if (!editor || editor.isDestroyed) {
19121
19507
  return;
19122
19508
  }
@@ -19358,7 +19744,7 @@ function AgentSlashStatusPanel({
19358
19744
  }
19359
19745
 
19360
19746
  // agent-gui/agentGuiNode/AgentReviewPickerPanel.tsx
19361
- import { useCallback as useCallback7, useEffect as useEffect9, useMemo as useMemo7, useRef as useRef9, useState as useState8 } from "react";
19747
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo7, useRef as useRef9, useState as useState9 } from "react";
19362
19748
  import { menuItemClassName } from "@tutti-os/ui-system";
19363
19749
 
19364
19750
  // agent-gui/agentGuiNode/AgentReviewBranchController.ts
@@ -19473,21 +19859,21 @@ function AgentReviewPickerPanel({
19473
19859
  onSubmitReview,
19474
19860
  onClose
19475
19861
  }) {
19476
- const [stage, setStage] = useState8("root");
19477
- const [query, setQuery] = useState8("");
19478
- const [highlightedIndex, setHighlightedIndex] = useState8(0);
19862
+ const [stage, setStage] = useState9("root");
19863
+ const [query, setQuery] = useState9("");
19864
+ const [highlightedIndex, setHighlightedIndex] = useState9(0);
19479
19865
  const searchInputRef = useRef9(null);
19480
19866
  const highlightedOptionRef = useRef9(null);
19481
19867
  const reviewBranchControllerRef = useRef9(
19482
19868
  null
19483
19869
  );
19484
- const [branchState, setBranchState] = useState8({
19870
+ const [branchState, setBranchState] = useState9({
19485
19871
  status: "idle",
19486
19872
  branches: [],
19487
19873
  currentBranch: null,
19488
19874
  error: null
19489
19875
  });
19490
- useEffect9(() => {
19876
+ useEffect10(() => {
19491
19877
  const controller = new AgentReviewBranchController();
19492
19878
  reviewBranchControllerRef.current = controller;
19493
19879
  const unsubscribe = controller.subscribe(setBranchState);
@@ -19497,7 +19883,7 @@ function AgentReviewPickerPanel({
19497
19883
  reviewBranchControllerRef.current = null;
19498
19884
  };
19499
19885
  }, []);
19500
- useEffect9(() => {
19886
+ useEffect10(() => {
19501
19887
  const controller = reviewBranchControllerRef.current;
19502
19888
  if (!controller) {
19503
19889
  return;
@@ -19507,7 +19893,7 @@ function AgentReviewPickerPanel({
19507
19893
  controller.ensureLoaded();
19508
19894
  }
19509
19895
  }, [onRequestGitBranches, stage]);
19510
- useEffect9(() => {
19896
+ useEffect10(() => {
19511
19897
  searchInputRef.current?.focus();
19512
19898
  }, [stage]);
19513
19899
  const submit = useCallback7(
@@ -19597,7 +19983,7 @@ function AgentReviewPickerPanel({
19597
19983
  goToStage
19598
19984
  ]);
19599
19985
  const safeHighlightedIndex = entries.length === 0 ? -1 : Math.min(highlightedIndex, entries.length - 1);
19600
- useEffect9(() => {
19986
+ useEffect10(() => {
19601
19987
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
19602
19988
  }, [safeHighlightedIndex]);
19603
19989
  const searchPlaceholder = stage === "base" ? labels.branchPlaceholder : stage === "commit" ? labels.commitPlaceholder : stage === "custom" ? labels.customPlaceholder : labels.searchPlaceholder;
@@ -19720,11 +20106,11 @@ function AgentReviewPickerPanel({
19720
20106
  import {
19721
20107
  forwardRef as forwardRef4,
19722
20108
  useCallback as useCallback8,
19723
- useEffect as useEffect10,
20109
+ useEffect as useEffect11,
19724
20110
  useLayoutEffect as useLayoutEffect2,
19725
20111
  useMemo as useMemo8,
19726
20112
  useRef as useRef10,
19727
- useState as useState9
20113
+ useState as useState10
19728
20114
  } from "react";
19729
20115
  import { createPortal as createPortal2 } from "react-dom";
19730
20116
  import { jsx as jsx27 } from "react/jsx-runtime";
@@ -19801,7 +20187,7 @@ function useComposerAnchoredMenuFrame({
19801
20187
  maxHeight,
19802
20188
  open
19803
20189
  }) {
19804
- const [frame, setFrame] = useState9(null);
20190
+ const [frame, setFrame] = useState10(null);
19805
20191
  const syncFrame = useCallback8(() => {
19806
20192
  const anchor = anchorRef.current;
19807
20193
  if (!anchor || typeof window === "undefined") {
@@ -19873,7 +20259,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
19873
20259
  },
19874
20260
  [forwardedRef, surfaceRef]
19875
20261
  );
19876
- useEffect10(() => {
20262
+ useEffect11(() => {
19877
20263
  if (!open || !onDismiss) {
19878
20264
  return;
19879
20265
  }
@@ -19963,8 +20349,14 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
19963
20349
  );
19964
20350
  });
19965
20351
 
19966
- // app/renderer/assets/icons/@-lined-14px.svg
19967
- var lined_14px_default = "./@-lined-14px-64O2KKB4.svg";
20352
+ // app/renderer/assets/icons/add-lined-bold.svg
20353
+ var add_lined_bold_default = "./add-lined-bold-5QPUDZCU.svg";
20354
+
20355
+ // app/renderer/assets/icons/@-bold-lined.svg
20356
+ var bold_lined_default = "./@-bold-lined-BLLFKBFI.svg";
20357
+
20358
+ // app/renderer/assets/icons/handoff-lined.svg
20359
+ var handoff_lined_default = "./handoff-lined-4WQUBVG3.svg";
19968
20360
 
19969
20361
  // agent-gui/agentGuiNode/AgentComposer.tsx
19970
20362
  import { jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
@@ -20006,7 +20398,7 @@ function AgentUsageChip({
20006
20398
  compactDisabled
20007
20399
  }) {
20008
20400
  "use memo";
20009
- const [usagePopoverOpen, setUsagePopoverOpen] = useState10(false);
20401
+ const [usagePopoverOpen, setUsagePopoverOpen] = useState11(false);
20010
20402
  const usagePopoverHoverTimerRef = useRef11(null);
20011
20403
  const usagePopoverContentRef = useRef11(null);
20012
20404
  const clampedPercent = Math.max(0, Math.min(100, percentUsed));
@@ -20079,7 +20471,7 @@ function AgentUsageChip({
20079
20471
  closeUsagePopover
20080
20472
  ]
20081
20473
  );
20082
- useEffect11(
20474
+ useEffect12(
20083
20475
  () => () => {
20084
20476
  clearUsagePopoverHoverTimer();
20085
20477
  clearUsagePopoverCloseTimer();
@@ -20202,6 +20594,12 @@ var MENTION_PALETTE_DISMISS_INTERACTION_SELECTOR = [
20202
20594
  ".workbench-window__resize-handle",
20203
20595
  "#agent-gui-conversation-rail-resize"
20204
20596
  ].join(",");
20597
+ function resolveComposerProviderIconUrl(provider) {
20598
+ return MANAGED_AGENT_ICON_URLS[normalizeManagedAgentProvider(provider)] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20599
+ }
20600
+ function resolveComposerProviderTargetIconUrl(target) {
20601
+ return target.iconUrl ?? resolveComposerProviderIconUrl(target.provider);
20602
+ }
20205
20603
  function resolveMentionPalettePortalTarget(anchor) {
20206
20604
  return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? anchor.closest(
20207
20605
  "[data-workbench-window-id], [data-workspace-node-window-root='true']"
@@ -20231,21 +20629,53 @@ function hasInlineOverflow(element) {
20231
20629
  }
20232
20630
  return element.scrollWidth > element.clientWidth + 1;
20233
20631
  }
20234
- function resolveComposerProviderIconUrl(provider) {
20235
- const normalizedProvider = normalizeManagedAgentProvider(provider);
20236
- return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20632
+ function AgentComposerMaskIcon({
20633
+ iconUrl,
20634
+ marker
20635
+ }) {
20636
+ return /* @__PURE__ */ jsx28(
20637
+ "span",
20638
+ {
20639
+ "aria-hidden": true,
20640
+ 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)]",
20641
+ "data-agent-reference-add-icon": marker === "reference-add" ? "true" : void 0,
20642
+ style: {
20643
+ WebkitMaskImage: `url("${iconUrl}")`,
20644
+ WebkitMaskPosition: "center",
20645
+ WebkitMaskRepeat: "no-repeat",
20646
+ WebkitMaskSize: "contain",
20647
+ maskImage: `url("${iconUrl}")`,
20648
+ maskPosition: "center",
20649
+ maskRepeat: "no-repeat",
20650
+ maskSize: "contain"
20651
+ }
20652
+ }
20653
+ );
20237
20654
  }
20238
- function resolveComposerProviderTargetIconUrl(target) {
20239
- return target.iconUrl?.trim() || resolveComposerProviderIconUrl(target.provider);
20655
+ var HANDOFF_SELECT_IDLE_VALUE = "__agent-handoff-idle__";
20656
+ function AgentComposerHandoffIcon() {
20657
+ return /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.composerHandoffIcon, children: /* @__PURE__ */ jsx28(
20658
+ "span",
20659
+ {
20660
+ className: AgentGUINode_styles_default.composerHandoffStaticIcon,
20661
+ style: {
20662
+ WebkitMaskImage: `url("${handoff_lined_default}")`,
20663
+ WebkitMaskPosition: "center",
20664
+ WebkitMaskRepeat: "no-repeat",
20665
+ WebkitMaskSize: "contain",
20666
+ maskImage: `url("${handoff_lined_default}")`,
20667
+ maskPosition: "center",
20668
+ maskRepeat: "no-repeat",
20669
+ maskSize: "contain"
20670
+ }
20671
+ }
20672
+ ) });
20240
20673
  }
20241
20674
  function AgentComposer({
20242
20675
  workspaceId,
20243
20676
  workspacePath,
20244
20677
  currentUserId,
20245
20678
  provider,
20246
- selectedProviderTarget = null,
20247
- providerTargets = [],
20248
- providerSelectReadonly = false,
20249
20679
  slashStatus = null,
20250
20680
  usage = null,
20251
20681
  draftContent,
@@ -20255,12 +20685,18 @@ function AgentComposer({
20255
20685
  availableSkills = EMPTY_PROVIDER_SKILLS,
20256
20686
  disabled,
20257
20687
  disabledReason,
20688
+ hasActiveConversation = true,
20258
20689
  submitDisabled,
20259
20690
  placeholder,
20260
20691
  composerSettings,
20261
20692
  queuedPrompts,
20262
20693
  drainingQueuedPromptId,
20263
20694
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS2,
20695
+ selectedProviderTarget = null,
20696
+ providerTargets = [],
20697
+ providerSelectReadonly = false,
20698
+ onProviderSelect,
20699
+ onHandoffConversation,
20264
20700
  canQueueWhileBusy,
20265
20701
  showStopButton,
20266
20702
  activePrompt,
@@ -20277,13 +20713,15 @@ function AgentComposer({
20277
20713
  promptImagesSupported = true,
20278
20714
  composerFocusRequestSequence = null,
20279
20715
  layoutMode = "dock",
20716
+ providerSelectLabel = "",
20717
+ handoffLabel,
20718
+ handoffMenuLabel,
20280
20719
  labels,
20281
20720
  workspaceUserProjectI18n,
20282
20721
  onDraftContentChange,
20283
20722
  onProjectPathChange = () => {
20284
20723
  },
20285
20724
  onSettingsChange,
20286
- onProviderSelect,
20287
20725
  capabilityMenuState,
20288
20726
  onSubmit,
20289
20727
  onSubmitGuidance,
@@ -20316,28 +20754,28 @@ function AgentComposer({
20316
20754
  const promptFilesSupported = Boolean(
20317
20755
  resolveDroppedFileReferences && promptFileUploadSupported
20318
20756
  );
20319
- const [isPaletteOpen, setIsPaletteOpen] = useState10(true);
20320
- const [isReviewPickerOpen, setIsReviewPickerOpen] = useState10(false);
20321
- const [highlightedIndex, setHighlightedIndex] = useState10(0);
20322
- const [mentionHighlightedKey, setMentionHighlightedKey] = useState10(null);
20323
- const [shouldCenterMentionHighlight, setShouldCenterMentionHighlight] = useState10(false);
20757
+ const [isPaletteOpen, setIsPaletteOpen] = useState11(true);
20758
+ const [isReviewPickerOpen, setIsReviewPickerOpen] = useState11(false);
20759
+ const [highlightedIndex, setHighlightedIndex] = useState11(0);
20760
+ const [mentionHighlightedKey, setMentionHighlightedKey] = useState11(null);
20761
+ const [shouldCenterMentionHighlight, setShouldCenterMentionHighlight] = useState11(false);
20324
20762
  const [
20325
20763
  shouldResetMentionHighlightToFilter,
20326
20764
  setShouldResetMentionHighlightToFilter
20327
- ] = useState10(false);
20328
- const [paletteDraftPrompt, setPaletteDraftPrompt] = useState10(
20765
+ ] = useState11(false);
20766
+ const [paletteDraftPrompt, setPaletteDraftPrompt] = useState11(
20329
20767
  goalDraftObjective ?? draftPrompt
20330
20768
  );
20331
- const [fileMentionSuggestion, setFileMentionSuggestion] = useState10(null);
20332
- const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState10(false);
20333
- const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState10(false);
20769
+ const [fileMentionSuggestion, setFileMentionSuggestion] = useState11(null);
20770
+ const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState11(false);
20771
+ const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState11(false);
20334
20772
  const slashStatusAgentSessionId = slashStatus?.agentSessionId ?? null;
20335
20773
  const previousSlashStatusAgentSessionIdRef = useRef11(
20336
20774
  slashStatusAgentSessionId
20337
20775
  );
20338
20776
  const selectedProjectPath = composerSettings.selectedProjectPath?.trim() ?? "";
20339
20777
  const previousSelectedProjectPathRef = useRef11(selectedProjectPath);
20340
- const [mentionSearchState, setMentionSearchState] = useState10({
20778
+ const [mentionSearchState, setMentionSearchState] = useState11({
20341
20779
  status: "idle",
20342
20780
  query: "",
20343
20781
  mode: "browse",
@@ -20361,15 +20799,15 @@ function AgentComposer({
20361
20799
  const wasActiveRef = useRef11(isActive);
20362
20800
  const lastComposerFocusRequestRef = useRef11(null);
20363
20801
  const autoMentionHighlightedKeyRef = useRef11(null);
20364
- const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState10(false);
20365
- const [dockComposerInputHeight, setDockComposerInputHeight] = useState10(
20802
+ const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState11(false);
20803
+ const [dockComposerInputHeight, setDockComposerInputHeight] = useState11(
20366
20804
  DOCK_COMPOSER_INPUT_MIN_HEIGHT
20367
20805
  );
20368
- const [dockComposerInputMaxHeight, setDockComposerInputMaxHeight] = useState10(
20806
+ const [dockComposerInputMaxHeight, setDockComposerInputMaxHeight] = useState11(
20369
20807
  DOCK_COMPOSER_INPUT_MAX_HEIGHT
20370
20808
  );
20371
- const [dockComposerAttachmentHeight, setDockComposerAttachmentHeight] = useState10(0);
20372
- const [dockComposerTextHeight, setDockComposerTextHeight] = useState10(
20809
+ const [dockComposerAttachmentHeight, setDockComposerAttachmentHeight] = useState11(0);
20810
+ const [dockComposerTextHeight, setDockComposerTextHeight] = useState11(
20373
20811
  DOCK_COMPOSER_INPUT_MIN_HEIGHT
20374
20812
  );
20375
20813
  const slashQuery = isGoalModeActive ? null : getPromptStartSlashCommandQuery(paletteDraftPrompt);
@@ -20529,11 +20967,11 @@ function AgentComposer({
20529
20967
  highlightedIndex,
20530
20968
  slashPaletteEntries.length
20531
20969
  );
20532
- const [mentionPaletteFrame, setMentionPaletteFrame] = useState10(null);
20533
- useEffect11(() => {
20970
+ const [mentionPaletteFrame, setMentionPaletteFrame] = useState11(null);
20971
+ useEffect12(() => {
20534
20972
  setHighlightedIndex(0);
20535
20973
  }, [skillQueryMatch?.prefix, skillQueryMatch?.query, slashQuery]);
20536
- useEffect11(() => {
20974
+ useEffect12(() => {
20537
20975
  const preferredKey = shouldResetMentionHighlightToFilter && mentionSearchState.mode === "browse" ? `category:${mentionSearchState.filter}` : null;
20538
20976
  if (shouldResetMentionHighlightToFilter) {
20539
20977
  const nextKey = repairMentionPaletteHighlight({
@@ -20565,7 +21003,7 @@ function AgentComposer({
20565
21003
  mentionSearchState,
20566
21004
  shouldResetMentionHighlightToFilter
20567
21005
  ]);
20568
- useEffect11(() => {
21006
+ useEffect12(() => {
20569
21007
  const controller = new AgentMentionSearchController({
20570
21008
  contextMentionProviders
20571
21009
  });
@@ -20577,7 +21015,7 @@ function AgentComposer({
20577
21015
  mentionControllerRef.current = null;
20578
21016
  };
20579
21017
  }, [contextMentionProviders]);
20580
- useEffect11(() => {
21018
+ useEffect12(() => {
20581
21019
  const isExternalDraftReplacement = draftPromptRef.current !== draftPrompt;
20582
21020
  draftPromptRef.current = draftPrompt;
20583
21021
  setPaletteDraftPrompt(goalDraftObjective ?? draftPrompt);
@@ -20589,13 +21027,13 @@ function AgentComposer({
20589
21027
  });
20590
21028
  }
20591
21029
  }, [draftPrompt, goalDraftObjective]);
20592
- useEffect11(() => {
21030
+ useEffect12(() => {
20593
21031
  draftImagesRef.current = draftImages;
20594
21032
  }, [draftImages]);
20595
- useEffect11(() => {
21033
+ useEffect12(() => {
20596
21034
  draftFilesRef.current = draftFiles;
20597
21035
  }, [draftFiles]);
20598
- useEffect11(() => {
21036
+ useEffect12(() => {
20599
21037
  if (previousSlashStatusAgentSessionIdRef.current === slashStatusAgentSessionId) {
20600
21038
  return;
20601
21039
  }
@@ -20851,11 +21289,13 @@ function AgentComposer({
20851
21289
  } else {
20852
21290
  onSubmit(submitContent);
20853
21291
  }
20854
- draftPromptRef.current = "";
20855
- draftImagesRef.current = [];
20856
- draftFilesRef.current = [];
20857
- setPaletteDraftPrompt("");
20858
- onDraftContentChange(emptyAgentComposerDraft());
21292
+ if (hasActiveConversation) {
21293
+ draftPromptRef.current = "";
21294
+ draftImagesRef.current = [];
21295
+ draftFilesRef.current = [];
21296
+ setPaletteDraftPrompt("");
21297
+ onDraftContentChange(emptyAgentComposerDraft());
21298
+ }
20859
21299
  }
20860
21300
  );
20861
21301
  const submit = useCallback9(
@@ -21039,7 +21479,10 @@ function AgentComposer({
21039
21479
  return makeAtPanelKeyDown({
21040
21480
  close: closeFileMentionPalette,
21041
21481
  commitSelection: () => {
21042
- createFileMentionPaletteAdapter().commitHighlighted();
21482
+ const result = createFileMentionPaletteAdapter().commitHighlighted();
21483
+ if (result.type === "none") {
21484
+ closeFileMentionPalette();
21485
+ }
21043
21486
  },
21044
21487
  cycleFilter: cycleFileMentionFilter,
21045
21488
  moveSelection: moveFileMentionSelection,
@@ -21080,7 +21523,7 @@ function AgentComposer({
21080
21523
  const handlePaletteKeyDown = useStableEventCallback(
21081
21524
  (event) => handleFileMentionKeyDown(event) || handleSlashPaletteKeyDown(event) || handleSlashCommandMenuKeyDown(event) || handlePlanModeToggleKeyDown(event)
21082
21525
  );
21083
- useEffect11(() => {
21526
+ useEffect12(() => {
21084
21527
  if (!showPalette || workspaceReferencePickerOpen) {
21085
21528
  return;
21086
21529
  }
@@ -21146,12 +21589,12 @@ function AgentComposer({
21146
21589
  },
21147
21590
  [onLinkAction, workspacePath]
21148
21591
  );
21149
- useEffect11(() => {
21592
+ useEffect12(() => {
21150
21593
  if (!showFileMentionPalette && shouldCenterMentionHighlight) {
21151
21594
  setShouldCenterMentionHighlight(false);
21152
21595
  }
21153
21596
  }, [shouldCenterMentionHighlight, showFileMentionPalette]);
21154
- useEffect11(() => {
21597
+ useEffect12(() => {
21155
21598
  if (!showFileMentionPalette) {
21156
21599
  return;
21157
21600
  }
@@ -21397,17 +21840,6 @@ function AgentComposer({
21397
21840
  }
21398
21841
  await applyReferencePickResult(await onRequestWorkspaceReferences());
21399
21842
  }, [applyReferencePickResult, onRequestWorkspaceReferences]);
21400
- const providerSwitchTargets = useMemo9(
21401
- () => providerTargets.filter((target) => target.disabled !== true),
21402
- [providerTargets]
21403
- );
21404
- const showProviderSelect = providerSwitchTargets.length > 1;
21405
- const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
21406
- const selectedProviderSwitchTarget = providerSwitchTargets.find(
21407
- (target) => target.targetId === selectedProviderTargetId
21408
- ) ?? selectedProviderTarget ?? providerSwitchTargets.find((target) => target.provider === provider) ?? null;
21409
- const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? provider;
21410
- const providerSelectDisabled = previewMode || providerSelectReadonly || !onProviderSelect;
21411
21843
  const applyDroppedFileReferences = useCallback9(
21412
21844
  async (files) => {
21413
21845
  if (!promptFilesSupported || !resolveDroppedFileReferences || files.length === 0) {
@@ -21523,11 +21955,40 @@ function AgentComposer({
21523
21955
  const mentionPaletteHeightPx = mentionPaletteFrame?.height ?? MENTION_PALETTE_MIN_HEIGHT_PX;
21524
21956
  const isHeroLayout = layoutMode === "hero";
21525
21957
  const composerClassName = isHeroLayout ? AgentGUINode_styles_default.composerHero : AgentGUINode_styles_default.composer;
21958
+ const providerSwitchTargets = useMemo9(
21959
+ () => providerTargets.filter(Boolean),
21960
+ [providerTargets]
21961
+ );
21962
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
21963
+ const selectedProviderSwitchTarget = providerSwitchTargets.find(
21964
+ (target) => target.targetId === selectedProviderTargetId
21965
+ ) ?? providerSwitchTargets.find((target) => target.provider === provider) ?? selectedProviderTarget;
21966
+ const providerMenuTargets = selectedProviderSwitchTarget && !providerSwitchTargets.some(
21967
+ (target) => target.targetId === selectedProviderSwitchTarget.targetId
21968
+ ) ? [selectedProviderSwitchTarget, ...providerSwitchTargets] : providerSwitchTargets;
21969
+ const handoffMenuTargets = selectedProviderSwitchTarget ? providerMenuTargets.filter((target) => {
21970
+ if (target.disabled === true) {
21971
+ return false;
21972
+ }
21973
+ if (target.targetId === selectedProviderSwitchTarget.targetId) {
21974
+ return false;
21975
+ }
21976
+ const selectedAgentTargetId = selectedProviderSwitchTarget.agentTargetId ?? selectedProviderSwitchTarget.targetId;
21977
+ const targetAgentTargetId = target.agentTargetId ?? target.targetId;
21978
+ return targetAgentTargetId !== selectedAgentTargetId;
21979
+ }) : providerMenuTargets;
21980
+ const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? selectedProviderTarget?.label ?? provider;
21981
+ const effectiveHandoffLabel = handoffLabel || labels.handoffConversation;
21982
+ const effectiveHandoffMenuLabel = handoffMenuLabel || labels.handoffConversationMenu;
21526
21983
  const inputShellClassName = cn(
21527
21984
  AgentGUINode_styles_default.composerInputShell,
21528
21985
  isHeroLayout && AgentGUINode_styles_default.composerInputShellHero
21529
21986
  );
21530
21987
  const inputDisabled = isSelectedProjectMissing || disabled && !canQueueWhileBusy;
21988
+ const providerSelectDisabled = providerSelectReadonly || composerControlsHardDisabled || inputDisabled;
21989
+ const handoffDisabled = composerControlsHardDisabled || inputDisabled || !onHandoffConversation || handoffMenuTargets.length === 0;
21990
+ const showProviderSelect = !isHeroLayout && selectedProviderSwitchTarget !== null && providerMenuTargets.length > 0;
21991
+ const showHandoffSelect = showProviderSelect && providerSelectReadonly && !previewMode;
21531
21992
  const handleMentionPaletteButton = useCallback9(() => {
21532
21993
  if (composerControlsHardDisabled || inputDisabled) {
21533
21994
  return;
@@ -21551,7 +22012,7 @@ function AgentComposer({
21551
22012
  },
21552
22013
  [addDraftImages, scheduleComposerFocus]
21553
22014
  );
21554
- useEffect11(() => {
22015
+ useEffect12(() => {
21555
22016
  const composer = composerRef.current;
21556
22017
  const dropTarget = composer?.closest("#agent-gui-detail") ?? composer;
21557
22018
  if (!dropTarget) {
@@ -21653,7 +22114,7 @@ function AgentComposer({
21653
22114
  promptImagesSupported,
21654
22115
  scheduleComposerFocus
21655
22116
  ]);
21656
- useEffect11(() => {
22117
+ useEffect12(() => {
21657
22118
  if (!isActive) {
21658
22119
  wasActiveRef.current = false;
21659
22120
  return;
@@ -21663,7 +22124,7 @@ function AgentComposer({
21663
22124
  }
21664
22125
  wasActiveRef.current = true;
21665
22126
  }, [isActive, scheduleComposerFocus]);
21666
- useEffect11(() => {
22127
+ useEffect12(() => {
21667
22128
  if (composerFocusRequestSequence === null || composerFocusRequestSequence === lastComposerFocusRequestRef.current) {
21668
22129
  return;
21669
22130
  }
@@ -21864,12 +22325,12 @@ function AgentComposer({
21864
22325
  const sendButtonState = isQueueMode ? "queue" : shouldShowStopButton ? isInterrupting ? "stopping" : "interrupt" : isSendingTurn ? "loading" : "send";
21865
22326
  const sendButtonBusy = isSendingTurn && !isQueueMode;
21866
22327
  const activePromptRequestId = activePrompt?.requestId ?? null;
21867
- const [dismissedPromptRequestId, setDismissedPromptRequestId] = useState10(null);
22328
+ const [dismissedPromptRequestId, setDismissedPromptRequestId] = useState11(null);
21868
22329
  const visibleActivePrompt = activePrompt && dismissedPromptRequestId !== activePromptRequestId ? activePrompt : null;
21869
22330
  const disabledReasonText = disabledReason?.trim() ?? "";
21870
22331
  const effectivePlaceholder = disabledReasonText || placeholder;
21871
22332
  const visibleDraftFiles = draftFiles;
21872
- useEffect11(() => {
22333
+ useEffect12(() => {
21873
22334
  if (previousSelectedProjectPathRef.current === selectedProjectPath) {
21874
22335
  return;
21875
22336
  }
@@ -21885,7 +22346,7 @@ function AgentComposer({
21885
22346
  sessionCwd: selectedProjectPath || null
21886
22347
  });
21887
22348
  }, [currentUserId, fileMentionSuggestion, selectedProjectPath, workspaceId]);
21888
- useEffect11(() => {
22349
+ useEffect12(() => {
21889
22350
  setDismissedPromptRequestId(null);
21890
22351
  }, [activePromptRequestId]);
21891
22352
  const submitInteractivePromptAndDismiss = useCallback9(
@@ -22361,14 +22822,13 @@ function AgentComposer({
22361
22822
  className: cn(
22362
22823
  AgentGUINode_styles_default.composerMenuTrigger,
22363
22824
  AgentGUINode_styles_default.composerReferenceTrigger,
22364
- "w-auto justify-center text-[var(--agent-gui-text-secondary)] [&_svg]:shrink-0"
22825
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)]"
22365
22826
  ),
22366
22827
  children: /* @__PURE__ */ jsx28(
22367
- AddIcon,
22828
+ AgentComposerMaskIcon,
22368
22829
  {
22369
- "aria-hidden": true,
22370
- className: "size-3.5",
22371
- "data-agent-reference-add-icon": "true"
22830
+ iconUrl: add_lined_bold_default,
22831
+ marker: "reference-add"
22372
22832
  }
22373
22833
  )
22374
22834
  }
@@ -22396,17 +22856,17 @@ function AgentComposer({
22396
22856
  {
22397
22857
  size: "sm",
22398
22858
  "aria-label": labels.referenceWorkspaceFiles,
22859
+ title: labels.referenceWorkspaceFiles,
22399
22860
  className: cn(
22400
22861
  AgentGUINode_styles_default.composerMenuTrigger,
22401
22862
  AgentGUINode_styles_default.composerReferenceTrigger,
22402
- "w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden [&_svg]:shrink-0"
22863
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden"
22403
22864
  ),
22404
22865
  children: /* @__PURE__ */ jsx28(
22405
- AddIcon,
22866
+ AgentComposerMaskIcon,
22406
22867
  {
22407
- "aria-hidden": true,
22408
- className: "size-3.5",
22409
- "data-agent-reference-add-icon": "true"
22868
+ iconUrl: add_lined_bold_default,
22869
+ marker: "reference-add"
22410
22870
  }
22411
22871
  )
22412
22872
  }
@@ -22415,50 +22875,120 @@ function AgentComposer({
22415
22875
  ),
22416
22876
  /* @__PURE__ */ jsx28(TooltipContent, { side: "top", children: labels.addContent })
22417
22877
  ] }) }),
22418
- /* @__PURE__ */ jsx28(
22419
- "button",
22420
- {
22421
- type: "button",
22422
- "aria-label": labels.mentionPalette,
22423
- title: labels.mentionPalette,
22424
- disabled: composerControlsHardDisabled || inputDisabled,
22425
- className: cn(
22426
- AgentGUINode_styles_default.composerMenuTrigger,
22427
- AgentGUINode_styles_default.composerReferenceTrigger,
22428
- "group w-auto justify-center text-[var(--agent-gui-text-secondary)] disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0"
22878
+ /* @__PURE__ */ jsx28(TooltipProvider, { delayDuration: 120, children: /* @__PURE__ */ jsxs15(Tooltip, { children: [
22879
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
22880
+ "button",
22881
+ {
22882
+ type: "button",
22883
+ "aria-label": labels.mentionPalette,
22884
+ disabled: composerControlsHardDisabled || inputDisabled,
22885
+ className: cn(
22886
+ AgentGUINode_styles_default.composerMenuTrigger,
22887
+ AgentGUINode_styles_default.composerReferenceTrigger,
22888
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)] disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0"
22889
+ ),
22890
+ onMouseDown: (event) => event.preventDefault(),
22891
+ onClick: handleMentionPaletteButton,
22892
+ children: /* @__PURE__ */ jsx28(
22893
+ "span",
22894
+ {
22895
+ "aria-hidden": true,
22896
+ 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)]",
22897
+ style: {
22898
+ WebkitMaskImage: `url("${bold_lined_default}")`,
22899
+ WebkitMaskPosition: "center",
22900
+ WebkitMaskRepeat: "no-repeat",
22901
+ WebkitMaskSize: "contain",
22902
+ maskImage: `url("${bold_lined_default}")`,
22903
+ maskPosition: "center",
22904
+ maskRepeat: "no-repeat",
22905
+ maskSize: "contain"
22906
+ }
22907
+ }
22908
+ )
22909
+ }
22910
+ ) }),
22911
+ /* @__PURE__ */ jsx28(TooltipContent, { side: "top", children: labels.mentionPalette })
22912
+ ] }) })
22913
+ ] }),
22914
+ showHandoffSelect ? /* @__PURE__ */ jsxs15(
22915
+ Select2,
22916
+ {
22917
+ value: HANDOFF_SELECT_IDLE_VALUE,
22918
+ disabled: handoffDisabled,
22919
+ onValueChange: (nextTargetId) => {
22920
+ const target = handoffMenuTargets.find(
22921
+ (candidate) => candidate.targetId === nextTargetId
22922
+ );
22923
+ if (!target || target.disabled === true) {
22924
+ return;
22925
+ }
22926
+ onHandoffConversation?.(target);
22927
+ },
22928
+ children: [
22929
+ /* @__PURE__ */ jsx28(
22930
+ SelectTrigger2,
22931
+ {
22932
+ size: "sm",
22933
+ "aria-label": effectiveHandoffLabel,
22934
+ title: effectiveHandoffLabel,
22935
+ className: cn(
22936
+ AgentGUINode_styles_default.composerMenuTrigger,
22937
+ AgentGUINode_styles_default.composerProviderSelect,
22938
+ AgentGUINode_styles_default.composerHandoffTrigger,
22939
+ "w-auto max-w-[180px] [&>svg:last-child]:hidden"
22940
+ ),
22941
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22942
+ /* @__PURE__ */ jsx28(AgentComposerHandoffIcon, {}),
22943
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: effectiveHandoffLabel })
22944
+ ] })
22945
+ }
22429
22946
  ),
22430
- onMouseDown: (event) => event.preventDefault(),
22431
- onClick: handleMentionPaletteButton,
22432
- children: /* @__PURE__ */ jsx28(
22433
- "span",
22947
+ /* @__PURE__ */ jsx28(
22948
+ SelectContent2,
22434
22949
  {
22435
- "aria-hidden": true,
22436
- 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)]",
22437
- style: {
22438
- WebkitMaskImage: `url("${lined_14px_default}")`,
22439
- WebkitMaskPosition: "center",
22440
- WebkitMaskRepeat: "no-repeat",
22441
- WebkitMaskSize: "contain",
22442
- maskImage: `url("${lined_14px_default}")`,
22443
- maskPosition: "center",
22444
- maskRepeat: "no-repeat",
22445
- maskSize: "contain"
22446
- }
22950
+ align: "start",
22951
+ className: cn(
22952
+ AgentGUINode_styles_default.composerMenuContent,
22953
+ AgentGUINode_styles_default.composerHandoffMenuContent,
22954
+ "min-w-[190px]"
22955
+ ),
22956
+ "aria-label": effectiveHandoffMenuLabel,
22957
+ children: handoffMenuTargets.map((target) => /* @__PURE__ */ jsx28(
22958
+ SelectItem2,
22959
+ {
22960
+ value: target.targetId,
22961
+ className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22962
+ disabled: target.disabled === true,
22963
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22964
+ /* @__PURE__ */ jsx28(
22965
+ "img",
22966
+ {
22967
+ alt: "",
22968
+ "aria-hidden": "true",
22969
+ className: "size-4 shrink-0 rounded-[4px]",
22970
+ src: resolveComposerProviderTargetIconUrl(target)
22971
+ }
22972
+ ),
22973
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: target.label })
22974
+ ] })
22975
+ },
22976
+ `${target.provider}:${target.targetId}`
22977
+ ))
22447
22978
  }
22448
22979
  )
22449
- }
22450
- )
22451
- ] }),
22452
- showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
22980
+ ]
22981
+ }
22982
+ ) : showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
22453
22983
  Select2,
22454
22984
  {
22455
- value: selectedProviderTargetId,
22985
+ value: selectedProviderSwitchTarget.targetId,
22456
22986
  disabled: providerSelectDisabled,
22457
22987
  onValueChange: (nextTargetId) => {
22458
- const target = providerSwitchTargets.find(
22988
+ const target = providerMenuTargets.find(
22459
22989
  (candidate) => candidate.targetId === nextTargetId
22460
22990
  );
22461
- if (!target) {
22991
+ if (!target || target.disabled === true) {
22462
22992
  return;
22463
22993
  }
22464
22994
  onProviderSelect?.({
@@ -22471,14 +23001,27 @@ function AgentComposer({
22471
23001
  SelectTrigger2,
22472
23002
  {
22473
23003
  size: "sm",
22474
- "aria-label": labels.providerSwitchLabel,
22475
- title: labels.providerSwitchLabel,
23004
+ "aria-label": providerSelectLabel,
23005
+ title: providerSelectLabel,
22476
23006
  className: cn(
22477
23007
  AgentGUINode_styles_default.composerMenuTrigger,
22478
23008
  AgentGUINode_styles_default.composerProviderSelect,
22479
- "max-w-[160px] text-[var(--agent-gui-text-secondary)]"
23009
+ "w-auto max-w-[180px]"
22480
23010
  ),
22481
- children: /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx28(SelectValue, { placeholder: selectedProviderLabel }) })
23011
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
23012
+ /* @__PURE__ */ jsx28(
23013
+ "img",
23014
+ {
23015
+ alt: "",
23016
+ "aria-hidden": "true",
23017
+ className: "size-4 shrink-0 rounded-[4px]",
23018
+ src: resolveComposerProviderTargetIconUrl(
23019
+ selectedProviderSwitchTarget
23020
+ )
23021
+ }
23022
+ ),
23023
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: selectedProviderLabel })
23024
+ ] })
22482
23025
  }
22483
23026
  ),
22484
23027
  /* @__PURE__ */ jsx28(
@@ -22486,12 +23029,13 @@ function AgentComposer({
22486
23029
  {
22487
23030
  align: "start",
22488
23031
  className: cn(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
22489
- children: providerSwitchTargets.map((target) => /* @__PURE__ */ jsx28(
23032
+ children: providerMenuTargets.map((target) => /* @__PURE__ */ jsx28(
22490
23033
  SelectItem2,
22491
23034
  {
22492
23035
  value: target.targetId,
22493
23036
  className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22494
- children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
23037
+ disabled: target.disabled === true,
23038
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22495
23039
  /* @__PURE__ */ jsx28(
22496
23040
  "img",
22497
23041
  {
@@ -22605,7 +23149,7 @@ function AgentComposer({
22605
23149
  totalTokens: usage.totalTokens,
22606
23150
  tooltipsEnabled: !previewMode,
22607
23151
  compactSupported: compactSupported ?? false,
22608
- compactDisabled: !hasCompactableContext || composerControlsHardDisabled,
23152
+ compactDisabled: !hasCompactableContext || composerControlsHardDisabled || isSendingTurn,
22609
23153
  onCompact: () => onSubmit(textPromptContent("/compact")),
22610
23154
  labels: {
22611
23155
  usageChipLabel: labels.usageChipLabel,
@@ -22726,7 +23270,7 @@ function AgentComposerDraftImagePreview({
22726
23270
  removeLabel,
22727
23271
  onRemove
22728
23272
  }) {
22729
- const [aspectRatio, setAspectRatio] = useState10(1);
23273
+ const [aspectRatio, setAspectRatio] = useState11(1);
22730
23274
  const previewWidth = Math.round(
22731
23275
  Math.min(
22732
23276
  DRAFT_IMAGE_PREVIEW_MAX_WIDTH_PX,
@@ -23222,6 +23766,14 @@ function AttentionGlyph() {
23222
23766
 
23223
23767
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
23224
23768
  import { createRichTextMentionHref as createRichTextMentionHref2 } from "@tutti-os/ui-rich-text/core";
23769
+
23770
+ // app/renderer/assets/icons/agents/claudecode-flat-filled.svg
23771
+ var claudecode_flat_filled_default = "./claudecode-flat-filled-NHO4JCVK.svg";
23772
+
23773
+ // app/renderer/assets/icons/agents/codex-flat-filled.svg
23774
+ var codex_flat_filled_default = "./codex-flat-filled-WYHCF5VR.svg";
23775
+
23776
+ // agent-gui/agentGuiNode/AgentGUINodeView.tsx
23225
23777
  import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
23226
23778
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
23227
23779
  var AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX = 240;
@@ -23242,8 +23794,22 @@ function resolveAgentGUIHeroIconUrl(provider) {
23242
23794
  const normalizedProvider = normalizeManagedAgentProvider(provider);
23243
23795
  return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
23244
23796
  }
23797
+ function agentGUIProviderIconPresentation(provider, iconUrl) {
23798
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
23799
+ return {
23800
+ provider: normalizedProvider,
23801
+ iconUrl: iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
23802
+ };
23803
+ }
23804
+ function agentGUIProviderRailIconPresentation(provider, iconUrl) {
23805
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
23806
+ return {
23807
+ provider: normalizedProvider,
23808
+ iconUrl: iconUrl?.trim() || MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] || resolveAgentGUIHeroIconUrl(normalizedProvider)
23809
+ };
23810
+ }
23245
23811
  function shouldEmphasizeEmptyHeroProvider(label) {
23246
- return !/[\u3400-\u9fff]/u.test(label);
23812
+ return label.trim().length > 0;
23247
23813
  }
23248
23814
  var fallbackWorkspaceFileReferenceCopy = {
23249
23815
  t(key, values) {
@@ -23424,9 +23990,45 @@ function conversationPlainTitle(conversation, labels, uiLanguage) {
23424
23990
  language: uiLanguage
23425
23991
  });
23426
23992
  }
23993
+ function buildAgentConversationHandoffPrompt(input) {
23994
+ const conversation = input.activeConversation;
23995
+ if (!conversation) {
23996
+ return "";
23997
+ }
23998
+ const sourceAgentLabel = input.selectedProviderTarget?.label?.trim() || conversation.provider;
23999
+ const title = conversationPlainTitle(
24000
+ conversation,
24001
+ input.labels,
24002
+ input.uiLanguage
24003
+ );
24004
+ const mentionLabel = `${sourceAgentLabel}${title ? ` ${title}` : ""}`.trim();
24005
+ const href = createRichTextMentionHref2({
24006
+ providerId: "agent-session",
24007
+ entityId: conversation.id,
24008
+ label: mentionLabel,
24009
+ scope: { workspaceId: input.workspaceId }
24010
+ });
24011
+ return `${formatAgentMentionMarkdown({
24012
+ kind: "session",
24013
+ href,
24014
+ workspaceId: input.workspaceId,
24015
+ targetId: conversation.id,
24016
+ name: mentionLabel,
24017
+ title: title || sourceAgentLabel,
24018
+ scope: "my_sessions",
24019
+ initiatorName: input.currentUserId?.trim() || sourceAgentLabel,
24020
+ agentName: sourceAgentLabel,
24021
+ status: conversation.status,
24022
+ updatedAtUnixMs: conversation.updatedAtUnixMs
24023
+ })} `;
24024
+ }
24025
+ function handoffProjectPathForConversation(conversation) {
24026
+ return conversation?.project?.path?.trim() || conversation?.cwd?.trim() || null;
24027
+ }
23427
24028
  function AgentGUINodeView({
23428
24029
  viewModel,
23429
24030
  onLinkAction,
24031
+ onHandoffConversation,
23430
24032
  capabilityMenuState,
23431
24033
  onCapabilitySettingsRequest,
23432
24034
  isActive = true,
@@ -23467,16 +24069,16 @@ function AgentGUINodeView({
23467
24069
  "use memo";
23468
24070
  const layoutElementRef = useRef12(null);
23469
24071
  const railResizeInteractionRef = useRef12(null);
23470
- const [isRailResizing, setIsRailResizing] = useState11(false);
23471
- const [railResizeWidthPx, setRailResizeWidthPx] = useState11(
24072
+ const [isRailResizing, setIsRailResizing] = useState12(false);
24073
+ const [railResizeWidthPx, setRailResizeWidthPx] = useState12(
23472
24074
  null
23473
24075
  );
23474
- const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState11(false);
23475
- const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState11(null);
24076
+ const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState12(false);
24077
+ const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState12(null);
23476
24078
  const [
23477
24079
  localComposerFocusRequestSequence,
23478
24080
  setLocalComposerFocusRequestSequence
23479
- ] = useState11(0);
24081
+ ] = useState12(0);
23480
24082
  const handledNewConversationRequestSequenceRef = useRef12(
23481
24083
  newConversationRequestSequence
23482
24084
  );
@@ -23644,7 +24246,7 @@ function AgentGUINodeView({
23644
24246
  viewModel.composerSettings.selectedProjectPath
23645
24247
  ]
23646
24248
  );
23647
- useEffect12(() => {
24249
+ useEffect13(() => {
23648
24250
  if (newConversationRequestSequence === null || handledNewConversationRequestSequenceRef.current === newConversationRequestSequence) {
23649
24251
  return;
23650
24252
  }
@@ -23734,7 +24336,7 @@ function AgentGUINodeView({
23734
24336
  },
23735
24337
  [onConversationRailWidthChanged]
23736
24338
  );
23737
- useEffect12(() => {
24339
+ useEffect13(() => {
23738
24340
  if (isRailResizing || railResizeWidthPx === null) {
23739
24341
  return;
23740
24342
  }
@@ -23774,13 +24376,22 @@ function AgentGUINodeView({
23774
24376
  ]
23775
24377
  );
23776
24378
  const visualConversationRailWidthPx = isRailResizing ? railResizeInteractionRef.current?.lastWidthPx ?? conversationRailWidthPx : railResizeWidthPx ?? conversationRailWidthPx;
24379
+ const effectiveConversationRailWidthPx = conversationRailCollapsed ? 0 : visualConversationRailWidthPx;
24380
+ const showProviderRail = true;
24381
+ const renderProviderRail = showProviderRail && !conversationRailCollapsed;
23777
24382
  const layoutStyle = {
23778
- "--agent-gui-conversation-rail-width": `${visualConversationRailWidthPx}px`,
24383
+ "--agent-gui-conversation-rail-width": `${effectiveConversationRailWidthPx}px`,
24384
+ "--agent-gui-conversation-rail-content-width": `${visualConversationRailWidthPx}px`,
23779
24385
  "--agent-gui-detail-min-width": `${detailMinWidthPx}px`,
23780
- 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)"
24386
+ "--agent-gui-provider-rail-width": renderProviderRail ? "52px" : "0px",
24387
+ 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)"
23781
24388
  };
23782
24389
  const effectiveRailConfigProvider = railConfigProvider === void 0 ? viewModel.data.provider : railConfigProvider;
23783
24390
  const effectiveRailSlashStatusLimits = railSlashStatusLimits ?? slashStatusLimits;
24391
+ const enabledProviderTargets = viewModel.providerTargets.filter(
24392
+ (target) => target.disabled !== true && ((target.agentTargetId?.trim() ?? "") || (target.targetId?.trim() ?? ""))
24393
+ );
24394
+ const sectionAgentTargetFallbackId = enabledProviderTargets.length <= 1 ? viewModel.selectedProviderTarget.agentTargetId?.trim() || viewModel.selectedProviderTarget.targetId?.trim() || null : null;
23784
24395
  const openAgentEnvSetup = useCallback10(() => {
23785
24396
  if (!effectiveRailConfigProvider) {
23786
24397
  return;
@@ -23806,8 +24417,8 @@ function AgentGUINodeView({
23806
24417
  selectedProviderTarget: viewModel.selectedProviderTarget,
23807
24418
  providerTargets: viewModel.providerTargets,
23808
24419
  providerTargetsLoading: viewModel.providerTargetsLoading,
23809
- conversationScope: viewModel.conversationScope,
23810
24420
  conversationFilter: viewModel.conversationFilter,
24421
+ sectionAgentTargetFallbackId,
23811
24422
  onCreateConversation: requestCreateConversation,
23812
24423
  onUpdateConversationFilter: actions.updateConversationFilter,
23813
24424
  onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
@@ -23845,6 +24456,7 @@ function AgentGUINodeView({
23845
24456
  retryOpenclawGateway,
23846
24457
  selectConversation,
23847
24458
  selectProjectDirectory,
24459
+ sectionAgentTargetFallbackId,
23848
24460
  effectiveRailConfigProvider,
23849
24461
  effectiveRailSlashStatusLimits,
23850
24462
  viewModel.selectedProviderTarget,
@@ -23852,7 +24464,6 @@ function AgentGUINodeView({
23852
24464
  viewModel.providerTargetsLoading,
23853
24465
  toggleConversationPinned,
23854
24466
  uiLanguage,
23855
- viewModel.conversationScope,
23856
24467
  viewModel.conversationFilter,
23857
24468
  viewModel.activeConversationId,
23858
24469
  viewModel.isDeletingConversation,
@@ -23900,6 +24511,28 @@ function AgentGUINodeView({
23900
24511
  inert: previewMode ? true : void 0,
23901
24512
  style: layoutStyle,
23902
24513
  children: [
24514
+ showProviderRail ? /* @__PURE__ */ jsx31(
24515
+ "aside",
24516
+ {
24517
+ className: AgentGUINode_styles_default.providerRailPanel,
24518
+ "aria-label": labels.providerSwitchLabel,
24519
+ "aria-hidden": conversationRailCollapsed ? "true" : void 0,
24520
+ inert: conversationRailCollapsed ? true : void 0,
24521
+ children: /* @__PURE__ */ jsx31(
24522
+ AgentGUIProviderRail,
24523
+ {
24524
+ conversationFilter: viewModel.conversationFilter,
24525
+ labels,
24526
+ previewMode,
24527
+ selectedProviderTarget: viewModel.selectedProviderTarget,
24528
+ providerTargets: viewModel.providerTargets,
24529
+ providerTargetsLoading: viewModel.providerTargetsLoading,
24530
+ onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
24531
+ onUpdateConversationFilter: actions.updateConversationFilter
24532
+ }
24533
+ )
24534
+ }
24535
+ ) : null,
23903
24536
  /* @__PURE__ */ jsx31(
23904
24537
  "aside",
23905
24538
  {
@@ -23958,6 +24591,7 @@ function AgentGUINodeView({
23958
24591
  slashStatusLimits,
23959
24592
  slashStatusLimitsLoading,
23960
24593
  onLinkAction,
24594
+ onHandoffConversation,
23961
24595
  capabilityMenuState,
23962
24596
  onCapabilitySettingsRequest,
23963
24597
  onAgentProviderLogin,
@@ -24078,6 +24712,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24078
24712
  slashStatusLimits,
24079
24713
  slashStatusLimitsLoading,
24080
24714
  onLinkAction,
24715
+ onHandoffConversation,
24081
24716
  capabilityMenuState,
24082
24717
  onCapabilitySettingsRequest,
24083
24718
  onAgentProviderLogin,
@@ -24094,18 +24729,20 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24094
24729
  const timelineScrollAnchorRef = useRef12(null);
24095
24730
  const submittedPromptScrollConversationRef = useRef12(null);
24096
24731
  const pendingPrependScrollAnchorRef = useRef12(null);
24097
- const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState11(true);
24732
+ const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState12(true);
24733
+ const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState12(true);
24098
24734
  const [
24099
24735
  bottomDockDismissedPromptRequestId,
24100
24736
  setBottomDockDismissedPromptRequestId
24101
- ] = useState11(null);
24737
+ ] = useState12(null);
24102
24738
  const conversation = useProjectedAgentConversation({
24103
24739
  conversation: viewModel.conversation,
24104
24740
  detail: viewModel.conversationDetail,
24105
24741
  avoidGroupingEdits: viewModel.avoidGroupingEdits
24106
24742
  });
24107
24743
  const hasActiveConversation = viewModel.activeConversationId !== null;
24108
- const emptyProviderReadinessGate = !hasActiveConversation ? viewModel.providerReadinessGate : null;
24744
+ const selectedProviderTargetComingSoon = viewModel.selectedProviderTarget?.disabled === true;
24745
+ const emptyProviderReadinessGate = !hasActiveConversation ? selectedProviderTargetComingSoon ? { status: "coming_soon" } : viewModel.providerReadinessGate : null;
24109
24746
  const activePrompt = viewModel.pendingInteractivePrompt ?? viewModel.pendingApproval;
24110
24747
  const activePromptRequestId = activePrompt?.requestId ?? null;
24111
24748
  const sessionChrome = useMemo10(
@@ -24252,26 +24889,32 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24252
24889
  );
24253
24890
  const goalBannerLabels = useMemo10(
24254
24891
  () => ({
24255
- goalLabel: labels.goalLabel,
24256
- statusActive: labels.goalStatusActive,
24257
- statusPaused: labels.goalStatusPaused,
24258
- statusBlocked: labels.goalStatusBlocked,
24259
- statusUsageLimited: labels.goalStatusUsageLimited,
24260
- statusBudgetLimited: labels.goalStatusBudgetLimited,
24261
- statusComplete: labels.goalStatusComplete,
24892
+ titleActive: labels.goalTitleActive,
24893
+ titlePaused: labels.goalTitlePaused,
24894
+ titleBlocked: labels.goalTitleBlocked,
24895
+ titleUsageLimited: labels.goalTitleUsageLimited,
24896
+ titleBudgetLimited: labels.goalTitleBudgetLimited,
24897
+ titleComplete: labels.goalTitleComplete,
24262
24898
  budgetUsage: labels.goalBudgetUsage,
24263
- clearHint: labels.goalClearHint
24899
+ clearHint: labels.goalClearHint,
24900
+ editAction: labels.goalEditAction,
24901
+ pauseAction: labels.goalPauseAction,
24902
+ resumeAction: labels.goalResumeAction,
24903
+ clearAction: labels.goalClearAction
24264
24904
  }),
24265
24905
  [
24266
- labels.goalLabel,
24267
- labels.goalStatusActive,
24268
- labels.goalStatusPaused,
24269
- labels.goalStatusBlocked,
24270
- labels.goalStatusUsageLimited,
24271
- labels.goalStatusBudgetLimited,
24272
- labels.goalStatusComplete,
24906
+ labels.goalTitleActive,
24907
+ labels.goalTitlePaused,
24908
+ labels.goalTitleBlocked,
24909
+ labels.goalTitleUsageLimited,
24910
+ labels.goalTitleBudgetLimited,
24911
+ labels.goalTitleComplete,
24273
24912
  labels.goalBudgetUsage,
24274
- labels.goalClearHint
24913
+ labels.goalClearHint,
24914
+ labels.goalEditAction,
24915
+ labels.goalPauseAction,
24916
+ labels.goalResumeAction,
24917
+ labels.goalClearAction
24275
24918
  ]
24276
24919
  );
24277
24920
  const interactivePromptLabels = useMemo10(
@@ -24421,6 +25064,8 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24421
25064
  addReference: labels.addReference,
24422
25065
  addContent: labels.addContent,
24423
25066
  referenceWorkspaceFiles: labels.referenceWorkspaceFiles,
25067
+ handoffConversation: labels.handoffConversation,
25068
+ handoffConversationMenu: labels.handoffConversationMenu,
24424
25069
  providerSwitchLabel: labels.providerSwitchLabel,
24425
25070
  projectLocked: labels.projectLocked,
24426
25071
  projectMissingDescription: labels.projectMissingDescription,
@@ -24440,6 +25085,8 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24440
25085
  labels.fileMentionLoading,
24441
25086
  labels.fileMentionPalette,
24442
25087
  labels.fileMentionTabHint,
25088
+ labels.handoffConversation,
25089
+ labels.handoffConversationMenu,
24443
25090
  labels.inheritedUnavailable,
24444
25091
  labels.loadingConversation,
24445
25092
  labels.modelLabel,
@@ -24558,6 +25205,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24558
25205
  actions.updateComposerSettings
24559
25206
  );
24560
25207
  const submitPrompt = useStableEventCallback2(actions.submitPrompt);
25208
+ const goalControl = useStableEventCallback2(actions.goalControl);
24561
25209
  const submitGuidancePrompt = useStableEventCallback2(
24562
25210
  actions.submitGuidancePrompt
24563
25211
  );
@@ -24619,17 +25267,22 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24619
25267
  },
24620
25268
  [submitInteractivePrompt]
24621
25269
  );
24622
- const canSwitchComposerProvider = viewModel.conversationScope === "multi-provider";
24623
- const composerProviderTargets = canSwitchComposerProvider ? viewModel.providerTargets : [viewModel.selectedProviderTarget];
25270
+ const canSwitchComposerProvider = true;
25271
+ const composerProviderTargets = viewModel.providerTargets;
25272
+ const composerProvider = viewModel.activeConversationId === null ? viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider : viewModel.data.provider;
25273
+ const composerSelectedProviderTarget = viewModel.activeConversationId === null ? viewModel.selectedProviderTarget : viewModel.providerTargets.find((target) => {
25274
+ if (target.provider !== viewModel.data.provider) {
25275
+ return false;
25276
+ }
25277
+ const agentTargetId = viewModel.data.agentTargetId;
25278
+ return !agentTargetId || target.targetId === agentTargetId || target.agentTargetId === agentTargetId;
25279
+ }) ?? viewModel.selectedProviderTarget;
24624
25280
  const bottomDockComposerProps = useMemo10(
24625
25281
  () => ({
24626
25282
  workspaceId: viewModel.workspaceId,
24627
25283
  workspacePath: viewModel.workspacePath,
24628
25284
  currentUserId: viewModel.currentUserId,
24629
- provider: viewModel.data.provider,
24630
- selectedProviderTarget: viewModel.selectedProviderTarget,
24631
- providerTargets: composerProviderTargets,
24632
- providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
25285
+ provider: composerProvider,
24633
25286
  slashStatus,
24634
25287
  usage: viewModel.usage,
24635
25288
  draftContent: viewModel.draftContent,
@@ -24637,8 +25290,13 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24637
25290
  hasCompactableContext: viewModel.hasSentUserMessage,
24638
25291
  compactSupported: viewModel.compactSupported,
24639
25292
  availableSkills: viewModel.availableSkills,
25293
+ selectedProviderTarget: composerSelectedProviderTarget,
25294
+ providerTargets: composerProviderTargets,
25295
+ providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
25296
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? actions.selectHomeComposerAgentTarget : void 0,
24640
25297
  disabled: composerDisabled,
24641
25298
  disabledReason: composerDisabledReason,
25299
+ hasActiveConversation: viewModel.activeConversationId !== null,
24642
25300
  submitDisabled,
24643
25301
  composerSettings: viewModel.composerSettings,
24644
25302
  queuedPrompts: viewModel.queuedPrompts,
@@ -24658,6 +25316,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24658
25316
  composerFocusRequestSequence,
24659
25317
  isActive,
24660
25318
  promptImagesSupported: viewModel.promptImagesSupported,
25319
+ providerSelectLabel: labels.providerSwitchLabel,
25320
+ handoffLabel: labels.handoffConversation,
25321
+ handoffMenuLabel: labels.handoffConversationMenu,
24661
25322
  isInterrupting: viewModel.isInterrupting,
24662
25323
  isSendingTurn: isComposerSending,
24663
25324
  isSubmittingPrompt: viewModel.isRespondingApproval,
@@ -24668,7 +25329,6 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24668
25329
  onDraftContentChange: updateDraftContent,
24669
25330
  onProjectPathChange: updateSelectedProjectPath,
24670
25331
  onSettingsChange: updateComposerSettings,
24671
- onProviderSelect: canSwitchComposerProvider ? actions.selectProvider : void 0,
24672
25332
  onSubmit: submitPromptAndScrollToBottom,
24673
25333
  onSubmitGuidance: submitGuidancePromptAndScrollToBottom,
24674
25334
  onPromptImagesUnsupported: showPromptImagesUnsupported,
@@ -24679,6 +25339,21 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24679
25339
  onSubmitInteractivePrompt: submitInteractivePrompt,
24680
25340
  onCapabilitySettingsRequest,
24681
25341
  onLinkAction: stableLinkAction,
25342
+ onHandoffConversation: onHandoffConversation && viewModel.activeConversationId !== null ? (target) => onHandoffConversation({
25343
+ agentTargetId: target.agentTargetId ?? target.targetId,
25344
+ draftPrompt: buildAgentConversationHandoffPrompt({
25345
+ activeConversation: viewModel.activeConversation,
25346
+ currentUserId: viewModel.currentUserId,
25347
+ labels,
25348
+ selectedProviderTarget: composerSelectedProviderTarget,
25349
+ uiLanguage,
25350
+ workspaceId: viewModel.workspaceId
25351
+ }),
25352
+ provider: target.provider,
25353
+ userProjectPath: handoffProjectPathForConversation(
25354
+ viewModel.activeConversation
25355
+ )
25356
+ }) : void 0,
24682
25357
  onRequestWorkspaceReferences: stableRequestWorkspaceReferences,
24683
25358
  resolveDroppedFileReferences,
24684
25359
  selectProjectDirectory: stableSelectProjectDirectory,
@@ -24688,19 +25363,26 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24688
25363
  [
24689
25364
  canQueueWhileBusy,
24690
25365
  backgroundAgentStatusText,
24691
- canSwitchComposerProvider,
25366
+ actions.selectHomeComposerAgentTarget,
24692
25367
  capabilityMenuState,
24693
- composerProviderTargets,
25368
+ canSwitchComposerProvider,
24694
25369
  composerDisabled,
24695
25370
  composerDisabledReason,
24696
25371
  composerFocusRequestSequence,
24697
25372
  composerLabels,
25373
+ composerProviderTargets,
25374
+ composerSelectedProviderTarget,
24698
25375
  handleInterruptCurrentTurn,
24699
25376
  isActive,
24700
25377
  isComposerSending,
24701
25378
  labels.followupPlaceholder,
25379
+ labels.handoffConversation,
25380
+ labels.handoffConversationMenu,
24702
25381
  labels.initialPlaceholder,
24703
25382
  labels.promptTips,
25383
+ labels.providerSwitchLabel,
25384
+ labels,
25385
+ onHandoffConversation,
24704
25386
  previewMode,
24705
25387
  workspaceReferencePickerOpen,
24706
25388
  composerActivePrompt,
@@ -24723,16 +25405,17 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24723
25405
  stableSelectProjectDirectory,
24724
25406
  stableRequestWorkspaceReferences,
24725
25407
  updateComposerSettings,
24726
- actions.selectProvider,
24727
25408
  updateDraftContent,
24728
25409
  updateSelectedProjectPath,
25410
+ viewModel.activeConversationId,
24729
25411
  viewModel.availableCommands,
24730
25412
  viewModel.availableSkills,
24731
25413
  viewModel.compactSupported,
24732
25414
  viewModel.composerSettings,
24733
25415
  viewModel.currentUserId,
24734
- viewModel.data.provider,
24735
- viewModel.selectedProviderTarget,
25416
+ viewModel.activeConversationId,
25417
+ viewModel.activeConversation,
25418
+ composerProvider,
24736
25419
  viewModel.draftContent,
24737
25420
  viewModel.draftPrompt,
24738
25421
  viewModel.drainingQueuedPromptId,
@@ -24756,6 +25439,12 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24756
25439
  [bottomDockComposerProps]
24757
25440
  );
24758
25441
  const emptyHeroProvider = viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider;
25442
+ const emptyHeroProviderLabel = labels.emptyProviderForProvider?.(emptyHeroProvider) ?? labels.emptyProvider ?? "";
25443
+ const emptyHeroLabel = labels.emptyForProvider?.(emptyHeroProvider) ?? labels.empty;
25444
+ const emptyHeroIconPresentations = useMemo10(
25445
+ () => viewModel.conversationFilter.kind === "all" ? agentGUILaunchpadIconPresentations() : [agentGUIProviderIconPresentation(emptyHeroProvider)],
25446
+ [emptyHeroProvider, viewModel.conversationFilter]
25447
+ );
24759
25448
  const bottomDockStoreState = useMemo10(
24760
25449
  () => ({
24761
25450
  // The lifted prompt is rendered from props on the pane; the store still
@@ -24792,7 +25481,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24792
25481
  viewModel.drainingQueuedPromptId ?? "",
24793
25482
  viewModel.isRespondingApproval ? "1" : "0"
24794
25483
  ].join("|");
24795
- useEffect12(() => {
25484
+ useEffect13(() => {
24796
25485
  setBottomDockDismissedPromptRequestId(null);
24797
25486
  }, [activePromptRequestId]);
24798
25487
  useLayoutEffect4(() => {
@@ -24806,6 +25495,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24806
25495
  pendingPrependScrollAnchorRef.current = null;
24807
25496
  submittedPromptScrollConversationRef.current = null;
24808
25497
  setIsTimelineScrolledToTop(true);
25498
+ setIsTimelineScrolledToBottom(true);
24809
25499
  return;
24810
25500
  }
24811
25501
  const maxScrollTop = Math.max(
@@ -24856,6 +25546,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24856
25546
  setIsTimelineScrolledToTop(
24857
25547
  nextScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
24858
25548
  );
25549
+ setIsTimelineScrolledToBottom(
25550
+ maxScrollTop - nextScrollTop <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX
25551
+ );
24859
25552
  }, [
24860
25553
  conversation,
24861
25554
  showTimelineSkeleton,
@@ -24874,6 +25567,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24874
25567
  const bottomDockRect = bottomDock.getBoundingClientRect();
24875
25568
  let visualTop = bottomDockRect.top;
24876
25569
  bottomDock.querySelectorAll("*").forEach((element) => {
25570
+ if (element.closest(`.${AgentGUINode_styles_default.bottomDockScrollToBottom}`)) {
25571
+ return;
25572
+ }
24877
25573
  const rect = element.getBoundingClientRect();
24878
25574
  if (rect.width > 0 && rect.height > 0) {
24879
25575
  visualTop = Math.min(visualTop, rect.top);
@@ -24887,6 +25583,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24887
25583
  "--agent-gui-bottom-dock-safe-area",
24888
25584
  `${overflowHeight}px`
24889
25585
  );
25586
+ bottomDock.style.setProperty(
25587
+ "--agent-gui-bottom-dock-floating-safe-area",
25588
+ `${overflowHeight}px`
25589
+ );
24890
25590
  };
24891
25591
  const syncBottomDockSpace = () => {
24892
25592
  syncBottomDockSafeArea();
@@ -24917,12 +25617,16 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24917
25617
  setIsTimelineScrolledToTop(
24918
25618
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
24919
25619
  );
25620
+ setIsTimelineScrolledToBottom(true);
24920
25621
  });
24921
25622
  };
24922
25623
  syncBottomDockSpace();
24923
25624
  if (typeof ResizeObserver === "undefined") {
24924
25625
  return () => {
24925
25626
  timeline.style.removeProperty("--agent-gui-bottom-dock-safe-area");
25627
+ bottomDock.style.removeProperty(
25628
+ "--agent-gui-bottom-dock-floating-safe-area"
25629
+ );
24926
25630
  if (animationFrameId !== null) {
24927
25631
  window.cancelAnimationFrame(animationFrameId);
24928
25632
  }
@@ -24938,13 +25642,16 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24938
25642
  }
24939
25643
  return () => {
24940
25644
  timeline.style.removeProperty("--agent-gui-bottom-dock-safe-area");
25645
+ bottomDock.style.removeProperty(
25646
+ "--agent-gui-bottom-dock-floating-safe-area"
25647
+ );
24941
25648
  if (animationFrameId !== null) {
24942
25649
  window.cancelAnimationFrame(animationFrameId);
24943
25650
  }
24944
25651
  observer.disconnect();
24945
25652
  };
24946
25653
  }, [bottomDockStoreRevision, viewModel.activeConversationId]);
24947
- useEffect12(() => {
25654
+ useEffect13(() => {
24948
25655
  const timeline = timelineRef.current;
24949
25656
  const activeConversationId = viewModel.activeConversationId;
24950
25657
  if (!timeline || !activeConversationId) {
@@ -24961,6 +25668,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24961
25668
  setIsTimelineScrolledToTop(
24962
25669
  scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
24963
25670
  );
25671
+ setIsTimelineScrolledToBottom(
25672
+ timeline.scrollHeight - scrollTop - timeline.clientHeight <= AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX
25673
+ );
24964
25674
  if (viewModel.hasOlderMessages && !viewModel.isLoadingOlderMessages && scrollTop <= AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX) {
24965
25675
  pendingPrependScrollAnchorRef.current = {
24966
25676
  conversationId: activeConversationId,
@@ -24981,6 +25691,28 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24981
25691
  viewModel.hasOlderMessages,
24982
25692
  viewModel.isLoadingOlderMessages
24983
25693
  ]);
25694
+ const scrollTimelineToBottom = useCallback10(() => {
25695
+ const timeline = timelineRef.current;
25696
+ const activeConversationId = viewModel.activeConversationId;
25697
+ if (!timeline || !activeConversationId) {
25698
+ return;
25699
+ }
25700
+ const maxScrollTop = Math.max(
25701
+ 0,
25702
+ timeline.scrollHeight - timeline.clientHeight
25703
+ );
25704
+ setTimelineScrollTopWithUserTransition(timeline, maxScrollTop);
25705
+ timelineScrollAnchorRef.current = {
25706
+ conversationId: activeConversationId,
25707
+ scrollHeight: timeline.scrollHeight,
25708
+ scrollTop: maxScrollTop,
25709
+ clientHeight: timeline.clientHeight
25710
+ };
25711
+ setIsTimelineScrolledToTop(
25712
+ maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
25713
+ );
25714
+ setIsTimelineScrolledToBottom(true);
25715
+ }, [viewModel.activeConversationId]);
24984
25716
  return /* @__PURE__ */ jsxs17("main", { className: AgentGUINode_styles_default.detail, children: [
24985
25717
  /* @__PURE__ */ jsx31(
24986
25718
  AgentGUIDetailHeader,
@@ -25032,7 +25764,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25032
25764
  ScrollArea,
25033
25765
  {
25034
25766
  scrollbarMode: "native",
25035
- className: "min-h-0 flex-1 [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
25767
+ className: "flex h-full min-h-0 flex-1 flex-col [&_[data-orientation=vertical][data-slot=scroll-area-scrollbar]]:opacity-100",
25036
25768
  viewportRef: timelineRef,
25037
25769
  viewportTestId: "agent-gui-timeline",
25038
25770
  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(),
@@ -25042,22 +25774,28 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25042
25774
  {
25043
25775
  provider: emptyHeroProvider,
25044
25776
  gate: emptyProviderReadinessGate,
25777
+ showAllProviders: viewModel.conversationFilter.kind === "all",
25045
25778
  labels
25046
25779
  }
25047
25780
  ) : /* @__PURE__ */ jsx31(
25048
25781
  AgentGUIEmptyHeroPane,
25049
25782
  {
25050
25783
  provider: emptyHeroProvider,
25051
- emptyLabel: labels.empty,
25052
- emptyProvider: labels.emptyProvider ?? "",
25784
+ emptyLabel: emptyHeroLabel,
25785
+ emptyProvider: emptyHeroProviderLabel,
25786
+ iconPresentations: emptyHeroIconPresentations,
25053
25787
  inlineNoticeChrome,
25054
25788
  isRespondingApproval: viewModel.isRespondingApproval,
25055
25789
  onSubmitApprovalOption: submitApprovalOption,
25056
25790
  onRetryActivation: retryActivation,
25057
25791
  onAuthLogin: authLogin,
25058
25792
  onContinueInNewConversation: continueInNewConversation,
25793
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? actions.selectHomeComposerAgentTarget : void 0,
25794
+ providerTargets: composerProviderTargets,
25795
+ selectedProviderTarget: viewModel.selectedProviderTarget,
25059
25796
  chromeLabels,
25060
- composerProps: emptyHeroComposerProps
25797
+ composerProps: emptyHeroComposerProps,
25798
+ providerSelectLabel: labels.providerSwitchLabel
25061
25799
  }
25062
25800
  ) : /* @__PURE__ */ jsx31(
25063
25801
  AgentGUIConversationTimelinePane,
@@ -25081,6 +25819,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25081
25819
  AgentGUIBottomDockPane,
25082
25820
  {
25083
25821
  bottomDockRef,
25822
+ showScrollToBottom: !isTimelineScrolledToBottom,
25823
+ scrollToBottomLabel: labels.scrollToBottom,
25824
+ onScrollToBottom: scrollTimelineToBottom,
25084
25825
  bottomDockLiftedPrompt,
25085
25826
  bottomDockReplacementPrompt,
25086
25827
  store: bottomDockStore,
@@ -25093,7 +25834,9 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
25093
25834
  onRetryActivation: retryActivation,
25094
25835
  onAuthLogin: authLogin,
25095
25836
  onContinueInNewConversation: continueInNewConversation,
25096
- onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt
25837
+ onSubmitBottomDockInteractivePrompt: submitBottomDockInteractivePrompt,
25838
+ onGoalControl: goalControl,
25839
+ goalPauseSupported: viewModel.goalPauseSupported
25097
25840
  }
25098
25841
  ) : null
25099
25842
  ] });
@@ -25195,29 +25938,52 @@ var AgentGUIEmptyHeroPane = memo(function AgentGUIEmptyHeroPane2({
25195
25938
  provider,
25196
25939
  emptyLabel,
25197
25940
  emptyProvider,
25941
+ iconPresentations,
25198
25942
  inlineNoticeChrome,
25199
25943
  isRespondingApproval,
25200
25944
  onSubmitApprovalOption,
25201
25945
  onAuthLogin,
25202
25946
  onRetryActivation,
25203
25947
  onContinueInNewConversation,
25948
+ onProviderSelect,
25949
+ providerTargets,
25950
+ selectedProviderTarget,
25204
25951
  chromeLabels,
25205
- composerProps
25952
+ composerProps,
25953
+ providerSelectLabel
25206
25954
  }) {
25207
25955
  "use memo";
25208
- const heroIconUrl = resolveAgentGUIHeroIconUrl(provider);
25956
+ const heroIconPresentations = iconPresentations.length > 0 ? iconPresentations : [agentGUIProviderIconPresentation(provider)];
25957
+ const heroIconAnimationKey = heroIconPresentations.map((icon) => `${icon.provider}:${icon.iconUrl}`).join("|");
25209
25958
  return /* @__PURE__ */ jsx31("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.emptyHeroBody, children: [
25210
- /* @__PURE__ */ jsx31(
25211
- "img",
25959
+ heroIconPresentations.length > 1 ? /* @__PURE__ */ jsx31(
25960
+ AgentGUIAllProviderGridIcon,
25212
25961
  {
25213
- "aria-hidden": "true",
25214
- className: AgentGUINode_styles_default.emptyHeroIconEffect,
25215
- draggable: false,
25216
- src: heroIconUrl,
25217
- alt: ""
25218
- }
25962
+ activeProvider: provider,
25963
+ className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
25964
+ icons: heroIconPresentations
25965
+ },
25966
+ heroIconAnimationKey
25967
+ ) : /* @__PURE__ */ jsx31(
25968
+ AgentGUIProviderIconVisual,
25969
+ {
25970
+ ariaHidden: true,
25971
+ imageClassName: AgentGUINode_styles_default.emptyHeroIconEffect,
25972
+ icon: heroIconPresentations[0]
25973
+ },
25974
+ heroIconAnimationKey
25219
25975
  ),
25220
- /* @__PURE__ */ jsx31("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: /* @__PURE__ */ jsx31(EmptyHeroTitle, { label: emptyLabel, providerLabel: emptyProvider }) }),
25976
+ /* @__PURE__ */ jsx31("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: /* @__PURE__ */ jsx31(
25977
+ EmptyHeroTitle,
25978
+ {
25979
+ label: emptyLabel,
25980
+ providerLabel: emptyProvider,
25981
+ providerSelectLabel,
25982
+ providerTargets,
25983
+ selectedProviderTarget,
25984
+ onProviderSelect
25985
+ }
25986
+ ) }),
25221
25987
  inlineNoticeChrome ? /* @__PURE__ */ jsx31(
25222
25988
  AgentSessionChrome,
25223
25989
  {
@@ -25237,13 +26003,21 @@ var AgentGUIProviderReadinessGatePane = memo(
25237
26003
  function AgentGUIProviderReadinessGatePane2({
25238
26004
  provider,
25239
26005
  gate,
26006
+ showAllProviders = false,
25240
26007
  labels
25241
26008
  }) {
25242
26009
  "use memo";
25243
26010
  const heroIconUrl = resolveAgentGUIHeroIconUrl(provider);
26011
+ const launchpadIconPresentations = useMemo10(
26012
+ () => agentGUILaunchpadIconPresentations(),
26013
+ []
26014
+ );
25244
26015
  const pendingAction = gate.pendingAction ?? null;
25245
26016
  const isPending = pendingAction !== null;
25246
- const content = providerGateContent(gate.status, labels);
26017
+ const showAllProvidersChecking = showAllProviders && gate.status === "checking";
26018
+ const content = providerGateContent(gate.status, labels, {
26019
+ showAllProviders: showAllProvidersChecking
26020
+ });
25247
26021
  const action = providerGateAction(gate.status);
25248
26022
  const pendingLabel = pendingAction === "install" ? labels.providerGatePendingInstall : pendingAction === "login" ? labels.providerGatePendingLogin : pendingAction === "refresh" ? labels.providerGatePendingRefresh : null;
25249
26023
  return /* @__PURE__ */ jsx31("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs17(
@@ -25253,7 +26027,13 @@ var AgentGUIProviderReadinessGatePane = memo(
25253
26027
  "data-testid": "agent-gui-provider-readiness-gate",
25254
26028
  role: "status",
25255
26029
  children: [
25256
- /* @__PURE__ */ jsx31(
26030
+ showAllProvidersChecking ? /* @__PURE__ */ jsx31(
26031
+ AgentGUIAllProviderGridIcon,
26032
+ {
26033
+ className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
26034
+ icons: launchpadIconPresentations
26035
+ }
26036
+ ) : /* @__PURE__ */ jsx31(
25257
26037
  "img",
25258
26038
  {
25259
26039
  "aria-hidden": "true",
@@ -25273,7 +26053,7 @@ var AgentGUIProviderReadinessGatePane = memo(
25273
26053
  children: pendingLabel
25274
26054
  }
25275
26055
  ) : null,
25276
- action ? /* @__PURE__ */ jsxs17(
26056
+ action ? /* @__PURE__ */ jsx31(
25277
26057
  Button,
25278
26058
  {
25279
26059
  type: "button",
@@ -25290,10 +26070,20 @@ var AgentGUIProviderReadinessGatePane = memo(
25290
26070
  }
25291
26071
  gate.onAction?.(provider, action);
25292
26072
  },
25293
- children: [
25294
- /* @__PURE__ */ jsx31(Wrench, { size: 16, strokeWidth: 2, "aria-hidden": "true" }),
25295
- isPending && pendingLabel ? pendingLabel : content.actionLabel
25296
- ]
26073
+ children: isPending && pendingLabel ? pendingLabel : content.actionLabel
26074
+ }
26075
+ ) : content.actionLabel ? /* @__PURE__ */ jsx31(
26076
+ Button,
26077
+ {
26078
+ type: "button",
26079
+ className: cn3(
26080
+ AgentGUINode_styles_default.emptyProviderGateAction,
26081
+ "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]"
26082
+ ),
26083
+ "data-testid": "agent-gui-provider-readiness-gate-action",
26084
+ disabled: true,
26085
+ onPointerDown: (event) => event.stopPropagation(),
26086
+ children: content.actionLabel
25297
26087
  }
25298
26088
  ) : null
25299
26089
  ]
@@ -25301,12 +26091,12 @@ var AgentGUIProviderReadinessGatePane = memo(
25301
26091
  ) });
25302
26092
  }
25303
26093
  );
25304
- function providerGateContent(status, labels) {
26094
+ function providerGateContent(status, labels, options = {}) {
25305
26095
  switch (status) {
25306
26096
  case "checking":
25307
26097
  return {
25308
26098
  title: labels.providerGateCheckingTitle,
25309
- description: labels.providerGateCheckingDescription
26099
+ description: options.showAllProviders === true ? labels.providerGateCheckingAgentsDescription : labels.providerGateCheckingDescription
25310
26100
  };
25311
26101
  case "not_installed":
25312
26102
  return {
@@ -25320,6 +26110,12 @@ function providerGateContent(status, labels) {
25320
26110
  description: labels.providerGateLoginDescription,
25321
26111
  actionLabel: labels.providerGateLoginAction
25322
26112
  };
26113
+ case "coming_soon":
26114
+ return {
26115
+ title: labels.providerGateComingSoonTitle,
26116
+ description: labels.providerGateComingSoonDescription,
26117
+ actionLabel: labels.providerGateComingSoonAction
26118
+ };
25323
26119
  case "unavailable":
25324
26120
  return {
25325
26121
  title: labels.providerGateUnavailableTitle,
@@ -25336,27 +26132,167 @@ function providerGateAction(status) {
25336
26132
  return "login";
25337
26133
  case "unavailable":
25338
26134
  return "refresh";
26135
+ case "coming_soon":
25339
26136
  case "checking":
25340
26137
  return null;
25341
26138
  }
25342
26139
  }
26140
+ function AgentGUIAllProviderGridIcon({
26141
+ activeProvider,
26142
+ className,
26143
+ icons
26144
+ }) {
26145
+ return /* @__PURE__ */ jsx31(
26146
+ "span",
26147
+ {
26148
+ "aria-hidden": "true",
26149
+ className: [AgentGUINode_styles_default.providerRailAvatar, className].filter(Boolean).join(" "),
26150
+ children: /* @__PURE__ */ jsx31(
26151
+ AgentGUILaunchpadIconGrid,
26152
+ {
26153
+ activeProvider,
26154
+ icons
26155
+ }
26156
+ )
26157
+ }
26158
+ );
26159
+ }
26160
+ function AgentGUILaunchpadIconGrid({
26161
+ activeProvider,
26162
+ icons
26163
+ }) {
26164
+ const normalizedActiveProvider = activeProvider ? normalizeManagedAgentProvider(activeProvider) : null;
26165
+ return /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map((icon) => {
26166
+ return /* @__PURE__ */ jsx31(
26167
+ "span",
26168
+ {
26169
+ className: AgentGUINode_styles_default.providerRailLaunchpadItem,
26170
+ "data-provider-active": normalizedActiveProvider === null ? void 0 : normalizeManagedAgentProvider(icon.provider) === normalizedActiveProvider,
26171
+ children: /* @__PURE__ */ jsx31(AgentGUIProviderIconVisual, { imageClassName: "", icon })
26172
+ },
26173
+ `${icon.provider}:${icon.iconUrl}`
26174
+ );
26175
+ }) });
26176
+ }
26177
+ function AgentGUIProviderIconVisual({
26178
+ ariaHidden = false,
26179
+ icon,
26180
+ imageClassName
26181
+ }) {
26182
+ return /* @__PURE__ */ jsx31(
26183
+ "img",
26184
+ {
26185
+ alt: "",
26186
+ "aria-hidden": ariaHidden ? "true" : void 0,
26187
+ className: imageClassName,
26188
+ draggable: false,
26189
+ src: icon.iconUrl
26190
+ }
26191
+ );
26192
+ }
25343
26193
  function EmptyHeroTitle({
25344
26194
  label,
25345
- providerLabel
26195
+ providerLabel,
26196
+ providerSelectLabel,
26197
+ providerTargets = [],
26198
+ selectedProviderTarget = null,
26199
+ onProviderSelect
25346
26200
  }) {
25347
26201
  const providerStart = providerLabel ? label.indexOf(providerLabel) : -1;
25348
26202
  if (!shouldEmphasizeEmptyHeroProvider(label) || providerStart < 0) {
25349
26203
  return /* @__PURE__ */ jsx31(Fragment8, { children: label });
25350
26204
  }
25351
26205
  const providerEnd = providerStart + providerLabel.length;
26206
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${selectedProviderTarget?.provider ?? ""}`;
26207
+ const canSwitchProvider = providerTargets.length > 1 && selectedProviderTarget && onProviderSelect;
26208
+ const providerName = label.slice(providerStart, providerEnd);
25352
26209
  return /* @__PURE__ */ jsxs17(Fragment8, { children: [
25353
26210
  label.slice(0, providerStart),
25354
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: label.slice(providerStart, providerEnd) }),
26211
+ canSwitchProvider ? /* @__PURE__ */ jsxs17(
26212
+ Select3,
26213
+ {
26214
+ value: selectedProviderTargetId,
26215
+ onValueChange: (nextTargetId) => {
26216
+ const target = providerTargets.find(
26217
+ (candidate) => candidate.targetId === nextTargetId
26218
+ );
26219
+ if (!target || target.disabled === true) {
26220
+ return;
26221
+ }
26222
+ onProviderSelect({
26223
+ provider: target.provider,
26224
+ providerTargetId: target.targetId
26225
+ });
26226
+ },
26227
+ children: [
26228
+ /* @__PURE__ */ jsx31(
26229
+ SelectTrigger3,
26230
+ {
26231
+ size: "sm",
26232
+ "aria-label": providerSelectLabel,
26233
+ title: providerSelectLabel,
26234
+ className: AgentGUINode_styles_default.emptyHeroProviderSelect,
26235
+ children: /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName })
26236
+ }
26237
+ ),
26238
+ /* @__PURE__ */ jsx31(
26239
+ SelectContent3,
26240
+ {
26241
+ align: "center",
26242
+ className: cn3(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
26243
+ children: providerTargets.map((target) => /* @__PURE__ */ jsx31(
26244
+ SelectItem3,
26245
+ {
26246
+ value: target.targetId,
26247
+ className: cn3(
26248
+ AgentGUINode_styles_default.composerMenuItem,
26249
+ "gap-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-30 data-[disabled]:text-[var(--text-disabled,var(--text-tertiary))]",
26250
+ target.disabled === true ? "cursor-not-allowed opacity-30" : null
26251
+ ),
26252
+ disabled: target.disabled === true,
26253
+ children: /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 items-center gap-1.5", children: [
26254
+ /* @__PURE__ */ jsx31(
26255
+ "img",
26256
+ {
26257
+ alt: "",
26258
+ "aria-hidden": "true",
26259
+ className: cn3(
26260
+ "size-4 shrink-0 rounded-[4px]",
26261
+ target.disabled === true ? "grayscale opacity-30" : null
26262
+ ),
26263
+ src: agentGUIProviderIconPresentation(
26264
+ target.provider,
26265
+ target.iconUrl
26266
+ ).iconUrl
26267
+ }
26268
+ ),
26269
+ /* @__PURE__ */ jsx31(
26270
+ "span",
26271
+ {
26272
+ className: cn3(
26273
+ "min-w-0 truncate",
26274
+ target.disabled === true ? "text-[var(--text-disabled,var(--text-tertiary))]" : null
26275
+ ),
26276
+ children: target.label
26277
+ }
26278
+ )
26279
+ ] })
26280
+ },
26281
+ `${target.provider}:${target.targetId}`
26282
+ ))
26283
+ }
26284
+ )
26285
+ ]
26286
+ }
26287
+ ) : /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.emptyHeroProvider, children: providerName }),
25355
26288
  label.slice(providerEnd)
25356
26289
  ] });
25357
26290
  }
25358
26291
  var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25359
26292
  bottomDockRef,
26293
+ showScrollToBottom,
26294
+ scrollToBottomLabel,
26295
+ onScrollToBottom,
25360
26296
  bottomDockLiftedPrompt,
25361
26297
  bottomDockReplacementPrompt,
25362
26298
  store,
@@ -25369,7 +26305,9 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25369
26305
  onAuthLogin,
25370
26306
  onRetryActivation,
25371
26307
  onContinueInNewConversation,
25372
- onSubmitBottomDockInteractivePrompt
26308
+ onSubmitBottomDockInteractivePrompt,
26309
+ onGoalControl,
26310
+ goalPauseSupported
25373
26311
  }) {
25374
26312
  "use memo";
25375
26313
  const state = useSnapshot(store);
@@ -25385,6 +26323,7 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25385
26323
  const goalStatus = goal ? stringValue2(goal.status) : "";
25386
26324
  const goalTokenBudget = goal ? numberValue2(goal.tokenBudget) : null;
25387
26325
  const goalTokensUsed = goal ? numberValue2(goal.tokensUsed) : null;
26326
+ const goalTimeUsedSeconds = goal ? numberValue2(goal.timeUsedSeconds) : null;
25388
26327
  const showGoalBanner = isGoalBannerVisible(goalObjective, goalStatus);
25389
26328
  return /* @__PURE__ */ jsxs17(
25390
26329
  "div",
@@ -25393,6 +26332,22 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25393
26332
  className: AgentGUINode_styles_default.bottomDock,
25394
26333
  "data-testid": "agent-gui-bottom-dock",
25395
26334
  children: [
26335
+ showScrollToBottom ? /* @__PURE__ */ jsx31(
26336
+ "button",
26337
+ {
26338
+ type: "button",
26339
+ className: cn3(
26340
+ AgentGUINode_styles_default.bottomDockScrollToBottom,
26341
+ "nodrag tsh-desktop-no-drag [-webkit-app-region:no-drag]"
26342
+ ),
26343
+ "data-testid": "agent-gui-scroll-to-bottom",
26344
+ "aria-label": scrollToBottomLabel,
26345
+ title: scrollToBottomLabel,
26346
+ onPointerDown: (event) => event.stopPropagation(),
26347
+ onClick: onScrollToBottom,
26348
+ children: /* @__PURE__ */ jsx31(ChevronsDown, { "aria-hidden": "true", size: 15, strokeWidth: 2.2 })
26349
+ }
26350
+ ) : null,
25396
26351
  bottomDockLiftedPrompt ? /* @__PURE__ */ jsx31(
25397
26352
  "div",
25398
26353
  {
@@ -25444,7 +26399,12 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
25444
26399
  status: goalStatus,
25445
26400
  tokenBudget: goalTokenBudget ?? void 0,
25446
26401
  tokensUsed: goalTokensUsed ?? void 0,
25447
- labels: goalBannerLabels
26402
+ timeUsedSeconds: goalTimeUsedSeconds ?? void 0,
26403
+ labels: goalBannerLabels,
26404
+ onEditObjective: (objective) => onGoalControl("set", objective),
26405
+ onPauseGoal: goalPauseSupported ? () => onGoalControl("pause") : void 0,
26406
+ onResumeGoal: goalPauseSupported ? () => onGoalControl("resume") : void 0,
26407
+ onClearGoal: () => onGoalControl("clear")
25448
26408
  }
25449
26409
  ) : null,
25450
26410
  bottomDockReplacementPrompt ? /* @__PURE__ */ jsx31(
@@ -25481,7 +26441,7 @@ function syncAgentGUIConversationRailStore(store, next) {
25481
26441
  Object.assign(store, next);
25482
26442
  }
25483
26443
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
25484
- 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;
26444
+ 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;
25485
26445
  }
25486
26446
  var AgentGUIConversationRailStorePane = memo(
25487
26447
  function AgentGUIConversationRailStorePane2({
@@ -25706,18 +26666,51 @@ function conversationProjectsRenderEqual2(left, right) {
25706
26666
  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);
25707
26667
  }
25708
26668
  var agentGUIProviderRailOrder = [
25709
- "nexight",
25710
- "claude-code",
25711
26669
  "codex",
25712
- "openclaw",
26670
+ "claude-code",
26671
+ "nexight",
25713
26672
  "hermes",
26673
+ "openclaw",
25714
26674
  "gemini"
25715
26675
  ];
26676
+ var agentGUIProviderRailDefaultProviders = [
26677
+ "codex",
26678
+ "claude-code",
26679
+ "nexight",
26680
+ "hermes",
26681
+ "openclaw"
26682
+ ];
26683
+ var agentGUIProviderRailDisabledProviders = /* @__PURE__ */ new Set([
26684
+ "nexight",
26685
+ "hermes",
26686
+ "openclaw"
26687
+ ]);
25716
26688
  function agentGUIProviderRailOrderIndex(provider) {
25717
26689
  const index = agentGUIProviderRailOrder.indexOf(provider);
25718
26690
  return index < 0 ? agentGUIProviderRailOrder.length : index;
25719
26691
  }
26692
+ function agentGUILaunchpadIconPresentations() {
26693
+ return [
26694
+ agentGUIProviderRailIconPresentation("codex"),
26695
+ agentGUIProviderRailIconPresentation("claude-code"),
26696
+ agentGUIProviderRailIconPresentation("tutti"),
26697
+ agentGUIProviderRailIconPresentation("hermes")
26698
+ ];
26699
+ }
26700
+ function agentGUIConversationProviderIconUrl(provider) {
26701
+ switch (normalizeManagedAgentProvider(provider)) {
26702
+ case "claude-code":
26703
+ return claudecode_flat_filled_default;
26704
+ case "codex":
26705
+ return codex_flat_filled_default;
26706
+ default:
26707
+ return null;
26708
+ }
26709
+ }
25720
26710
  function agentGUIProviderRailLabel(provider, targetLabel, labels) {
26711
+ if (provider === "nexight" && targetLabel === "Tutti Agent") {
26712
+ return labels.conversationFilterTutti;
26713
+ }
25721
26714
  if (targetLabel.trim() && targetLabel !== provider) {
25722
26715
  return targetLabel;
25723
26716
  }
@@ -25732,21 +26725,51 @@ function agentGUIProviderRailLabel(provider, targetLabel, labels) {
25732
26725
  function agentGUIProviderTargetMatchesConversationFilter(target, filter) {
25733
26726
  return filter.kind === "agentTarget" && (target.agentTargetId?.trim() ?? "") === filter.agentTargetId;
25734
26727
  }
26728
+ function agentGUIProviderRailTargets(providerTargets, providerTargetsLoading) {
26729
+ if (providerTargetsLoading) {
26730
+ return [];
26731
+ }
26732
+ const source = providerTargets.length > 0 && !agentGUIProviderRailTargetsAreFullLocalFallback(providerTargets) ? providerTargets : [];
26733
+ const seenProviders = new Set(source.map((target) => target.provider));
26734
+ const missingDefaultProviders = agentGUIProviderRailDefaultProviders.filter(
26735
+ (provider) => !seenProviders.has(provider)
26736
+ );
26737
+ if (source.length > 0 && missingDefaultProviders.length === 0) {
26738
+ return source;
26739
+ }
26740
+ return [
26741
+ ...source,
26742
+ ...missingDefaultProviders.map(
26743
+ (provider) => agentGUIProviderRailDisabledProviders.has(provider) ? createDisabledPlaceholderAgentGUIProviderTarget(provider) : createLocalAgentGUIProviderTarget(provider)
26744
+ )
26745
+ ];
26746
+ }
26747
+ function agentGUIProviderRailTargetsAreFullLocalFallback(providerTargets) {
26748
+ if (providerTargets.length !== agentGUIProviderRailOrder.length) {
26749
+ return false;
26750
+ }
26751
+ const fallbackProviders = new Set(agentGUIProviderRailOrder);
26752
+ return providerTargets.every(
26753
+ (target) => fallbackProviders.has(target.provider) && target.ref.kind === "local" && target.ref.provider === target.provider && target.targetId === `local:${target.provider}`
26754
+ );
26755
+ }
25735
26756
  var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25736
26757
  conversationFilter,
25737
26758
  labels,
25738
26759
  previewMode,
26760
+ selectedProviderTarget,
25739
26761
  providerTargets,
25740
26762
  providerTargetsLoading,
25741
26763
  onSelectConversationFilterTarget,
25742
26764
  onUpdateConversationFilter
25743
26765
  }) {
25744
26766
  "use memo";
26767
+ const railProviderTargets = useMemo10(
26768
+ () => agentGUIProviderRailTargets(providerTargets, providerTargetsLoading),
26769
+ [providerTargets, providerTargetsLoading]
26770
+ );
25745
26771
  const providerTiles = useMemo10(() => {
25746
- const enabledTargets = providerTargets.filter(
25747
- (target) => target.disabled !== true
25748
- );
25749
- const targets = [...enabledTargets];
26772
+ const targets = [...railProviderTargets];
25750
26773
  const originalIndexByTarget = /* @__PURE__ */ new Map();
25751
26774
  targets.forEach((target, index) => {
25752
26775
  originalIndexByTarget.set(
@@ -25763,12 +26786,31 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25763
26786
  `${right.provider}\0${right.targetId}`
25764
26787
  ) ?? 0);
25765
26788
  });
25766
- }, [providerTargets]);
25767
- const allTileSelected = conversationFilter.kind === "all";
26789
+ }, [railProviderTargets]);
26790
+ const launchpadIconPresentations = useMemo10(
26791
+ () => agentGUILaunchpadIconPresentations(),
26792
+ []
26793
+ );
26794
+ const selectedProviderTargetIsPlaceholder = selectedProviderTarget?.disabled === true;
26795
+ const allTileSelected = conversationFilter.kind === "all" && !selectedProviderTargetIsPlaceholder;
25768
26796
  const selectAllProviders = useCallback10(() => {
25769
26797
  onUpdateConversationFilter({ kind: "all" });
25770
- }, [onUpdateConversationFilter]);
25771
- const selectProviderTile = useCallback10(
26798
+ if (selectedProviderTargetIsPlaceholder) {
26799
+ const fallbackTarget = railProviderTargets.find((target) => target.disabled !== true) ?? null;
26800
+ if (fallbackTarget) {
26801
+ onSelectConversationFilterTarget({
26802
+ provider: fallbackTarget.provider,
26803
+ providerTargetId: fallbackTarget.targetId
26804
+ });
26805
+ }
26806
+ }
26807
+ }, [
26808
+ onSelectConversationFilterTarget,
26809
+ onUpdateConversationFilter,
26810
+ railProviderTargets,
26811
+ selectedProviderTargetIsPlaceholder
26812
+ ]);
26813
+ const selectAgentTargetTile = useCallback10(
25772
26814
  (target) => {
25773
26815
  onSelectConversationFilterTarget({
25774
26816
  provider: target.provider,
@@ -25785,23 +26827,22 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25785
26827
  "aria-label": labels.providerSwitchLabel,
25786
26828
  "aria-busy": providerTargetsLoading,
25787
26829
  children: [
25788
- /* @__PURE__ */ jsxs17(
26830
+ /* @__PURE__ */ jsx31(
25789
26831
  "button",
25790
26832
  {
25791
26833
  type: "button",
25792
26834
  role: "tab",
26835
+ "aria-label": labels.conversationFilterAll,
25793
26836
  "aria-selected": allTileSelected,
25794
26837
  className: AgentGUINode_styles_default.providerRailTile,
25795
26838
  "data-selected": allTileSelected ? "true" : "false",
25796
26839
  disabled: previewMode,
25797
26840
  onClick: selectAllProviders,
25798
- children: [
25799
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(LayoutGrid, { "aria-hidden": true, className: AgentGUINode_styles_default.providerRailAvatarIcon }) }),
25800
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: labels.conversationFilterAll })
25801
- ]
26841
+ children: /* @__PURE__ */ jsx31(AgentGUIAllProviderGridIcon, { icons: launchpadIconPresentations })
25802
26842
  }
25803
26843
  ),
25804
- providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsxs17(
26844
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailSeparator }),
26845
+ providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsx31(
25805
26846
  "button",
25806
26847
  {
25807
26848
  type: "button",
@@ -25811,49 +26852,54 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25811
26852
  "data-loading": "true",
25812
26853
  "data-selected": "false",
25813
26854
  disabled: true,
25814
- children: [
25815
- /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar }),
25816
- /* @__PURE__ */ jsx31(
25817
- "span",
25818
- {
25819
- "aria-hidden": "true",
25820
- className: AgentGUINode_styles_default.providerRailTileLabel
25821
- }
25822
- )
25823
- ]
26855
+ children: /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar })
25824
26856
  },
25825
26857
  `provider-target-loading-${index}`
25826
26858
  )) : null,
25827
26859
  providerTiles.map((target) => {
25828
- const providerSelected = agentGUIProviderTargetMatchesConversationFilter(
26860
+ const providerSelected = target.disabled === true ? selectedProviderTarget?.provider === target.provider && selectedProviderTarget?.targetId === target.targetId : agentGUIProviderTargetMatchesConversationFilter(
25829
26861
  target,
25830
26862
  conversationFilter
25831
26863
  );
25832
- return /* @__PURE__ */ jsxs17(
26864
+ const label = agentGUIProviderRailLabel(
26865
+ target.provider,
26866
+ target.label,
26867
+ labels
26868
+ );
26869
+ const tile = /* @__PURE__ */ jsx31(
25833
26870
  "button",
25834
26871
  {
25835
26872
  type: "button",
25836
26873
  role: "tab",
26874
+ "aria-label": label,
25837
26875
  "aria-selected": providerSelected,
25838
26876
  className: AgentGUINode_styles_default.providerRailTile,
26877
+ "data-disabled": target.disabled === true ? "true" : void 0,
26878
+ "data-provider-tile": "true",
25839
26879
  "data-selected": providerSelected ? "true" : "false",
25840
- disabled: previewMode,
25841
- onClick: () => selectProviderTile(target),
25842
- children: [
25843
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
25844
- "img",
25845
- {
25846
- alt: "",
25847
- "aria-hidden": "true",
25848
- className: AgentGUINode_styles_default.providerRailAvatarImage,
25849
- src: target.iconUrl || resolveAgentGUIHeroIconUrl(target.provider)
25850
- }
25851
- ) }),
25852
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: agentGUIProviderRailLabel(target.provider, target.label, labels) })
25853
- ]
26880
+ disabled: previewMode || target.disabled === true,
26881
+ onClick: () => selectAgentTargetTile(target),
26882
+ children: /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
26883
+ AgentGUIProviderIconVisual,
26884
+ {
26885
+ ariaHidden: true,
26886
+ imageClassName: AgentGUINode_styles_default.providerRailAvatarImage,
26887
+ icon: agentGUIProviderRailIconPresentation(
26888
+ target.provider,
26889
+ target.iconUrl
26890
+ )
26891
+ }
26892
+ ) })
25854
26893
  },
25855
26894
  `${target.provider}:${target.targetId}`
25856
26895
  );
26896
+ if (previewMode) {
26897
+ return tile;
26898
+ }
26899
+ return /* @__PURE__ */ jsxs17(Tooltip3, { children: [
26900
+ /* @__PURE__ */ jsx31(TooltipTrigger3, { asChild: true, children: tile }),
26901
+ /* @__PURE__ */ jsx31(TooltipContent3, { side: "right", sideOffset: -4, children: label })
26902
+ ] }, `${target.provider}:${target.targetId}:tooltip`);
25857
26903
  })
25858
26904
  ]
25859
26905
  }
@@ -25865,18 +26911,19 @@ function useAgentGUIConversationRail({
25865
26911
  conversations,
25866
26912
  labels,
25867
26913
  previewMode,
26914
+ sectionAgentTargetFallbackId,
25868
26915
  userProjects,
25869
26916
  workspaceId
25870
26917
  }) {
25871
26918
  const agentActivityRuntime = useAgentActivityRuntime();
25872
- const [runtimeRailSections, setRuntimeRailSections] = useState11(null);
25873
- const [sectionPageStates, setSectionPageStates] = useState11(() => /* @__PURE__ */ new Map());
26919
+ const [runtimeRailSections, setRuntimeRailSections] = useState12(null);
26920
+ const [sectionPageStates, setSectionPageStates] = useState12(() => /* @__PURE__ */ new Map());
25874
26921
  const pagingRequestSequenceRef = useRef12(0);
25875
26922
  const pagingAbortControllersRef = useRef12(/* @__PURE__ */ new Map());
25876
26923
  const runtimeListSessionSections = agentActivityRuntime.listSessionSections;
25877
26924
  const runtimeListSessionSectionPage = agentActivityRuntime.listSessionSectionPage;
25878
26925
  const runtimeSectionsEnabled = !previewMode && Boolean(runtimeListSessionSections) && Boolean(runtimeListSessionSectionPage);
25879
- const sectionAgentTargetId = conversationFilter.kind === "agentTarget" ? conversationFilter.agentTargetId.trim() : "";
26926
+ const sectionAgentTargetId = conversationFilter.kind === "agentTarget" ? conversationFilter.agentTargetId.trim() : sectionAgentTargetFallbackId?.trim() ?? "";
25880
26927
  const userProjectPaths = useMemo10(
25881
26928
  () => userProjects.map((project) => project.path.trim()).filter((path) => path.length > 0),
25882
26929
  [userProjects]
@@ -25892,7 +26939,7 @@ function useAgentGUIConversationRail({
25892
26939
  }),
25893
26940
  [labels.sectionConversations, labels.sectionPinned]
25894
26941
  );
25895
- useEffect12(() => {
26942
+ useEffect13(() => {
25896
26943
  pagingRequestSequenceRef.current += 1;
25897
26944
  for (const controller of pagingAbortControllersRef.current.values()) {
25898
26945
  controller.abort();
@@ -25914,7 +26961,7 @@ function useAgentGUIConversationRail({
25914
26961
  ).join("|"),
25915
26962
  [conversations]
25916
26963
  );
25917
- useEffect12(() => {
26964
+ useEffect13(() => {
25918
26965
  if (!runtimeSectionsEnabled || !runtimeListSessionSections) {
25919
26966
  return;
25920
26967
  }
@@ -25968,7 +27015,7 @@ function useAgentGUIConversationRail({
25968
27015
  userProjectPathKey,
25969
27016
  workspaceId
25970
27017
  ]);
25971
- useEffect12(() => {
27018
+ useEffect13(() => {
25972
27019
  if (!runtimeSectionsEnabled) {
25973
27020
  return;
25974
27021
  }
@@ -26107,12 +27154,8 @@ var AgentGUIConversationRailPane = memo(
26107
27154
  isCollapsed,
26108
27155
  railConfigProvider,
26109
27156
  slashStatusLimits,
26110
- providerTargets,
26111
- providerTargetsLoading,
26112
- conversationScope,
26113
27157
  conversationFilter,
26114
- onUpdateConversationFilter,
26115
- onSelectConversationFilterTarget,
27158
+ sectionAgentTargetFallbackId,
26116
27159
  onCreateConversation,
26117
27160
  onOpenAgentEnvSetup,
26118
27161
  onRetryOpenclawGateway,
@@ -26129,17 +27172,10 @@ var AgentGUIConversationRailPane = memo(
26129
27172
  onConfirmDeleteConversation
26130
27173
  }) {
26131
27174
  "use memo";
26132
- const showProviderRail = conversationScope === "multi-provider";
26133
- const [conversationQuery, setConversationQuery] = useState11("");
26134
- const updateConversationFilter = useStableEventCallback2(
26135
- onUpdateConversationFilter
26136
- );
26137
- const selectConversationFilterTarget = useStableEventCallback2(
26138
- onSelectConversationFilterTarget
26139
- );
26140
- const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState11(() => /* @__PURE__ */ new Set());
26141
- const [currentTimeMs, setCurrentTimeMs] = useState11(() => Date.now());
26142
- const [pendingProjectAction, setPendingProjectAction] = useState11(null);
27175
+ const [conversationQuery, setConversationQuery] = useState12("");
27176
+ const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState12(() => /* @__PURE__ */ new Set());
27177
+ const [currentTimeMs, setCurrentTimeMs] = useState12(() => Date.now());
27178
+ const [pendingProjectAction, setPendingProjectAction] = useState12(null);
26143
27179
  const railElementRef = useRef12(null);
26144
27180
  const conversationListRef = useRef12(null);
26145
27181
  const conversationItemElementsRef = useRef12(
@@ -26159,10 +27195,11 @@ var AgentGUIConversationRailPane = memo(
26159
27195
  conversations,
26160
27196
  labels,
26161
27197
  previewMode,
27198
+ sectionAgentTargetFallbackId,
26162
27199
  userProjects,
26163
27200
  workspaceId
26164
27201
  });
26165
- useEffect12(() => {
27202
+ useEffect13(() => {
26166
27203
  const timer = window.setInterval(() => {
26167
27204
  setCurrentTimeMs(Date.now());
26168
27205
  }, 6e4);
@@ -26314,18 +27351,6 @@ var AgentGUIConversationRailPane = memo(
26314
27351
  }
26315
27352
  )
26316
27353
  ] }),
26317
- showProviderRail ? /* @__PURE__ */ jsx31(
26318
- AgentGUIProviderRail,
26319
- {
26320
- conversationFilter,
26321
- labels,
26322
- previewMode,
26323
- providerTargets,
26324
- providerTargetsLoading,
26325
- onSelectConversationFilterTarget: selectConversationFilterTarget,
26326
- onUpdateConversationFilter: updateConversationFilter
26327
- }
26328
- ) : null,
26329
27354
  openclawGateway?.status === "starting" ? /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.gatewayStatus, "data-state": "starting", children: [
26330
27355
  /* @__PURE__ */ jsx31(
26331
27356
  StatusDot,
@@ -26559,7 +27584,7 @@ var AgentGUIConversationRailSection = memo(
26559
27584
  }) {
26560
27585
  "use memo";
26561
27586
  const isProjectSection = section.kind === "project";
26562
- const [visibleItemLimit, setVisibleItemLimit] = useState11(
27587
+ const [visibleItemLimit, setVisibleItemLimit] = useState12(
26563
27588
  AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
26564
27589
  );
26565
27590
  const visibleItemCount = isSectionCollapsed ? 0 : Math.min(visibleItemLimit, section.items.length);
@@ -26922,6 +27947,7 @@ var AgentGUIConversationRailItem = memo(
26922
27947
  }) {
26923
27948
  "use memo";
26924
27949
  const pinned = (item.pinnedAtUnixMs ?? 0) > 0;
27950
+ const providerIconUrl = agentGUIConversationProviderIconUrl(item.provider);
26925
27951
  const setItemElement = useCallback10(
26926
27952
  (element) => {
26927
27953
  registerItemElement(item.id, element);
@@ -26963,7 +27989,19 @@ var AgentGUIConversationRailItem = memo(
26963
27989
  className: AgentGUINode_styles_default.conversationSelect,
26964
27990
  onClick: handleSelect,
26965
27991
  children: [
26966
- /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.conversationTitle, children: conversationPlainTitle(item, labels, uiLanguage) }),
27992
+ /* @__PURE__ */ jsxs17("span", { className: AgentGUINode_styles_default.conversationTitleRow, children: [
27993
+ providerIconUrl ? /* @__PURE__ */ jsx31(
27994
+ "span",
27995
+ {
27996
+ "aria-hidden": "true",
27997
+ className: AgentGUINode_styles_default.conversationProviderIcon,
27998
+ style: {
27999
+ "--agent-gui-conversation-provider-icon-url": `url("${providerIconUrl}")`
28000
+ }
28001
+ }
28002
+ ) : null,
28003
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.conversationTitle, children: conversationPlainTitle(item, labels, uiLanguage) })
28004
+ ] }),
26967
28005
  /* @__PURE__ */ jsx31(ConversationMeta, { item, nowMs: currentTimeMs, labels })
26968
28006
  ]
26969
28007
  }
@@ -27174,6 +28212,17 @@ var AgentGUIConversationTimelinePane = memo(
27174
28212
  function setTimelineScrollTopInstantly(element, top) {
27175
28213
  element.scrollTop = top;
27176
28214
  }
28215
+ function setTimelineScrollTopWithUserTransition(element, top) {
28216
+ const reducedMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
28217
+ if (typeof element.scrollTo === "function") {
28218
+ element.scrollTo({
28219
+ top,
28220
+ behavior: reducedMotion ? "auto" : "smooth"
28221
+ });
28222
+ return;
28223
+ }
28224
+ element.scrollTop = top;
28225
+ }
27177
28226
 
27178
28227
  // agent-gui/workspaceDesktop/view/desktopDockAgentProbeTooltipModel.ts
27179
28228
  function findWorkspaceAgentProbeForDockProvider(snapshot3, provider) {
@@ -27182,35 +28231,6 @@ function findWorkspaceAgentProbeForDockProvider(snapshot3, provider) {
27182
28231
  }
27183
28232
  return snapshot3.providers.find((p) => p.provider === provider) ?? null;
27184
28233
  }
27185
- function quotaRenderStateEquals(left, right) {
27186
- 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;
27187
- }
27188
- function agentProbeProviderRenderStateEquals(left, right) {
27189
- if (left === right) {
27190
- return true;
27191
- }
27192
- if (!left || !right) {
27193
- return left === right;
27194
- }
27195
- 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) => {
27196
- const next = right.availability.checks?.[index];
27197
- return check.name === next?.name && check.passed === next?.passed && check.detail === next?.detail;
27198
- }) && (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(
27199
- (quota, index) => quotaRenderStateEquals(quota, right.usage?.quotas?.[index])
27200
- ) && (left.attempts?.length ?? 0) === (right.attempts?.length ?? 0) && (left.attempts ?? []).every((attempt, index) => {
27201
- const next = right.attempts?.[index];
27202
- return attempt.strategy === next?.strategy && attempt.success === next?.success && attempt.errorCode === next?.errorCode && attempt.errorMessage === next?.errorMessage;
27203
- }) && left.lastError?.code === right.lastError?.code && left.lastError?.message === right.lastError?.message;
27204
- }
27205
- function workspaceAgentProbeRenderStateEqualsForProvider(left, right, provider) {
27206
- if (left === right) {
27207
- return true;
27208
- }
27209
- return (left?.isLoadingAvailability ?? false) === (right?.isLoadingAvailability ?? false) && (left?.isLoadingUsage ?? false) === (right?.isLoadingUsage ?? false) && agentProbeProviderRenderStateEquals(
27210
- findWorkspaceAgentProbeForDockProvider(left?.snapshot ?? null, provider),
27211
- findWorkspaceAgentProbeForDockProvider(right?.snapshot ?? null, provider)
27212
- );
27213
- }
27214
28234
  function buildDockAgentProbeTooltipLines(probe, isLoadingAvailability, t, popupOpts) {
27215
28235
  if (isLoadingAvailability && !probe) {
27216
28236
  return [t("agentHost.workspaceAgentProbeDockChecking")];
@@ -27378,10 +28398,10 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
27378
28398
  import { Info as Info3 } from "lucide-react";
27379
28399
  import {
27380
28400
  useCallback as useCallback11,
27381
- useEffect as useEffect13,
28401
+ useEffect as useEffect14,
27382
28402
  useLayoutEffect as useLayoutEffect5,
27383
28403
  useRef as useRef13,
27384
- useState as useState12
28404
+ useState as useState13
27385
28405
  } from "react";
27386
28406
  import { createPortal as createPortal4 } from "react-dom";
27387
28407
  import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -27420,8 +28440,8 @@ function AgentProbeInfoPopover({
27420
28440
  "use memo";
27421
28441
  const anchorRef = useRef13(null);
27422
28442
  const popoverRef = useRef13(null);
27423
- const [isOpen, setIsOpen] = useState12(false);
27424
- const [popoverStyle, setPopoverStyle] = useState12(null);
28443
+ const [isOpen, setIsOpen] = useState13(false);
28444
+ const [popoverStyle, setPopoverStyle] = useState13(null);
27425
28445
  const openPopover = useCallback11(() => {
27426
28446
  if (!isOpen) {
27427
28447
  onOpen?.();
@@ -27461,7 +28481,7 @@ function AgentProbeInfoPopover({
27461
28481
  maxWidth: availableWidth
27462
28482
  });
27463
28483
  }, []);
27464
- useEffect13(() => {
28484
+ useEffect14(() => {
27465
28485
  if (!isOpen) {
27466
28486
  return;
27467
28487
  }
@@ -27857,9 +28877,6 @@ function normalizeSlashStatusModelName(value) {
27857
28877
  return value?.trim().toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") ?? "";
27858
28878
  }
27859
28879
  function resolveAgentGUIRailStatusProvider(input) {
27860
- if (input.conversationScope !== "multi-provider") {
27861
- return input.activeProvider;
27862
- }
27863
28880
  const filter = input.conversationFilter;
27864
28881
  if (filter.kind !== "agentTarget") {
27865
28882
  return null;
@@ -27911,11 +28928,7 @@ function composerOverridesByAgentTargetIdEqual(left, right) {
27911
28928
  return true;
27912
28929
  }
27913
28930
  function areAgentGUINodePropsEqual(previous, next) {
27914
- 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(
27915
- previous.workspaceAgentProbes,
27916
- next.workspaceAgentProbes,
27917
- previous.state.provider
27918
- )) && 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;
28931
+ 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;
27919
28932
  }
27920
28933
  var AgentGUINode = memo2(function AgentGUINode2({
27921
28934
  nodeId,
@@ -27938,6 +28951,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
27938
28951
  height,
27939
28952
  desktopSize,
27940
28953
  onLinkAction,
28954
+ onHandoffConversation,
27941
28955
  capabilityMenuState,
27942
28956
  onCapabilitySettingsRequest,
27943
28957
  onAgentProviderLogin,
@@ -27945,7 +28959,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
27945
28959
  providerTargetsLoading = false,
27946
28960
  providerReadinessGates = null,
27947
28961
  defaultProviderTargetId = null,
27948
- conversationScope = "single-provider",
27949
28962
  onWorkspaceFileReferencesAdded,
27950
28963
  onOpenConversationWindow,
27951
28964
  onClose,
@@ -28102,7 +29115,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
28102
29115
  workspacePath,
28103
29116
  avoidGroupingEdits: agentSettings.avoidGroupingEdits,
28104
29117
  data: state,
28105
- conversationScope,
28106
29118
  openSessionRequest,
28107
29119
  prefillPromptRequest,
28108
29120
  providerTargets,
@@ -28141,13 +29153,8 @@ var AgentGUINode = memo2(function AgentGUINode2({
28141
29153
  const activeReadinessProvider = viewModel.activeConversationId !== null ? activeProvider : viewModel.selectedProviderTarget.provider;
28142
29154
  const selectedProviderTargetLabel = viewModel.selectedProviderTarget?.label ?? resolveAgentGUIProviderDisplayLabel(state.provider, fallbackAgentTitle);
28143
29155
  const displayProviderLabel = viewModel.activeConversation ? resolveAgentGUIProviderDisplayLabel(activeProvider, fallbackAgentTitle) : selectedProviderTargetLabel;
28144
- const windowAgentTitle = viewModel.activeConversation ? getAgentHostManagedToolchainAgentByName(activeProvider)?.label ?? displayProviderLabel : displayProviderLabel;
28145
29156
  const activeConversationDockTitle = viewModel.activeConversation ? resolveAgentGUIDockConversationTitle(viewModel.activeConversation) : null;
28146
- const activeConversationWindowTitle = viewModel.activeConversation ? formatAgentGUIConversationPlainTitle(viewModel.activeConversation, {
28147
- fallbackAgentLabel: fallbackAgentTitle,
28148
- language: locale
28149
- }) : null;
28150
- useEffect14(() => {
29157
+ useEffect15(() => {
28151
29158
  if (previewMode || !viewModel.activeConversation) {
28152
29159
  return;
28153
29160
  }
@@ -28199,6 +29206,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
28199
29206
  "agentHost.agentGui.providerGateCheckingDescription",
28200
29207
  { provider: displayProviderLabel }
28201
29208
  ),
29209
+ providerGateCheckingAgentsDescription: t(
29210
+ "agentHost.agentGui.providerGateCheckingAgentsDescription"
29211
+ ),
28202
29212
  providerGateInstallTitle: t(
28203
29213
  "agentHost.agentGui.providerGateInstallTitle",
28204
29214
  { provider: displayProviderLabel }
@@ -28218,6 +29228,17 @@ var AgentGUINode = memo2(function AgentGUINode2({
28218
29228
  { provider: displayProviderLabel }
28219
29229
  ),
28220
29230
  providerGateLoginAction: t("agentHost.agentGui.providerGateLoginAction"),
29231
+ providerGateComingSoonTitle: t(
29232
+ "agentHost.agentGui.providerGateComingSoonTitle",
29233
+ { provider: displayProviderLabel }
29234
+ ),
29235
+ providerGateComingSoonDescription: t(
29236
+ "agentHost.agentGui.providerGateComingSoonDescription",
29237
+ { provider: displayProviderLabel }
29238
+ ),
29239
+ providerGateComingSoonAction: t(
29240
+ "agentHost.agentGui.providerGateComingSoonAction"
29241
+ ),
28221
29242
  providerGateUnavailableTitle: t(
28222
29243
  "agentHost.agentGui.providerGateUnavailableTitle",
28223
29244
  { provider: displayProviderLabel }
@@ -28342,7 +29363,14 @@ var AgentGUINode = memo2(function AgentGUINode2({
28342
29363
  planImplementationSkip: t("agentHost.agentGui.planImplementationSkip"),
28343
29364
  noRunningResponse: t("agentHost.agentGui.noRunningResponse"),
28344
29365
  empty: t("agentHost.agentGui.empty", { provider: displayProviderLabel }),
29366
+ emptyForProvider: (provider) => t("agentHost.agentGui.empty", {
29367
+ provider: resolveAgentGUIProviderDisplayLabel(
29368
+ provider,
29369
+ fallbackAgentTitle
29370
+ )
29371
+ }),
28345
29372
  emptyProvider: displayProviderLabel,
29373
+ emptyProviderForProvider: (provider) => resolveAgentGUIProviderDisplayLabel(provider, fallbackAgentTitle),
28346
29374
  conversations: t("agentHost.agentGui.conversations"),
28347
29375
  newConversation: t("agentHost.agentGui.newConversation"),
28348
29376
  agentConfig: t("agentHost.agentGui.agentConfig"),
@@ -28356,11 +29384,13 @@ var AgentGUINode = memo2(function AgentGUINode2({
28356
29384
  conversationFilterClaudeCode: t(
28357
29385
  "agentHost.agentGui.conversationFilterClaudeCode"
28358
29386
  ),
29387
+ conversationFilterTutti: t("agentHost.agentGui.conversationFilterTutti"),
28359
29388
  providerSwitchLabel: t("agentHost.agentGui.providerSwitchLabel"),
28360
29389
  startConversation: t("agentHost.agentGui.startConversation"),
28361
29390
  selectConversation: t("agentHost.agentGui.selectConversation"),
28362
29391
  loadingConversations: t("agentHost.agentGui.loadingConversations"),
28363
29392
  loadingConversation: t("agentHost.agentGui.loadingConversation"),
29393
+ scrollToBottom: t("agentHost.agentGui.scrollToBottom"),
28364
29394
  searchNoConversations: t("agentHost.agentGui.searchNoConversations"),
28365
29395
  conversationUnavailable: t("agentHost.agentGui.conversationUnavailable"),
28366
29396
  fallbackAgentTitle,
@@ -28429,14 +29459,18 @@ var AgentGUINode = memo2(function AgentGUINode2({
28429
29459
  "agentHost.agentGui.continueInNewConversation"
28430
29460
  ),
28431
29461
  goalLabel: t("agentHost.agentGui.goalLabel"),
28432
- goalStatusActive: t("agentHost.agentGui.goalStatusActive"),
28433
- goalStatusPaused: t("agentHost.agentGui.goalStatusPaused"),
28434
- goalStatusBlocked: t("agentHost.agentGui.goalStatusBlocked"),
28435
- goalStatusUsageLimited: t("agentHost.agentGui.goalStatusUsageLimited"),
28436
- goalStatusBudgetLimited: t("agentHost.agentGui.goalStatusBudgetLimited"),
28437
- goalStatusComplete: t("agentHost.agentGui.goalStatusComplete"),
29462
+ goalTitleActive: t("agentHost.agentGui.goalTitleActive"),
29463
+ goalTitlePaused: t("agentHost.agentGui.goalTitlePaused"),
29464
+ goalTitleBlocked: t("agentHost.agentGui.goalTitleBlocked"),
29465
+ goalTitleUsageLimited: t("agentHost.agentGui.goalTitleUsageLimited"),
29466
+ goalTitleBudgetLimited: t("agentHost.agentGui.goalTitleBudgetLimited"),
29467
+ goalTitleComplete: t("agentHost.agentGui.goalTitleComplete"),
28438
29468
  goalBudgetUsage: (used, budget) => t("agentHost.agentGui.goalBudgetUsage", { used, budget }),
28439
29469
  goalClearHint: t("agentHost.agentGui.goalClearHint"),
29470
+ goalEditAction: t("agentHost.agentGui.goalEditAction"),
29471
+ goalPauseAction: t("agentHost.agentGui.goalPauseAction"),
29472
+ goalResumeAction: t("agentHost.agentGui.goalResumeAction"),
29473
+ goalClearAction: t("agentHost.agentGui.goalClearAction"),
28440
29474
  processing: t("agentHost.agentGui.processing"),
28441
29475
  turnSummary: t("agentHost.agentGui.turnSummary"),
28442
29476
  userMessageLocator: t("agentHost.agentGui.userMessageLocator"),
@@ -28674,7 +29708,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
28674
29708
  removeMention: t("common.remove"),
28675
29709
  addReference: t("agentHost.agentGui.addReference"),
28676
29710
  addContent: t("agentHost.agentGui.addContent"),
28677
- referenceWorkspaceFiles: t("agentHost.issue.referenceWorkspaceFiles")
29711
+ referenceWorkspaceFiles: t("agentHost.issue.referenceWorkspaceFiles"),
29712
+ handoffConversation: t("agentHost.agentGui.handoffConversation"),
29713
+ handoffConversationMenu: t("agentHost.agentGui.handoffConversationMenu")
28678
29714
  }),
28679
29715
  [displayProviderLabel, fallbackAgentTitle, t]
28680
29716
  );
@@ -28687,23 +29723,14 @@ var AgentGUINode = memo2(function AgentGUINode2({
28687
29723
  }),
28688
29724
  [t]
28689
29725
  );
28690
- const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle : null;
28691
- const windowTitle = collapsedWindowConversationTitle || (isConversationRailCollapsed ? activeConversationWindowTitle : null) || windowAgentTitle || title;
28692
- const windowTitleIconUrl = agentGuiDockIconUrls[activeProvider] ?? null;
29726
+ const windowTitle = title;
28693
29727
  const activeProbeProvider = activeProvider;
28694
29728
  const railStatusProvider = useMemo11(
28695
29729
  () => resolveAgentGUIRailStatusProvider({
28696
- activeProvider: activeProbeProvider,
28697
29730
  conversationFilter: viewModel.conversationFilter,
28698
- conversationScope: viewModel.conversationScope,
28699
29731
  providerTargets: viewModel.providerTargets
28700
29732
  }),
28701
- [
28702
- activeProbeProvider,
28703
- viewModel.conversationFilter,
28704
- viewModel.conversationScope,
28705
- viewModel.providerTargets
28706
- ]
29733
+ [viewModel.conversationFilter, viewModel.providerTargets]
28707
29734
  );
28708
29735
  const activeAgentProbe = useMemo11(
28709
29736
  () => findWorkspaceAgentProbeForDockProvider(
@@ -28775,7 +29802,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28775
29802
  workspaceAgentProbes?.isLoadingUsage,
28776
29803
  t
28777
29804
  ]);
28778
- useEffect14(() => {
29805
+ useEffect15(() => {
28779
29806
  if (previewMode || !onAgentProbeDemandChange) {
28780
29807
  return;
28781
29808
  }
@@ -28785,7 +29812,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28785
29812
  onAgentProbeDemandChange(null, probeSourceId);
28786
29813
  };
28787
29814
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
28788
- useEffect14(() => {
29815
+ useEffect15(() => {
28789
29816
  if (previewMode || !onAgentProbeDemandChange || !railStatusProvider || railStatusProvider === activeProbeProvider) {
28790
29817
  return;
28791
29818
  }
@@ -28813,17 +29840,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28813
29840
  nodeId,
28814
29841
  kind: "agentGui",
28815
29842
  title: windowTitle,
28816
- titleIcon: windowTitleIconUrl ? /* @__PURE__ */ jsx33(
28817
- "img",
28818
- {
28819
- src: windowTitleIconUrl,
28820
- alt: "",
28821
- draggable: false,
28822
- "aria-hidden": "true",
28823
- className: "size-4 rounded-[4px]",
28824
- "data-agent-gui-window-provider-icon": "true"
28825
- }
28826
- ) : null,
29843
+ titleIcon: null,
28827
29844
  position,
28828
29845
  width,
28829
29846
  height,
@@ -28891,6 +29908,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
28891
29908
  railSlashStatusLimits,
28892
29909
  previewMode,
28893
29910
  onLinkAction: handleLinkAction,
29911
+ onHandoffConversation,
28894
29912
  capabilityMenuState,
28895
29913
  onCapabilitySettingsRequest,
28896
29914
  onAgentProviderLogin: onAgentProviderLogin ? handleAgentProviderLogin : void 0,