@tutti-os/agent-gui 0.0.73 → 0.0.75

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 (95) hide show
  1. package/README.md +23 -2
  2. package/dist/agent-conversation/index.d.ts +5 -5
  3. package/dist/agent-conversation/index.js +8 -8
  4. package/dist/agent-message-center/index.d.ts +2 -2
  5. package/dist/agent-message-center/index.js +170 -12
  6. package/dist/agent-message-center/index.js.map +1 -1
  7. package/dist/{agentConversationVM-DPAgUJlR.d.ts → agentConversationVM-BgoqFyE9.d.ts} +1 -1
  8. package/dist/{agentGuiNodeTypes-aJ3AX7u2.d.ts → agentGuiNodeTypes-CmuJ7VDZ.d.ts} +17 -6
  9. package/dist/app/renderer/agentactivity.css +58 -33
  10. package/dist/app/renderer/assets/icons/agents/cursor-colorful.png +0 -0
  11. package/dist/app/renderer/assets/icons/agents/opencode-rounded.png +0 -0
  12. package/dist/app/renderer/assets/icons/agents/provider-rail-opencode-colorful.png +0 -0
  13. package/dist/{chunk-IVIXKAEH.js → chunk-3FYA2K4P.js} +76 -7
  14. package/dist/chunk-3FYA2K4P.js.map +1 -0
  15. package/dist/{chunk-4US2YHBY.js → chunk-4HP6V2YA.js} +16 -4
  16. package/dist/chunk-4HP6V2YA.js.map +1 -0
  17. package/dist/{chunk-G6BVEY7I.js → chunk-4TNM6ZEC.js} +3 -114
  18. package/dist/chunk-4TNM6ZEC.js.map +1 -0
  19. package/dist/{chunk-3PKRGSMH.js → chunk-52GTPN7X.js} +4 -23
  20. package/dist/chunk-52GTPN7X.js.map +1 -0
  21. package/dist/{chunk-OBJRIQPX.js → chunk-7GSBP5CN.js} +68 -34
  22. package/dist/chunk-7GSBP5CN.js.map +1 -0
  23. package/dist/{chunk-2I2WRI4F.js → chunk-BEM3KDOJ.js} +3 -4
  24. package/dist/chunk-BEM3KDOJ.js.map +1 -0
  25. package/dist/{chunk-ATEZXUHK.js → chunk-BT2DT2P7.js} +1 -1
  26. package/dist/chunk-BT2DT2P7.js.map +1 -0
  27. package/dist/{chunk-SVGIWXNK.js → chunk-GZX2SGAG.js} +2 -2
  28. package/dist/{chunk-KWQ4N4IZ.js → chunk-KELYWKTC.js} +28 -6
  29. package/dist/chunk-KELYWKTC.js.map +1 -0
  30. package/dist/{chunk-UAAXRSW2.js → chunk-L2ZMLLYL.js} +14 -7
  31. package/dist/chunk-L2ZMLLYL.js.map +1 -0
  32. package/dist/{chunk-5H6NINJY.js → chunk-M6FZ2YIR.js} +3 -8
  33. package/dist/chunk-M6FZ2YIR.js.map +1 -0
  34. package/dist/{chunk-XZF4QNT4.js → chunk-MNESUMOS.js} +2 -2
  35. package/dist/{chunk-466AWJTS.js → chunk-QDKD6RNC.js} +15 -6
  36. package/dist/{chunk-466AWJTS.js.map → chunk-QDKD6RNC.js.map} +1 -1
  37. package/dist/{chunk-GDFQXJMG.js → chunk-RIRFNGPB.js} +7 -7
  38. package/dist/chunk-RIRFNGPB.js.map +1 -0
  39. package/dist/{chunk-4I2VCAMW.js → chunk-SYWMKIRW.js} +4 -11
  40. package/dist/chunk-SYWMKIRW.js.map +1 -0
  41. package/dist/{chunk-SZF52NMJ.js → chunk-U6AZ3XQS.js} +38 -13
  42. package/dist/chunk-U6AZ3XQS.js.map +1 -0
  43. package/dist/{chunk-Q6AWM3RH.js → chunk-U6EDUTUO.js} +4 -4
  44. package/dist/{chunk-MYD37I32.js → chunk-VAKFNNKT.js} +1 -15
  45. package/dist/chunk-VAKFNNKT.js.map +1 -0
  46. package/dist/{chunk-BHNJN2TR.js → chunk-XW4CVBUH.js} +2 -5
  47. package/dist/chunk-XW4CVBUH.js.map +1 -0
  48. package/dist/{chunk-C7K3EFGI.js → chunk-YWQHNFYA.js} +2 -2
  49. package/dist/context-mention-palette/index.js +9 -9
  50. package/dist/i18n/index.d.ts +2 -110
  51. package/dist/i18n/index.js +2 -2
  52. package/dist/index.d.ts +86 -10
  53. package/dist/index.js +1284 -667
  54. package/dist/index.js.map +1 -1
  55. package/dist/plan-decision-ops.d.ts +2 -2
  56. package/dist/queued-prompt-runtime.d.ts +4 -6
  57. package/dist/queued-prompt-runtime.js +1 -1
  58. package/dist/{types-CrwMqBm1.d.ts → types-DUHHejs2.d.ts} +3 -3
  59. package/dist/workbench/contribution.d.ts +1 -1
  60. package/dist/workbench/contribution.js +6 -6
  61. package/dist/workbench/index.d.ts +1 -1
  62. package/dist/workbench/index.js +9 -9
  63. package/dist/workbench/launch.d.ts +2 -2
  64. package/dist/workbench/launch.js +3 -3
  65. package/dist/workbench/providerCatalog.d.ts +3 -3
  66. package/dist/workbench/providerCatalog.js +1 -1
  67. package/dist/workbench/sessionTitle.d.ts +1 -1
  68. package/dist/workbench/sessionTitle.js +3 -3
  69. package/dist/workbench/state.d.ts +1 -1
  70. package/dist/workbench/state.js +2 -2
  71. package/dist/workbench/types.d.ts +2 -2
  72. package/dist/workbench/types.js +1 -1
  73. package/dist/workspace-agent-generated-files.d.ts +1 -1
  74. package/dist/workspace-agent-generated-files.js +4 -4
  75. package/dist/{workspaceAgentActivityListViewModel-DJvAqZso.d.ts → workspaceAgentActivityListViewModel-TXH1VXrk.d.ts} +0 -10
  76. package/package.json +12 -12
  77. package/dist/chunk-2I2WRI4F.js.map +0 -1
  78. package/dist/chunk-3PKRGSMH.js.map +0 -1
  79. package/dist/chunk-4I2VCAMW.js.map +0 -1
  80. package/dist/chunk-4US2YHBY.js.map +0 -1
  81. package/dist/chunk-5H6NINJY.js.map +0 -1
  82. package/dist/chunk-ATEZXUHK.js.map +0 -1
  83. package/dist/chunk-BHNJN2TR.js.map +0 -1
  84. package/dist/chunk-G6BVEY7I.js.map +0 -1
  85. package/dist/chunk-GDFQXJMG.js.map +0 -1
  86. package/dist/chunk-IVIXKAEH.js.map +0 -1
  87. package/dist/chunk-KWQ4N4IZ.js.map +0 -1
  88. package/dist/chunk-MYD37I32.js.map +0 -1
  89. package/dist/chunk-OBJRIQPX.js.map +0 -1
  90. package/dist/chunk-SZF52NMJ.js.map +0 -1
  91. package/dist/chunk-UAAXRSW2.js.map +0 -1
  92. /package/dist/{chunk-SVGIWXNK.js.map → chunk-GZX2SGAG.js.map} +0 -0
  93. /package/dist/{chunk-XZF4QNT4.js.map → chunk-MNESUMOS.js.map} +0 -0
  94. /package/dist/{chunk-Q6AWM3RH.js.map → chunk-U6EDUTUO.js.map} +0 -0
  95. /package/dist/{chunk-C7K3EFGI.js.map → chunk-YWQHNFYA.js.map} +0 -0
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  resolveAgentGuiSessionProviderFlatIconUrl,
12
12
  resolveNextAgentGUIConversationRailWidthPx,
13
13
  shouldAutoCollapseAgentGUIConversationRail
14
- } from "./chunk-SZF52NMJ.js";
14
+ } from "./chunk-U6AZ3XQS.js";
15
15
  import {
16
16
  agentGUIDefaultTargetProviders,
17
17
  agentGUIProviderTargetRefsEqual,
@@ -23,16 +23,16 @@ import {
23
23
  localAgentGUIProviderTargetId,
24
24
  normalizeAgentGUIProviderTargets,
25
25
  resolveAgentGUIProviderTarget
26
- } from "./chunk-2I2WRI4F.js";
27
- import "./chunk-UAAXRSW2.js";
28
- import "./chunk-ATEZXUHK.js";
26
+ } from "./chunk-BEM3KDOJ.js";
27
+ import "./chunk-L2ZMLLYL.js";
28
+ import "./chunk-BT2DT2P7.js";
29
29
  import {
30
30
  resolveAgentGuiWorkbenchProviderLabel
31
- } from "./chunk-BHNJN2TR.js";
31
+ } from "./chunk-XW4CVBUH.js";
32
32
  import {
33
33
  AgentInteractivePromptSurface,
34
34
  approvalOptionDisplayLabel
35
- } from "./chunk-Q6AWM3RH.js";
35
+ } from "./chunk-U6EDUTUO.js";
36
36
  import {
37
37
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
38
38
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -51,7 +51,7 @@ import {
51
51
  resolveAgentGUIExplicitConversationTitle,
52
52
  resolveAgentGUIProviderDisplayLabel,
53
53
  resolveAgentGUIProviderIdentity
54
- } from "./chunk-5H6NINJY.js";
54
+ } from "./chunk-M6FZ2YIR.js";
55
55
  import {
56
56
  AGENT_PASTED_TEXT_BLOCK_KIND,
57
57
  AGENT_PASTED_TEXT_MENTION_KIND,
@@ -88,14 +88,14 @@ import {
88
88
  textPromptContent,
89
89
  toLocalShortDateTime,
90
90
  useProjectedAgentConversation
91
- } from "./chunk-OBJRIQPX.js";
91
+ } from "./chunk-7GSBP5CN.js";
92
92
  import {
93
93
  AgentMessageMarkdown,
94
94
  AgentTargetPresentationProvider,
95
95
  ZoomableImage,
96
96
  cn,
97
97
  resolveWorkspaceLinkAction
98
- } from "./chunk-IVIXKAEH.js";
98
+ } from "./chunk-3FYA2K4P.js";
99
99
  import {
100
100
  openAgentEnvPanel
101
101
  } from "./chunk-PSLAWU25.js";
@@ -106,17 +106,18 @@ import {
106
106
  DEFAULT_AGENT_MENTION_FILTER,
107
107
  agentMentionItemKey,
108
108
  preloadAgentMentionBrowse
109
- } from "./chunk-466AWJTS.js";
109
+ } from "./chunk-QDKD6RNC.js";
110
110
  import {
111
111
  buildWorkspaceAgentActivityListViewModel,
112
112
  isWorkspaceAgentUntitledTask
113
- } from "./chunk-3PKRGSMH.js";
114
- import "./chunk-SVGIWXNK.js";
113
+ } from "./chunk-52GTPN7X.js";
114
+ import "./chunk-GZX2SGAG.js";
115
115
  import {
116
116
  resolveWorkspaceAgentSessionSortTimeUnixMs
117
117
  } from "./chunk-IBIMGLCD.js";
118
118
  import {
119
119
  AGENT_RICH_TEXT_CARET_ANCHOR,
120
+ AgentMentionTooltipProviderScope,
120
121
  createAgentSessionMarkdownLink,
121
122
  createAgentSessionMentionHref,
122
123
  exitAgentFileMentionSuggestion,
@@ -124,7 +125,7 @@ import {
124
125
  mentionItemToAttrs,
125
126
  normalizeAgentSessionMentionTitle,
126
127
  parseMentionItemFromHref
127
- } from "./chunk-KWQ4N4IZ.js";
128
+ } from "./chunk-KELYWKTC.js";
128
129
  import "./chunk-Y35GDLP2.js";
129
130
  import "./chunk-LUGELG5V.js";
130
131
  import {
@@ -133,6 +134,7 @@ import {
133
134
  MANAGED_AGENT_ICON_FALLBACK_URL,
134
135
  MANAGED_AGENT_ICON_URLS,
135
136
  MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS,
137
+ agentActivityRuntimeCapabilityEnabled,
136
138
  getAgentActivityRuntime,
137
139
  getAgentActivityRuntimeByOrigin,
138
140
  getAgentCustomMentionKind,
@@ -148,36 +150,37 @@ import {
148
150
  useAgentHostApi,
149
151
  useOptionalAgentActivityRuntime,
150
152
  useOptionalAgentHostApi
151
- } from "./chunk-GDFQXJMG.js";
153
+ } from "./chunk-RIRFNGPB.js";
152
154
  import {
153
155
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
154
156
  createWorkspaceAgentActivityUserMessageIdFromClientSubmitId,
155
157
  isWorkspaceAgentActivityOptimisticMessage,
156
158
  isWorkspaceAgentActivityRuntimeSessionOrigin,
157
159
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
160
+ minFiniteDurableWorkspaceAgentActivityMessageVersion,
158
161
  selectWorkspaceAgentActivityOverlayMessages
159
- } from "./chunk-4US2YHBY.js";
162
+ } from "./chunk-4HP6V2YA.js";
160
163
  import {
161
164
  AgentGuiI18nProvider,
162
165
  agentGuiI18nModule,
163
166
  agentGuiI18nResources,
164
167
  translate,
165
168
  useTranslation
166
- } from "./chunk-C7K3EFGI.js";
169
+ } from "./chunk-YWQHNFYA.js";
167
170
  import "./chunk-PJP5BUU6.js";
168
171
  import {
169
172
  agentColorfulUrl,
170
173
  cursorColorfulUrl,
171
174
  normalizeManagedAgentProvider
172
- } from "./chunk-4I2VCAMW.js";
173
- import "./chunk-G6BVEY7I.js";
175
+ } from "./chunk-SYWMKIRW.js";
176
+ import "./chunk-4TNM6ZEC.js";
174
177
  import {
175
178
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
176
179
  } from "./chunk-JM24HADP.js";
177
180
  import "./chunk-GCBDIQDX.js";
178
181
  import {
179
182
  createAgentQueuedPromptRuntime
180
- } from "./chunk-MYD37I32.js";
183
+ } from "./chunk-VAKFNNKT.js";
181
184
 
182
185
  // shared/agentActivitySnapshotProjection.ts
183
186
  import {
@@ -343,7 +346,7 @@ import { memo as memo4 } from "react";
343
346
  import { TooltipProvider as TooltipProvider4 } from "@tutti-os/ui-system";
344
347
 
345
348
  // agent-gui/agentGuiNode/AgentGUINode.tsx
346
- import { memo as memo3, useCallback as useCallback12, useEffect as useEffect16, useMemo as useMemo10 } from "react";
349
+ import { memo as memo3, useCallback as useCallback12, useEffect as useEffect17, useMemo as useMemo11 } from "react";
347
350
  import { createWorkspaceUserProjectI18nRuntime } from "@tutti-os/workspace-user-project/i18n";
348
351
  import { createWorkspaceFileManagerI18nRuntime } from "@tutti-os/workspace-file-manager";
349
352
 
@@ -2266,6 +2269,7 @@ function getTestAgentQueuedPromptRuntime() {
2266
2269
  // agent-gui/agentGuiNode/controller/useAgentGUINodeController.ts
2267
2270
  import {
2268
2271
  resolveSubmitAvailability,
2272
+ isLiveTurnLifecyclePhase,
2269
2273
  resolveAgentActivityCapability as resolveAgentActivityCapability2,
2270
2274
  resolveAgentActivityUsage,
2271
2275
  selectSessionDisplayStatuses
@@ -2279,7 +2283,6 @@ var AGENT_PROVIDERS = [
2279
2283
  "tutti-agent",
2280
2284
  "nexight",
2281
2285
  "opencode",
2282
- "gemini",
2283
2286
  "openclaw",
2284
2287
  "hermes"
2285
2288
  ];
@@ -2323,7 +2326,6 @@ var DEFAULT_AGENT_SETTINGS = {
2323
2326
  cursor: false,
2324
2327
  nexight: false,
2325
2328
  opencode: false,
2326
- gemini: false,
2327
2329
  openclaw: false,
2328
2330
  hermes: false
2329
2331
  },
@@ -2334,7 +2336,6 @@ var DEFAULT_AGENT_SETTINGS = {
2334
2336
  cursor: "",
2335
2337
  nexight: "",
2336
2338
  opencode: "",
2337
- gemini: "",
2338
2339
  openclaw: "",
2339
2340
  hermes: ""
2340
2341
  },
@@ -2345,7 +2346,6 @@ var DEFAULT_AGENT_SETTINGS = {
2345
2346
  cursor: [],
2346
2347
  nexight: [],
2347
2348
  opencode: [],
2348
- gemini: [],
2349
2349
  openclaw: [],
2350
2350
  hermes: []
2351
2351
  },
@@ -2496,6 +2496,9 @@ function agentGUIConversationProjectSummaryFromProject(matchedProject) {
2496
2496
  path: matchedProject.path,
2497
2497
  label: resolveWorkspaceUserProjectDisplayLabel(matchedProject)
2498
2498
  };
2499
+ if (matchedProject.sectionKey !== void 0) {
2500
+ summary.sectionKey = matchedProject.sectionKey;
2501
+ }
2499
2502
  if (matchedProject.createdAtUnixMs !== void 0) {
2500
2503
  summary.createdAtUnixMs = matchedProject.createdAtUnixMs;
2501
2504
  }
@@ -2929,6 +2932,7 @@ function workspaceAgentMessagesFromTimelineItems(timelineItems) {
2929
2932
  ...item.status ? { status: item.status } : {},
2930
2933
  payload: {
2931
2934
  ...item.payload,
2935
+ __agentGuiTimelineProjection: true,
2932
2936
  content: item.payload?.content ?? item.content,
2933
2937
  text: item.payload?.text ?? item.content,
2934
2938
  callType: item.callType,
@@ -4246,8 +4250,7 @@ function ensureActivityStreamUpstream(entry) {
4246
4250
  const runtime = getAgentActivityRuntimeByOrigin(entry.payload.origin);
4247
4251
  if (runtime) {
4248
4252
  try {
4249
- const ensureSessionSynchronized = runtime.ensureSessionSynchronized ?? runtime.retainSessionEvents;
4250
- entry.releaseRuntimeEvents = ensureSessionSynchronized({
4253
+ entry.releaseRuntimeEvents = runtime.ensureSessionSynchronized({
4251
4254
  workspaceId: entry.payload.workspaceId,
4252
4255
  agentSessionId: entry.payload.agentSessionId,
4253
4256
  onError: (error) => {
@@ -4789,35 +4792,31 @@ function normalizeAgentGUIConversationListFilter(input) {
4789
4792
  if (input.conversationFilter) {
4790
4793
  return normalizeAgentGUIConversationFilter(input.conversationFilter);
4791
4794
  }
4792
- return null;
4795
+ return { kind: "all" };
4793
4796
  }
4794
- function conversationFilterKey(filter, provider) {
4795
- if (!filter) {
4796
- return `legacy-provider:${provider}`;
4797
- }
4797
+ function conversationFilterKey(filter) {
4798
4798
  const normalized = normalizeAgentGUIConversationFilter(filter);
4799
4799
  if (normalized.kind === "all") {
4800
4800
  return "all";
4801
4801
  }
4802
4802
  return `agent-target:${normalized.agentTargetId}`;
4803
4803
  }
4804
- function conversationRetainableForQueryFilter(conversation, filter) {
4805
- if (!conversation || !filter || filter.kind !== "agentTarget") {
4804
+ function conversationMatchesQueryFilter(conversation, filter) {
4805
+ if (!conversation || filter.kind !== "agentTarget") {
4806
4806
  return true;
4807
4807
  }
4808
- return matchesAgentGUIConversationSummaryFilter(conversation, filter);
4808
+ return (conversation.agentTargetId?.trim() ?? "") === filter.agentTargetId;
4809
4809
  }
4810
4810
  function createAgentGUIConversationListQueryKey(input) {
4811
4811
  const normalized = normalizeQuery(input);
4812
4812
  if (!normalized) {
4813
4813
  return null;
4814
4814
  }
4815
- const providerScope = normalized.conversationFilter ? "conversation-filter" : normalized.provider;
4816
4815
  const queryKey = [
4817
4816
  normalized.workspaceId,
4818
4817
  normalized.userId,
4819
- providerScope,
4820
- conversationFilterKey(normalized.conversationFilter, normalized.provider),
4818
+ "conversation-filter",
4819
+ conversationFilterKey(normalized.conversationFilter),
4821
4820
  normalized.sessionOrigin
4822
4821
  ].join("::");
4823
4822
  return queryKey;
@@ -5586,8 +5585,8 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5586
5585
  userId: state.query.userId
5587
5586
  };
5588
5587
  const currentWorkspaceAgentSnapshot = getWorkspaceAgentSnapshotForConversations(workspaceAgentsInput);
5589
- const canProjectExplicitFilterFromCurrentSnapshot = reason === "projection-sync" && state.query.conversationFilter !== null && currentWorkspaceAgentSnapshot.sessions.length > 0;
5590
- const workspaceAgentSnapshot = shouldUseCurrentWorkspaceAgentSnapshotForRefresh(reason) || canProjectExplicitFilterFromCurrentSnapshot ? currentWorkspaceAgentSnapshot : await loadWorkspaceAgentSnapshotForConversations(
5588
+ const canProjectFilterFromCurrentSnapshot = reason === "projection-sync" && currentWorkspaceAgentSnapshot.sessions.length > 0;
5589
+ const workspaceAgentSnapshot = shouldUseCurrentWorkspaceAgentSnapshotForRefresh(reason) || canProjectFilterFromCurrentSnapshot ? currentWorkspaceAgentSnapshot : await loadWorkspaceAgentSnapshotForConversations(
5591
5590
  workspaceAgentsInput
5592
5591
  );
5593
5592
  if (requestId !== requestIdByQueryKey.get(queryKey)) {
@@ -5643,14 +5642,19 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5643
5642
  return agentSessionId && dirtySessionIds.has(agentSessionId) || syncSessionId && dirtySessionIds.has(syncSessionId);
5644
5643
  }) : workspaceAgentSnapshot.sessions;
5645
5644
  const baseConversations = buildAgentGUIConversationSummaries({
5646
- ...state.query.conversationFilter ? { conversationFilter: state.query.conversationFilter } : {},
5645
+ conversationFilter: state.query.conversationFilter,
5647
5646
  snapshot: canApplyDirtySessionProjection ? {
5648
5647
  ...workspaceAgentSnapshot,
5649
5648
  sessions: projectionSessions
5650
5649
  } : workspaceAgentSnapshot,
5651
5650
  provider: state.query.provider,
5652
5651
  sessionMessagesById: sessionMessagesByIdForSummaries
5653
- });
5652
+ }).filter(
5653
+ (conversation) => conversationMatchesQueryFilter(
5654
+ conversation,
5655
+ state.query.conversationFilter
5656
+ )
5657
+ );
5654
5658
  const conversationsToDecorate = canApplyDirtySessionProjection ? /* @__PURE__ */ new Set([
5655
5659
  ...dirtySessionIds,
5656
5660
  ...baseConversations.map((conversation) => conversation.id)
@@ -5668,30 +5672,16 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5668
5672
  return agentSessionId && agentTargetId ? [[agentSessionId, agentTargetId]] : [];
5669
5673
  })
5670
5674
  );
5671
- const snapshotSessionProviderById = new Map(
5672
- workspaceAgentSnapshot.sessions.flatMap((session) => {
5673
- const agentSessionId = session.agentSessionId.trim();
5674
- const provider = session.provider?.trim() ?? "";
5675
- return agentSessionId && provider ? [[agentSessionId, provider]] : [];
5676
- })
5677
- );
5678
5675
  const retainableForQueryFilter = (agentSessionId) => {
5679
5676
  const filter = state.query.conversationFilter;
5680
- if (!filter || filter.kind !== "agentTarget") {
5677
+ if (filter.kind !== "agentTarget") {
5681
5678
  return true;
5682
5679
  }
5683
5680
  const snapshotAgentTargetId = snapshotSessionAgentTargetIdById.get(agentSessionId);
5684
- const snapshotProvider = snapshotSessionProviderById.get(agentSessionId);
5685
- if (snapshotAgentTargetId || snapshotProvider) {
5686
- return matchesAgentGUIConversationSummaryFilter(
5687
- {
5688
- agentTargetId: snapshotAgentTargetId ?? null,
5689
- provider: snapshotProvider ?? null
5690
- },
5691
- filter
5692
- );
5681
+ if (snapshotAgentTargetId) {
5682
+ return snapshotAgentTargetId === filter.agentTargetId;
5693
5683
  }
5694
- return conversationRetainableForQueryFilter(
5684
+ return conversationMatchesQueryFilter(
5695
5685
  currentConversationsById.get(agentSessionId),
5696
5686
  filter
5697
5687
  );
@@ -6642,7 +6632,7 @@ function nodeComposerOverridesForProvider(data) {
6642
6632
  return data.composerOverridesByProvider?.[data.provider] ?? data.composerOverrides ?? null;
6643
6633
  }
6644
6634
  function composerSupportForProvider(provider) {
6645
- if (provider === "claude-code" || provider === "codex" || provider === "gemini" || provider === "opencode") {
6635
+ if (provider === "claude-code" || provider === "codex" || provider === "opencode") {
6646
6636
  return {
6647
6637
  model: true,
6648
6638
  permission: provider === "claude-code" || provider === "codex",
@@ -6872,11 +6862,29 @@ function sanitizeComposerSettingsForTarget(input) {
6872
6862
  function agentGUIProviderTargetsEqual(left, right) {
6873
6863
  return left.provider === right.provider && left.targetId === right.targetId && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && agentGUIProviderTargetRefsEqual(left.ref, right.ref);
6874
6864
  }
6875
- function reportAgentGUIRuntimeError(input) {
6876
- const reportDiagnostic = input.runtime.reportDiagnostic;
6877
- if (!reportDiagnostic) {
6878
- return;
6865
+ function reportAgentGUIDiagnostic(runtime, input) {
6866
+ const reportDiagnostic = runtime.reportDiagnostic;
6867
+ try {
6868
+ if (reportDiagnostic) {
6869
+ void Promise.resolve(reportDiagnostic.call(runtime, input)).catch(
6870
+ () => {
6871
+ }
6872
+ );
6873
+ return;
6874
+ }
6875
+ if (!agentGUIDevConsoleDiagnosticSinkEnabled(runtime)) {
6876
+ return;
6877
+ }
6878
+ const level = input.level ?? "info";
6879
+ const consoleMethod = level === "error" ? console.error : level === "warn" ? console.warn : level === "debug" ? console.debug : console.info;
6880
+ consoleMethod.call(console, "[agent-gui]", input.event, input);
6881
+ } catch {
6879
6882
  }
6883
+ }
6884
+ function agentGUIDevConsoleDiagnosticSinkEnabled(runtime) {
6885
+ return runtime.devDiagnosticConsoleSink !== false && typeof process !== "undefined" && (process.env.NODE_ENV === "development" || process.env.AGENT_GUI_DEV_DIAGNOSTIC_CONSOLE === "1");
6886
+ }
6887
+ function reportAgentGUIRuntimeError(input) {
6880
6888
  const details = {
6881
6889
  error: normalizeAgentGUIDiagnosticError(input.error),
6882
6890
  errorCode: getAgentGUIErrorCode(input.error),
@@ -6886,19 +6894,13 @@ function reportAgentGUIRuntimeError(input) {
6886
6894
  ...input.requestId !== void 0 && input.requestId !== null ? { requestId: input.requestId } : {},
6887
6895
  ...input.context ?? {}
6888
6896
  };
6889
- try {
6890
- void Promise.resolve(
6891
- reportDiagnostic.call(input.runtime, {
6892
- details,
6893
- event: "agent.gui.caught_error",
6894
- level: "error",
6895
- source: "agent-gui",
6896
- workspaceId: input.workspaceId
6897
- })
6898
- ).catch(() => {
6899
- });
6900
- } catch {
6901
- }
6897
+ reportAgentGUIDiagnostic(input.runtime, {
6898
+ details,
6899
+ event: "agent.gui.caught_error",
6900
+ level: "error",
6901
+ source: "agent-gui",
6902
+ workspaceId: input.workspaceId
6903
+ });
6902
6904
  }
6903
6905
  function showAgentGUIControllerErrorToast(hostToast, message) {
6904
6906
  if (hostToast?.error) {
@@ -6908,102 +6910,70 @@ function showAgentGUIControllerErrorToast(hostToast, message) {
6908
6910
  toast.error(message);
6909
6911
  }
6910
6912
  function reportAgentGUIConversationFilterTargetUnresolved(input) {
6911
- const reportDiagnostic = input.runtime.reportDiagnostic;
6912
- if (!reportDiagnostic) {
6913
- return;
6914
- }
6915
- try {
6916
- void Promise.resolve(
6917
- reportDiagnostic.call(input.runtime, {
6918
- details: {
6919
- provider: input.provider,
6920
- providerTargetCount: input.providerTargetCount,
6921
- providerTargetId: input.providerTargetId,
6922
- reason: input.reason
6923
- },
6924
- event: "agent.gui.conversation_filter.target_unresolved",
6925
- level: "warn",
6926
- source: "agent-gui",
6927
- workspaceId: input.workspaceId
6928
- })
6929
- ).catch(() => {
6930
- });
6931
- } catch {
6932
- }
6913
+ reportAgentGUIDiagnostic(input.runtime, {
6914
+ details: {
6915
+ provider: input.provider,
6916
+ providerTargetCount: input.providerTargetCount,
6917
+ providerTargetId: input.providerTargetId,
6918
+ reason: input.reason
6919
+ },
6920
+ event: "agent.gui.conversation_filter.target_unresolved",
6921
+ level: "warn",
6922
+ source: "agent-gui",
6923
+ workspaceId: input.workspaceId
6924
+ });
6933
6925
  }
6934
6926
  function reportAgentGUIMessagePageDiagnostic(input) {
6935
- const reportDiagnostic = input.runtime.reportDiagnostic;
6936
- if (!reportDiagnostic) {
6937
- return;
6938
- }
6939
6927
  const versions = (input.messages ?? []).map((message) => message.version).filter((version) => Number.isFinite(version));
6940
- try {
6941
- void Promise.resolve(
6942
- reportDiagnostic.call(input.runtime, {
6943
- details: {
6944
- agentSessionId: input.agentSessionId,
6945
- ...input.messages ? {
6946
- firstVersion: versions.length ? Math.min(...versions) : null,
6947
- lastVersion: versions.length ? Math.max(...versions) : null,
6948
- messageCount: input.messages.length
6949
- } : {},
6950
- ...input.details ?? {}
6951
- },
6952
- event: input.event,
6953
- level: input.level ?? "info",
6954
- source: "agent-gui",
6955
- workspaceId: input.workspaceId
6956
- })
6957
- ).catch(() => {
6958
- });
6959
- } catch {
6960
- }
6928
+ reportAgentGUIDiagnostic(input.runtime, {
6929
+ details: {
6930
+ agentSessionId: input.agentSessionId,
6931
+ ...input.messages ? {
6932
+ firstVersion: versions.length ? Math.min(...versions) : null,
6933
+ lastVersion: versions.length ? Math.max(...versions) : null,
6934
+ messageCount: input.messages.length
6935
+ } : {},
6936
+ ...input.details ?? {}
6937
+ },
6938
+ event: input.event,
6939
+ level: input.level ?? "info",
6940
+ source: "agent-gui",
6941
+ workspaceId: input.workspaceId
6942
+ });
6961
6943
  }
6962
6944
  function reportAgentGUIRenderStateDiagnostic(input) {
6963
- const reportDiagnostic = input.runtime.reportDiagnostic;
6964
- if (!reportDiagnostic) {
6965
- return;
6966
- }
6967
- try {
6968
- void Promise.resolve(
6969
- reportDiagnostic.call(input.runtime, {
6970
- details: {
6971
- activeActivityDisplayStatus: input.activeActivityDisplayStatus,
6972
- activeConversationBusy: input.activeConversationBusy,
6973
- activeConversationId: input.activeConversationId,
6974
- activeConversationStatus: input.activeConversation?.status ?? null,
6975
- activeHasPendingSubmittedTurn: input.activeHasPendingSubmittedTurn,
6976
- activeLiveState: input.activeLiveState,
6977
- activeSubmitBlocked: input.activeSubmitBlocked,
6978
- canQueueWhileBusy: input.canQueueWhileBusy,
6979
- canSubmit: input.canSubmit,
6980
- conversation: agentGUIConversationDiagnosticDetails(
6981
- input.conversation
6982
- ),
6983
- isCreatingConversation: input.isCreatingConversation,
6984
- isLoadingMessages: input.isLoadingMessages,
6985
- isSubmitting: input.isSubmitting,
6986
- pendingApprovalRequestId: input.pendingApproval?.requestId ?? null,
6987
- pendingInteractivePromptKind: input.pendingInteractivePrompt?.kind ?? null,
6988
- pendingInteractivePromptRequestId: promptRequestId(
6989
- input.pendingInteractivePrompt
6990
- ),
6991
- runtimeSession: agentGUIRuntimeSessionDiagnosticDetails(
6992
- input.activeRuntimeSession
6993
- ),
6994
- sessionState: agentGUISessionStateDiagnosticDetails(
6995
- input.activeSessionState
6996
- )
6997
- },
6998
- event: "agent.gui.node.render_state_changed",
6999
- level: "info",
7000
- source: "agent-gui",
7001
- workspaceId: input.workspaceId
7002
- })
7003
- ).catch(() => {
7004
- });
7005
- } catch {
7006
- }
6945
+ reportAgentGUIDiagnostic(input.runtime, {
6946
+ details: {
6947
+ activeActivityDisplayStatus: input.activeActivityDisplayStatus,
6948
+ activeConversationBusy: input.activeConversationBusy,
6949
+ activeConversationId: input.activeConversationId,
6950
+ activeConversationStatus: input.activeConversation?.status ?? null,
6951
+ activeHasPendingSubmittedTurn: input.activeHasPendingSubmittedTurn,
6952
+ activeLiveState: input.activeLiveState,
6953
+ activeSubmitBlocked: input.activeSubmitBlocked,
6954
+ canQueueWhileBusy: input.canQueueWhileBusy,
6955
+ canSubmit: input.canSubmit,
6956
+ conversation: agentGUIConversationDiagnosticDetails(input.conversation),
6957
+ isCreatingConversation: input.isCreatingConversation,
6958
+ isLoadingMessages: input.isLoadingMessages,
6959
+ isSubmitting: input.isSubmitting,
6960
+ pendingApprovalRequestId: input.pendingApproval?.requestId ?? null,
6961
+ pendingInteractivePromptKind: input.pendingInteractivePrompt?.kind ?? null,
6962
+ pendingInteractivePromptRequestId: promptRequestId(
6963
+ input.pendingInteractivePrompt
6964
+ ),
6965
+ runtimeSession: agentGUIRuntimeSessionDiagnosticDetails(
6966
+ input.activeRuntimeSession
6967
+ ),
6968
+ sessionState: agentGUISessionStateDiagnosticDetails(
6969
+ input.activeSessionState
6970
+ )
6971
+ },
6972
+ event: "agent.gui.node.render_state_changed",
6973
+ level: "info",
6974
+ source: "agent-gui",
6975
+ workspaceId: input.workspaceId
6976
+ });
7007
6977
  }
7008
6978
  function reportAgentGUIActiveConversationCleared(input) {
7009
6979
  const reportDiagnostic = input.runtime.reportDiagnostic;
@@ -7806,14 +7776,7 @@ function messageActivityTimeUnixMs(message) {
7806
7776
  return null;
7807
7777
  }
7808
7778
  function minFiniteMessageVersion(messages) {
7809
- let result = null;
7810
- for (const message of messages) {
7811
- if (!Number.isFinite(message.version) || isWorkspaceAgentActivityOptimisticMessage(message)) {
7812
- continue;
7813
- }
7814
- result = result === null ? message.version : Math.min(result, message.version);
7815
- }
7816
- return result;
7779
+ return minFiniteDurableWorkspaceAgentActivityMessageVersion(messages);
7817
7780
  }
7818
7781
  function isUserTextMessage(message) {
7819
7782
  return message.kind.trim().toLowerCase() === "text" && message.role.trim().toLowerCase() === "user" && workspaceAgentActivityMessageText(message).trim() !== "";
@@ -8496,6 +8459,9 @@ function useStableStringArrayByValue(values) {
8496
8459
  }
8497
8460
  return currentValues ?? values;
8498
8461
  }
8462
+ function agentGUISectionActionAgentTargetId(filter) {
8463
+ return filter.kind === "agentTarget" ? normalizeOptionalText2(filter.agentTargetId) ?? void 0 : void 0;
8464
+ }
8499
8465
  function agentSessionStatusBusy(input) {
8500
8466
  const normalized = normalizeOptionalWorkspaceAgentStatus(input);
8501
8467
  return normalized?.kind === "working" || normalized?.kind === "waiting";
@@ -8509,6 +8475,14 @@ function conversationBusyStatusFromAgentActivityDisplayStatus(status) {
8509
8475
  }
8510
8476
  return null;
8511
8477
  }
8478
+ function agentActivitySessionHasLiveTurn(session) {
8479
+ const lifecycle = session?.turnLifecycle;
8480
+ if (!lifecycle || lifecycle.settling === true) {
8481
+ return false;
8482
+ }
8483
+ const activeTurnId = lifecycle.activeTurnId?.trim() ?? "";
8484
+ return activeTurnId !== "" || isLiveTurnLifecyclePhase(lifecycle.phase);
8485
+ }
8512
8486
  function reuseAgentActivityDisplayStatusesIfUnchanged(previous, next) {
8513
8487
  if (!previous || previous.size !== next.size) {
8514
8488
  return next;
@@ -8798,7 +8772,7 @@ function mergeSessionControlStatePatch(current, patch) {
8798
8772
  }
8799
8773
  if (patch.turn?.phase) {
8800
8774
  next.turnLifecycle = {
8801
- activeTurnId: patch.turn.activeTurnId !== void 0 ? patch.turn.activeTurnId : patch.turn.phase === "settled" ? null : patch.turn.turnId,
8775
+ activeTurnId: patch.turn.activeTurnId !== void 0 ? patch.turn.activeTurnId : patch.turn.phase === "settled" || patch.turn.phase === "idle" ? null : patch.turn.turnId,
8802
8776
  phase: patch.turn.phase,
8803
8777
  settling: patch.turn.settling,
8804
8778
  outcome: patch.turn.outcome ?? null,
@@ -8948,6 +8922,22 @@ function useAgentGUINodeController({
8948
8922
  onShowMessage
8949
8923
  }) {
8950
8924
  const agentActivityRuntime = useAgentActivityRuntime();
8925
+ const canCancel = agentActivityRuntimeCapabilityEnabled(
8926
+ agentActivityRuntime,
8927
+ "canCancel"
8928
+ );
8929
+ const canSubmitInteractive = agentActivityRuntimeCapabilityEnabled(
8930
+ agentActivityRuntime,
8931
+ "canSubmitInteractive"
8932
+ );
8933
+ const canGoalControl = agentActivityRuntimeCapabilityEnabled(
8934
+ agentActivityRuntime,
8935
+ "canGoalControl"
8936
+ );
8937
+ const canUploadAttachment = agentActivityRuntimeCapabilityEnabled(
8938
+ agentActivityRuntime,
8939
+ "canUploadAttachment"
8940
+ );
8951
8941
  const agentActivityRuntimeOrigin = agentActivityRuntime.origin?.trim() || AGENT_GUI_RUNTIME_SESSION_ORIGIN;
8952
8942
  const agentQueuedPromptRuntime = useAgentQueuedPromptRuntime();
8953
8943
  const agentHostApi = useAgentHostApi();
@@ -9204,6 +9194,7 @@ function useAgentGUINodeController({
9204
9194
  pendingDeleteProjectConversations,
9205
9195
  setPendingDeleteProjectConversations
9206
9196
  ] = useState4(null);
9197
+ const [pendingDeleteConversations, setPendingDeleteConversations] = useState4(null);
9207
9198
  const [listError, setListError] = useState4(null);
9208
9199
  const [detailError, setDetailError] = useState4(null);
9209
9200
  const [statePatchErrorBySessionId, setStatePatchErrorBySessionId] = useState4({});
@@ -9256,7 +9247,7 @@ function useAgentGUINodeController({
9256
9247
  ) ? true : selectedModelForPromptImages === null ? false : providerComposerOptions?.models.find(
9257
9248
  (option) => option.value === selectedModelForPromptImages
9258
9249
  )?.supportsImageInput ?? false;
9259
- const promptImagesSupported = (resolvedPromptImagesSupported ?? true) && selectedModelImageInputSupported;
9250
+ const promptImagesSupported = canUploadAttachment && (resolvedPromptImagesSupported ?? true) && selectedModelImageInputSupported;
9260
9251
  const compactSupported = resolveAgentActivityCapability2("compact", {
9261
9252
  composerOptions: providerComposerOptions,
9262
9253
  sessionRuntimeContext: activeSessionRuntimeContext
@@ -9334,6 +9325,7 @@ function useAgentGUINodeController({
9334
9325
  ),
9335
9326
  [agentActivitySnapshot.sessions]
9336
9327
  );
9328
+ const activeRuntimeSession = runtimeSessionsBySessionId.get(activeConversationId ?? "") ?? null;
9337
9329
  const stableRuntimeSyncStateBySessionId = useMemo3(() => {
9338
9330
  const current = stableRuntimeSyncStateBySessionIdRef.current;
9339
9331
  let next = current;
@@ -12403,6 +12395,16 @@ function useAgentGUINodeController({
12403
12395
  setIsLoadingMessages(false);
12404
12396
  setDetailError(null);
12405
12397
  persistActiveConversation(null);
12398
+ const homeDraftKeysToClear = /* @__PURE__ */ new Set();
12399
+ if (previous) {
12400
+ const selectedTargetData = selectedComposerTargetDataRef.current;
12401
+ homeDraftKeysToClear.add(
12402
+ nodeDefaultDraftContentKey(
12403
+ selectedTargetData.provider,
12404
+ selectedTargetData.agentTargetId
12405
+ )
12406
+ );
12407
+ }
12406
12408
  const filter = conversationFilterRef.current;
12407
12409
  if (filter.kind === "agentTarget") {
12408
12410
  const filterTarget = resolveAgentGUIProviderTarget({
@@ -12414,8 +12416,31 @@ function useAgentGUINodeController({
12414
12416
  });
12415
12417
  if (filterTarget && filterTarget.disabled !== true && (filterTarget.agentTargetId?.trim() ?? "") === filter.agentTargetId) {
12416
12418
  setHomeComposerTargetOverride(filterTarget);
12419
+ if (previous) {
12420
+ homeDraftKeysToClear.add(
12421
+ nodeDefaultDraftContentKey(
12422
+ filterTarget.provider,
12423
+ filterTarget.agentTargetId
12424
+ )
12425
+ );
12426
+ }
12417
12427
  }
12418
12428
  }
12429
+ const clearHomeDrafts = (current) => {
12430
+ let next = null;
12431
+ for (const key of homeDraftKeysToClear) {
12432
+ const existing = current[key];
12433
+ if (existing && agentComposerDraftHasContent(existing)) {
12434
+ next = next ?? { ...current };
12435
+ next[key] = emptyAgentComposerDraft();
12436
+ }
12437
+ }
12438
+ return next ?? current;
12439
+ };
12440
+ draftBySessionIdRef.current = clearHomeDrafts(
12441
+ draftBySessionIdRef.current
12442
+ );
12443
+ setDraftBySessionId(clearHomeDrafts);
12419
12444
  loadDraftComposerOptions();
12420
12445
  },
12421
12446
  [
@@ -12985,6 +13010,9 @@ function useAgentGUINodeController({
12985
13010
  if (!normalizedAgentSessionId) {
12986
13011
  return false;
12987
13012
  }
13013
+ if (isCreatingConversationRef.current && startingConversationIdRef.current === normalizedAgentSessionId) {
13014
+ return true;
13015
+ }
12988
13016
  if (pendingTurnIdBySessionIdRef.current[normalizedAgentSessionId]) {
12989
13017
  return true;
12990
13018
  }
@@ -12992,14 +13020,26 @@ function useAgentGUINodeController({
12992
13020
  if (sessionState?.pendingInteractive) {
12993
13021
  return true;
12994
13022
  }
13023
+ const runtimeSession = runtimeSessionsBySessionId.get(normalizedAgentSessionId) ?? null;
13024
+ if (runtimeSession && resolveSubmitAvailability(runtimeSession).state === "blocked") {
13025
+ return true;
13026
+ }
13027
+ const conversationStatus = conversations.find(
13028
+ (conversation2) => conversation2.id === normalizedAgentSessionId
13029
+ )?.status ?? null;
13030
+ if (conversationBusyStatus2(conversationStatus)) {
13031
+ return true;
13032
+ }
12995
13033
  return agentActivityDisplayStatusBusy(
12996
13034
  agentActivityDisplayStatuses.get(normalizedAgentSessionId)
12997
13035
  );
12998
13036
  },
12999
13037
  [
13000
13038
  agentActivityDisplayStatuses,
13039
+ conversations,
13001
13040
  isRespondingApproval,
13002
13041
  isSubmitting,
13042
+ runtimeSessionsBySessionId,
13003
13043
  sessionViewRef
13004
13044
  ]
13005
13045
  );
@@ -13052,7 +13092,7 @@ function useAgentGUINodeController({
13052
13092
  );
13053
13093
  const goalControl = useCallback4(
13054
13094
  (action, objective) => {
13055
- if (previewMode) {
13095
+ if (previewMode || !canGoalControl) {
13056
13096
  return;
13057
13097
  }
13058
13098
  const agentSessionId = activeConversationIdRef.current;
@@ -13082,6 +13122,7 @@ function useAgentGUINodeController({
13082
13122
  },
13083
13123
  [
13084
13124
  agentActivityRuntime,
13125
+ canGoalControl,
13085
13126
  executePrompt,
13086
13127
  isCurrentConversation,
13087
13128
  previewMode,
@@ -13173,7 +13214,7 @@ function useAgentGUINodeController({
13173
13214
  setDetailError(translate("agentHost.agentGui.promptImagesUnsupported"));
13174
13215
  return;
13175
13216
  }
13176
- const activeTurnId = activeSessionState?.turnLifecycle?.activeTurnId?.trim() ?? "";
13217
+ const activeTurnId = activeRuntimeSession?.turnLifecycle?.activeTurnId?.trim() || activeSessionState?.turnLifecycle?.activeTurnId?.trim() || "";
13177
13218
  if (activeTurnId === "") {
13178
13219
  return;
13179
13220
  }
@@ -13185,7 +13226,13 @@ function useAgentGUINodeController({
13185
13226
  { bypassLocalQueue: true, guidance: true }
13186
13227
  );
13187
13228
  },
13188
- [activeSessionState, promptImagesSupported, submitExistingPrompt, translate]
13229
+ [
13230
+ activeRuntimeSession,
13231
+ activeSessionState,
13232
+ promptImagesSupported,
13233
+ submitExistingPrompt,
13234
+ translate
13235
+ ]
13189
13236
  );
13190
13237
  useEffect4(() => {
13191
13238
  if (previewMode) {
@@ -13203,6 +13250,9 @@ function useAgentGUINodeController({
13203
13250
  }, []);
13204
13251
  const submitInteractivePrompt = useCallback4(
13205
13252
  (input) => {
13253
+ if (!canSubmitInteractive) {
13254
+ return;
13255
+ }
13206
13256
  if (input.action === PLAN_IMPLEMENTATION_ACTION_IMPLEMENT) {
13207
13257
  planActionsRef.current.implement();
13208
13258
  return;
@@ -13268,7 +13318,8 @@ function useAgentGUINodeController({
13268
13318
  loadSessionState,
13269
13319
  refreshMessagesFromSnapshot,
13270
13320
  workspaceId,
13271
- agentActivityRuntime
13321
+ agentActivityRuntime,
13322
+ canSubmitInteractive
13272
13323
  ]
13273
13324
  );
13274
13325
  const submitApprovalOption = useCallback4(
@@ -13279,6 +13330,9 @@ function useAgentGUINodeController({
13279
13330
  );
13280
13331
  const interruptCurrentTurn = useCallback4(
13281
13332
  (noRunningResponseMessage) => {
13333
+ if (!canCancel) {
13334
+ return;
13335
+ }
13282
13336
  const agentSessionId = activeConversationIdRef.current;
13283
13337
  if (!agentSessionId || interruptingSessionIds[agentSessionId]) {
13284
13338
  return;
@@ -13387,7 +13441,8 @@ function useAgentGUINodeController({
13387
13441
  runtimeSessionsBySessionId,
13388
13442
  activeSessionState,
13389
13443
  workspaceId,
13390
- agentActivityRuntime
13444
+ agentActivityRuntime,
13445
+ canCancel
13391
13446
  ]
13392
13447
  );
13393
13448
  useEffect4(() => {
@@ -13564,6 +13619,20 @@ function useAgentGUINodeController({
13564
13619
  target: targetData,
13565
13620
  options: snapshotComposerOptions
13566
13621
  });
13622
+ agentActivityRuntime.reportDiagnostic?.({
13623
+ details: {
13624
+ agentTargetId: targetData.agentTargetId ?? null,
13625
+ changedFields: Object.keys(supportedNextSettings).sort().join(","),
13626
+ nextModel: supportedNextSettings.model ?? null,
13627
+ previousModel: previousSettings.model ?? null,
13628
+ provider: targetData.provider,
13629
+ reason: "no_active_conversation",
13630
+ resolvedModel: targetSafeMerged.model ?? null
13631
+ },
13632
+ event: "agent.gui.composer_settings.default_only",
13633
+ level: "info",
13634
+ workspaceId
13635
+ });
13567
13636
  draftSettingsBySessionIdRef.current = {
13568
13637
  ...draftSettingsBySessionIdRef.current,
13569
13638
  [defaultDraftKey]: targetSafeMerged
@@ -13654,7 +13723,54 @@ function useAgentGUINodeController({
13654
13723
  );
13655
13724
  }
13656
13725
  }
13657
- if (Object.keys(sessionSettingsPatch).length > 0 && (activeSessionState2 !== null || isPreActivationSession)) {
13726
+ const sessionSettingsPatchKeys = Object.keys(sessionSettingsPatch).sort();
13727
+ if (sessionSettingsPatchKeys.length === 0 && (nextModel !== void 0 || nextReasoningEffort !== void 0 || nextSpeed !== void 0 || nextPlanMode !== void 0 || nextPermission !== void 0 || nextBrowserUse !== void 0 || nextComputerUse !== void 0)) {
13728
+ agentActivityRuntime.reportDiagnostic?.({
13729
+ details: {
13730
+ agentSessionId,
13731
+ agentTargetId: normalizeOptionalText2(dataRef.current.agentTargetId),
13732
+ attemptedModel: nextModel ?? null,
13733
+ currentModel,
13734
+ provider: dataRef.current.provider,
13735
+ reason: "settings_already_current"
13736
+ },
13737
+ event: "agent.gui.composer_settings.update_noop",
13738
+ level: "info",
13739
+ workspaceId
13740
+ });
13741
+ }
13742
+ if (sessionSettingsPatchKeys.length > 0 && activeSessionState2 === null && !isPreActivationSession) {
13743
+ agentActivityRuntime.reportDiagnostic?.({
13744
+ details: {
13745
+ agentSessionId,
13746
+ agentTargetId: normalizeOptionalText2(dataRef.current.agentTargetId),
13747
+ changedFields: sessionSettingsPatchKeys.join(","),
13748
+ currentModel,
13749
+ nextModel: sessionSettingsPatch.model ?? null,
13750
+ provider: dataRef.current.provider,
13751
+ reason: "missing_active_session_state"
13752
+ },
13753
+ event: "agent.gui.composer_settings.update_skipped",
13754
+ level: "warn",
13755
+ workspaceId
13756
+ });
13757
+ }
13758
+ if (sessionSettingsPatchKeys.length > 0 && (activeSessionState2 !== null || isPreActivationSession)) {
13759
+ agentActivityRuntime.reportDiagnostic?.({
13760
+ details: {
13761
+ agentSessionId,
13762
+ agentTargetId: normalizeOptionalText2(dataRef.current.agentTargetId),
13763
+ changedFields: sessionSettingsPatchKeys.join(","),
13764
+ currentModel,
13765
+ isPreActivationSession,
13766
+ nextModel: sessionSettingsPatch.model ?? null,
13767
+ provider: dataRef.current.provider,
13768
+ turnPhase: activeSessionState2?.turnLifecycle?.phase ?? null
13769
+ },
13770
+ event: "agent.gui.composer_settings.update_requested",
13771
+ level: "info",
13772
+ workspaceId
13773
+ });
13658
13774
  updateAgentSessionViewControlState(
13659
13775
  sessionViewRef(agentSessionId),
13660
13776
  (existing) => {
@@ -13944,30 +14060,54 @@ function useAgentGUINodeController({
13944
14060
  if (!normalizedPath || isDeletingProjectConversations) {
13945
14061
  return;
13946
14062
  }
13947
- const targetConversations = conversationsRef.current.filter(
13948
- (conversation2) => normalizeProjectConversationPath(
13949
- resolveAgentGUIConversationProject(
13950
- conversation2.cwd,
13951
- userProjectsRef.current,
13952
- { isNoProjectPath: isNoProjectPathRef.current }
13953
- )?.path
13954
- ) === normalizedPath
13955
- );
13956
- if (targetConversations.length === 0) {
14063
+ const countSessionSection = agentActivityRuntime.countSessionSection;
14064
+ if (!countSessionSection) {
13957
14065
  return;
13958
14066
  }
13959
14067
  const project = userProjectsRef.current.find(
13960
14068
  (candidate) => normalizeProjectConversationPath(candidate.path) === normalizedPath
13961
14069
  );
14070
+ setDetailError(null);
14071
+ setListError(null);
13962
14072
  setPendingDeleteProjectConversations({
13963
- conversationCount: targetConversations.length,
14073
+ conversationCount: null,
13964
14074
  label: project?.label?.trim() || path,
13965
14075
  path: normalizedPath
13966
14076
  });
13967
- setDetailError(null);
13968
- setListError(null);
14077
+ void countSessionSection({
14078
+ agentTargetId: agentGUISectionActionAgentTargetId(
14079
+ conversationFilterRef.current
14080
+ ),
14081
+ sectionKey: projectConversationSectionKey(normalizedPath),
14082
+ workspaceId
14083
+ }).then((count) => {
14084
+ if (count.count <= 0) {
14085
+ setPendingDeleteProjectConversations(
14086
+ (current) => current?.path === normalizedPath ? null : current
14087
+ );
14088
+ return;
14089
+ }
14090
+ setPendingDeleteProjectConversations(
14091
+ (current) => current?.path === normalizedPath ? {
14092
+ ...current,
14093
+ conversationCount: count.count
14094
+ } : current
14095
+ );
14096
+ }).catch((error) => {
14097
+ const message = getAgentGUIErrorMessage(error);
14098
+ setPendingDeleteProjectConversations(
14099
+ (current) => current?.path === normalizedPath ? null : current
14100
+ );
14101
+ setListError(message);
14102
+ showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14103
+ });
13969
14104
  },
13970
- [isDeletingProjectConversations]
14105
+ [
14106
+ agentActivityRuntime,
14107
+ agentHostApi.toast,
14108
+ isDeletingProjectConversations,
14109
+ workspaceId
14110
+ ]
13971
14111
  );
13972
14112
  const cancelDeleteProjectConversations = useCallback4(() => {
13973
14113
  if (isDeletingProjectConversations) {
@@ -14135,181 +14275,226 @@ function useAgentGUINodeController({
14135
14275
  removeConversations
14136
14276
  ]
14137
14277
  );
14138
- const confirmDeleteProjectConversations = useCallback4(
14139
- (path) => {
14140
- const normalizedPath = normalizeProjectConversationPath(path);
14141
- const target = normalizedPath !== "" ? {
14142
- conversationCount: conversationsRef.current.filter(
14143
- (conversation2) => normalizeProjectConversationPath(
14144
- resolveAgentGUIConversationProject(
14145
- conversation2.cwd,
14146
- userProjectsRef.current,
14147
- { isNoProjectPath: isNoProjectPathRef.current }
14148
- )?.path
14149
- ) === normalizedPath
14150
- ).length,
14151
- label: userProjectsRef.current.find(
14152
- (project) => normalizeProjectConversationPath(project.path) === normalizedPath
14153
- )?.label ?? path ?? normalizedPath,
14154
- path: normalizedPath
14155
- } : pendingDeleteProjectConversations;
14156
- if (!target || isDeletingProjectConversations) {
14157
- return;
14158
- }
14159
- const targetConversations = conversationsRef.current.filter(
14160
- (conversation2) => normalizeProjectConversationPath(
14161
- resolveAgentGUIConversationProject(
14162
- conversation2.cwd,
14163
- userProjectsRef.current,
14164
- { isNoProjectPath: isNoProjectPathRef.current }
14165
- )?.path
14166
- ) === target.path
14278
+ const confirmDeleteProjectConversations = useCallback4(() => {
14279
+ const target = pendingDeleteProjectConversations;
14280
+ if (!target || isDeletingProjectConversations) {
14281
+ return;
14282
+ }
14283
+ if (target.conversationCount === null) {
14284
+ return;
14285
+ }
14286
+ const targetConversations = conversationsRef.current.filter(
14287
+ (conversation2) => normalizeProjectConversationPath(
14288
+ resolveAgentGUIConversationProject(
14289
+ conversation2.cwd,
14290
+ userProjectsRef.current,
14291
+ { isNoProjectPath: isNoProjectPathRef.current }
14292
+ )?.path
14293
+ ) === target.path
14294
+ );
14295
+ const seedTargetIds = new Set(
14296
+ targetConversations.map((conversation2) => conversation2.id)
14297
+ );
14298
+ const deleteSessionSection = agentActivityRuntime.deleteSessionSection;
14299
+ if (!deleteSessionSection) {
14300
+ return;
14301
+ }
14302
+ setIsDeletingProjectConversations(true);
14303
+ setDetailError(null);
14304
+ setListError(null);
14305
+ const activeDeletedConversationId = activeConversationIdRef.current;
14306
+ if (activeDeletedConversationId && seedTargetIds.has(activeDeletedConversationId)) {
14307
+ clearSelectedConversationNotFoundRetry();
14308
+ setIsLoadingMessages(true);
14309
+ setAgentSessionViewMessagesLoading(
14310
+ sessionViewRef(activeDeletedConversationId),
14311
+ true
14312
+ );
14313
+ }
14314
+ const targetSectionKey = projectConversationSectionKey(target.path);
14315
+ void deleteSessionSection({
14316
+ agentTargetId: agentGUISectionActionAgentTargetId(
14317
+ conversationFilterRef.current
14318
+ ),
14319
+ sectionKey: targetSectionKey,
14320
+ workspaceId
14321
+ }).then((result) => {
14322
+ const targetIds = new Set(
14323
+ result.removedSessionIds.map((id) => id.trim()).filter((id) => id !== "")
14167
14324
  );
14168
- if (targetConversations.length === 0) {
14325
+ if (targetIds.size === 0) {
14169
14326
  setPendingDeleteProjectConversations(null);
14170
14327
  return;
14171
14328
  }
14172
- const targetIds = new Set(
14173
- targetConversations.map((conversation2) => conversation2.id)
14174
- );
14175
- setIsDeletingProjectConversations(true);
14176
- setDetailError(null);
14177
- setListError(null);
14178
- const activeDeletedConversationId = activeConversationIdRef.current;
14179
- if (activeDeletedConversationId && targetIds.has(activeDeletedConversationId)) {
14180
- clearSelectedConversationNotFoundRetry();
14181
- setIsLoadingMessages(true);
14329
+ finalizeConversationBatchDeletion(targetIds);
14330
+ setPendingDeleteProjectConversations(null);
14331
+ }).catch((error) => {
14332
+ const message = getAgentGUIErrorMessage(error);
14333
+ reportAgentGUIRuntimeError({
14334
+ error,
14335
+ phase: "delete_conversation",
14336
+ provider: dataRef.current.provider,
14337
+ runtime: agentActivityRuntime,
14338
+ workspaceId,
14339
+ context: {
14340
+ projectPath: target.path,
14341
+ sectionKey: targetSectionKey,
14342
+ conversationCount: target.conversationCount
14343
+ }
14344
+ });
14345
+ setListError(message);
14346
+ showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14347
+ if (activeDeletedConversationId && activeConversationIdRef.current === activeDeletedConversationId) {
14348
+ setIsLoadingMessages(false);
14182
14349
  setAgentSessionViewMessagesLoading(
14183
14350
  sessionViewRef(activeDeletedConversationId),
14184
- true
14351
+ false
14185
14352
  );
14186
14353
  }
14187
- void Promise.all(
14188
- targetConversations.map(async (conversation2) => {
14189
- await activation.unactivate(conversation2.id);
14190
- await agentActivityRuntime.deleteSession({
14191
- workspaceId,
14192
- agentSessionId: conversation2.id
14193
- });
14194
- })
14195
- ).then(() => {
14196
- finalizeConversationBatchDeletion(targetIds);
14197
- setPendingDeleteProjectConversations(null);
14198
- }).catch((error) => {
14199
- const message = getAgentGUIErrorMessage(error);
14200
- reportAgentGUIRuntimeError({
14201
- error,
14202
- phase: "delete_conversation",
14203
- provider: dataRef.current.provider,
14204
- runtime: agentActivityRuntime,
14205
- workspaceId,
14206
- context: {
14207
- projectPath: target.path,
14208
- conversationCount: targetConversations.length
14209
- }
14210
- });
14211
- setListError(message);
14212
- showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14213
- if (activeDeletedConversationId && activeConversationIdRef.current === activeDeletedConversationId) {
14214
- setIsLoadingMessages(false);
14215
- setAgentSessionViewMessagesLoading(
14216
- sessionViewRef(activeDeletedConversationId),
14217
- false
14218
- );
14219
- }
14220
- }).finally(() => {
14221
- setIsDeletingProjectConversations(false);
14222
- });
14223
- },
14224
- [
14225
- activation,
14226
- agentActivityRuntime,
14227
- conversationListQuery,
14228
- clearSelectedConversationNotFoundRetry,
14229
- finalizeConversationBatchDeletion,
14230
- isDeletingProjectConversations,
14231
- markSelectedConversationDetailPending,
14232
- pendingDeleteProjectConversations,
14233
- persistActiveConversation,
14234
- sessionViewRef,
14235
- setTransientConversation,
14236
- removeConversations,
14237
- agentHostApi.toast,
14354
+ }).finally(() => {
14355
+ setIsDeletingProjectConversations(false);
14356
+ });
14357
+ }, [
14358
+ agentActivityRuntime,
14359
+ clearSelectedConversationNotFoundRetry,
14360
+ finalizeConversationBatchDeletion,
14361
+ isDeletingProjectConversations,
14362
+ pendingDeleteProjectConversations,
14363
+ sessionViewRef,
14364
+ agentHostApi.toast,
14365
+ workspaceId
14366
+ ]);
14367
+ const requestDeleteConversations = useCallback4(() => {
14368
+ if (isDeletingProjectConversations) {
14369
+ return;
14370
+ }
14371
+ const countSessionSection = agentActivityRuntime.countSessionSection;
14372
+ if (!countSessionSection) {
14373
+ return;
14374
+ }
14375
+ setDetailError(null);
14376
+ setListError(null);
14377
+ setPendingDeleteConversations({
14378
+ conversationCount: null
14379
+ });
14380
+ void countSessionSection({
14381
+ agentTargetId: agentGUISectionActionAgentTargetId(
14382
+ conversationFilterRef.current
14383
+ ),
14384
+ sectionKey: "conversations",
14238
14385
  workspaceId
14239
- ]
14240
- );
14241
- const confirmDeleteConversations = useCallback4(
14242
- (agentSessionIds) => {
14243
- if (isDeletingProjectConversations) {
14386
+ }).then((count) => {
14387
+ if (count.count <= 0) {
14388
+ setPendingDeleteConversations(null);
14244
14389
  return;
14245
14390
  }
14246
- const targetIds = new Set(
14247
- agentSessionIds.map((id) => id.trim()).filter((id) => id !== "")
14391
+ setPendingDeleteConversations(
14392
+ (current) => current ? {
14393
+ conversationCount: count.count
14394
+ } : current
14248
14395
  );
14249
- const targetConversations = conversationsRef.current.filter(
14250
- (conversation2) => targetIds.has(conversation2.id)
14396
+ }).catch((error) => {
14397
+ const message = getAgentGUIErrorMessage(error);
14398
+ setPendingDeleteConversations(null);
14399
+ setListError(message);
14400
+ showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14401
+ });
14402
+ }, [
14403
+ agentActivityRuntime,
14404
+ agentHostApi.toast,
14405
+ isDeletingProjectConversations,
14406
+ workspaceId
14407
+ ]);
14408
+ const cancelDeleteConversations = useCallback4(() => {
14409
+ if (isDeletingProjectConversations) {
14410
+ return;
14411
+ }
14412
+ setPendingDeleteConversations(null);
14413
+ }, [isDeletingProjectConversations]);
14414
+ const confirmDeleteConversations = useCallback4(() => {
14415
+ const target = pendingDeleteConversations;
14416
+ if (!target || isDeletingProjectConversations) {
14417
+ return;
14418
+ }
14419
+ if (target.conversationCount === null) {
14420
+ return;
14421
+ }
14422
+ const deleteSessionSection = agentActivityRuntime.deleteSessionSection;
14423
+ if (!deleteSessionSection) {
14424
+ return;
14425
+ }
14426
+ const seedTargetIds = new Set(
14427
+ conversationsRef.current.filter(
14428
+ (conversation2) => !resolveAgentGUIConversationProject(
14429
+ conversation2.cwd,
14430
+ userProjectsRef.current,
14431
+ { isNoProjectPath: isNoProjectPathRef.current }
14432
+ )
14433
+ ).map((conversation2) => conversation2.id)
14434
+ );
14435
+ setIsDeletingProjectConversations(true);
14436
+ setDetailError(null);
14437
+ setListError(null);
14438
+ const activeDeletedConversationId = activeConversationIdRef.current;
14439
+ if (activeDeletedConversationId && seedTargetIds.has(activeDeletedConversationId)) {
14440
+ clearSelectedConversationNotFoundRetry();
14441
+ setIsLoadingMessages(true);
14442
+ setAgentSessionViewMessagesLoading(
14443
+ sessionViewRef(activeDeletedConversationId),
14444
+ true
14445
+ );
14446
+ }
14447
+ void deleteSessionSection({
14448
+ agentTargetId: agentGUISectionActionAgentTargetId(
14449
+ conversationFilterRef.current
14450
+ ),
14451
+ sectionKey: "conversations",
14452
+ workspaceId
14453
+ }).then((result) => {
14454
+ const targetIds = new Set(
14455
+ result.removedSessionIds.map((id) => id.trim()).filter((id) => id !== "")
14251
14456
  );
14252
- if (targetConversations.length === 0) {
14457
+ if (targetIds.size === 0) {
14458
+ setPendingDeleteConversations(null);
14253
14459
  return;
14254
14460
  }
14255
- setIsDeletingProjectConversations(true);
14256
- setDetailError(null);
14257
- setListError(null);
14258
- const activeDeletedConversationId = activeConversationIdRef.current;
14259
- if (activeDeletedConversationId && targetIds.has(activeDeletedConversationId)) {
14260
- clearSelectedConversationNotFoundRetry();
14261
- setIsLoadingMessages(true);
14461
+ finalizeConversationBatchDeletion(targetIds);
14462
+ setPendingDeleteConversations(null);
14463
+ }).catch((error) => {
14464
+ const message = getAgentGUIErrorMessage(error);
14465
+ reportAgentGUIRuntimeError({
14466
+ error,
14467
+ phase: "delete_conversation",
14468
+ provider: dataRef.current.provider,
14469
+ runtime: agentActivityRuntime,
14470
+ workspaceId,
14471
+ context: {
14472
+ conversationCount: target.conversationCount,
14473
+ sectionKey: "conversations"
14474
+ }
14475
+ });
14476
+ setListError(message);
14477
+ showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14478
+ if (activeDeletedConversationId && activeConversationIdRef.current === activeDeletedConversationId) {
14479
+ setIsLoadingMessages(false);
14262
14480
  setAgentSessionViewMessagesLoading(
14263
14481
  sessionViewRef(activeDeletedConversationId),
14264
- true
14482
+ false
14265
14483
  );
14266
14484
  }
14267
- void Promise.all(
14268
- targetConversations.map(async (conversation2) => {
14269
- await activation.unactivate(conversation2.id);
14270
- await agentActivityRuntime.deleteSession({
14271
- workspaceId,
14272
- agentSessionId: conversation2.id
14273
- });
14274
- })
14275
- ).then(() => {
14276
- finalizeConversationBatchDeletion(targetIds);
14277
- }).catch((error) => {
14278
- const message = getAgentGUIErrorMessage(error);
14279
- reportAgentGUIRuntimeError({
14280
- error,
14281
- phase: "delete_conversation",
14282
- provider: dataRef.current.provider,
14283
- runtime: agentActivityRuntime,
14284
- workspaceId,
14285
- context: {
14286
- conversationCount: targetConversations.length
14287
- }
14288
- });
14289
- setListError(message);
14290
- showAgentGUIControllerErrorToast(agentHostApi.toast, message);
14291
- if (activeDeletedConversationId && activeConversationIdRef.current === activeDeletedConversationId) {
14292
- setIsLoadingMessages(false);
14293
- setAgentSessionViewMessagesLoading(
14294
- sessionViewRef(activeDeletedConversationId),
14295
- false
14296
- );
14297
- }
14298
- }).finally(() => {
14299
- setIsDeletingProjectConversations(false);
14300
- });
14301
- },
14302
- [
14303
- activation,
14304
- agentActivityRuntime,
14305
- clearSelectedConversationNotFoundRetry,
14306
- finalizeConversationBatchDeletion,
14307
- isDeletingProjectConversations,
14308
- sessionViewRef,
14309
- agentHostApi.toast,
14310
- workspaceId
14311
- ]
14312
- );
14485
+ }).finally(() => {
14486
+ setIsDeletingProjectConversations(false);
14487
+ });
14488
+ }, [
14489
+ agentActivityRuntime,
14490
+ clearSelectedConversationNotFoundRetry,
14491
+ finalizeConversationBatchDeletion,
14492
+ isDeletingProjectConversations,
14493
+ pendingDeleteConversations,
14494
+ sessionViewRef,
14495
+ agentHostApi.toast,
14496
+ workspaceId
14497
+ ]);
14313
14498
  const toggleConversationPinned = useCallback4(
14314
14499
  (agentSessionId, pinned) => {
14315
14500
  const normalizedAgentSessionId = agentSessionId.trim();
@@ -14609,13 +14794,15 @@ function useAgentGUINodeController({
14609
14794
  );
14610
14795
  }, [conversationUserIds, ensureAccountProfiles]);
14611
14796
  const projectionConversationRef = useRef4(null);
14797
+ const activeRuntimeSessionLiveTurn = agentActivitySessionHasLiveTurn(activeRuntimeSession);
14798
+ const activeRuntimeTurnLifecycle = activeRuntimeSessionLiveTurn ? activeRuntimeSession?.turnLifecycle ?? null : null;
14612
14799
  const projectionConversation = useMemo3(() => {
14613
14800
  if (!activeConversation) {
14614
14801
  projectionConversationRef.current = null;
14615
14802
  return null;
14616
14803
  }
14617
14804
  const previous = projectionConversationRef.current;
14618
- const turnLifecycle = activeSessionState?.agentSessionId === activeConversation.id ? activeSessionState.turnLifecycle ?? null : null;
14805
+ const turnLifecycle = activeRuntimeTurnLifecycle ?? (activeSessionState?.agentSessionId === activeConversation.id ? activeSessionState.turnLifecycle ?? null : null);
14619
14806
  if (previous && previous.id === activeConversation.id && previous.userId === activeConversation.userId && previous.provider === activeConversation.provider && previous.title === activeConversation.title && previous.titleFallback === activeConversation.titleFallback && previous.status === activeConversation.status && previous.cwd === activeConversation.cwd && (previous.turnLifecycle?.activeTurnId ?? null) === (turnLifecycle?.activeTurnId ?? null) && (previous.turnLifecycle?.phase ?? null) === (turnLifecycle?.phase ?? null) && (previous.turnLifecycle?.settling ?? false) === (turnLifecycle?.settling ?? false)) {
14620
14807
  return previous;
14621
14808
  }
@@ -14643,6 +14830,9 @@ function useAgentGUINodeController({
14643
14830
  activeConversation?.title,
14644
14831
  activeConversation?.titleFallback,
14645
14832
  activeConversation?.userId,
14833
+ activeRuntimeTurnLifecycle?.activeTurnId,
14834
+ activeRuntimeTurnLifecycle?.phase,
14835
+ activeRuntimeTurnLifecycle?.settling,
14646
14836
  activeSessionState?.agentSessionId,
14647
14837
  activeSessionState?.turnLifecycle?.activeTurnId,
14648
14838
  activeSessionState?.turnLifecycle?.phase,
@@ -14743,7 +14933,7 @@ function useAgentGUINodeController({
14743
14933
  conversation,
14744
14934
  workspaceId
14745
14935
  ]);
14746
- const activeLiveState = activeConversationLiveState;
14936
+ const activeLiveState = activeConversationLiveState === "inactive" && activeRuntimeSessionLiveTurn ? "active" : activeConversationLiveState;
14747
14937
  const activationError = activation.errorFor(activeConversationId);
14748
14938
  const activationErrorCode = activation.codeFor(activeConversationId);
14749
14939
  const hasProviderSessionNotFoundError = isNonRetryableResumeErrorCode(activationErrorCode);
@@ -14800,11 +14990,11 @@ function useAgentGUINodeController({
14800
14990
  activeRawPromptRequestId,
14801
14991
  suppressedPromptRequestId
14802
14992
  ]);
14803
- const pendingApproval = hasProviderSessionNotFoundError || isActivePromptSuppressed ? null : rawPendingApproval;
14804
- const serverInteractivePrompt = hasProviderSessionNotFoundError || isActivePromptSuppressed ? null : rawPendingInteractivePrompt;
14993
+ const pendingApproval = !canSubmitInteractive || hasProviderSessionNotFoundError || isActivePromptSuppressed ? null : rawPendingApproval;
14994
+ const serverInteractivePrompt = !canSubmitInteractive || hasProviderSessionNotFoundError || isActivePromptSuppressed ? null : rawPendingInteractivePrompt;
14805
14995
  const isInterrupting = activeConversationId !== null && Boolean(interruptingSessionIds[activeConversationId]);
14806
14996
  const isCancelPending = activeConversationId !== null && Boolean(pendingInterruptSessionIds[activeConversationId]);
14807
- const queuedPrompts = activeConversationId ? [...activeQueuedPrompts] : [];
14997
+ const queuedPrompts = activeConversationId ? activeQueuedPrompts : EMPTY_QUEUED_PROMPTS;
14808
14998
  const drainingQueuedPromptId = activeQueuedPromptClaim?.promptId ?? null;
14809
14999
  const sessionSettings = useStableComposerSettings(
14810
15000
  cloneComposerSettings(activeSessionState?.settings ?? null)
@@ -14886,12 +15076,11 @@ function useAgentGUINodeController({
14886
15076
  );
14887
15077
  const planImplementationTurnId = activeConversationId !== null && dataRef.current.provider === "codex" && composerSupport.plan && Boolean(draftSettings.planMode) && activeConversation?.status !== "working" ? latestPlanTurnId(activeTimelineItems) : null;
14888
15078
  planImplementationTurnIdRef.current = planImplementationTurnId;
14889
- const planImplementationPromptVM = planImplementationTurnId !== null && activeConversationId !== null && dismissedPlanTurnIdBySessionId[activeConversationId] !== planImplementationTurnId ? planImplementationPromptFromPlanTurn(
15079
+ const planImplementationPromptVM = canSubmitInteractive && planImplementationTurnId !== null && activeConversationId !== null && dismissedPlanTurnIdBySessionId[activeConversationId] !== planImplementationTurnId ? planImplementationPromptFromPlanTurn(
14890
15080
  planImplementationTurnId,
14891
15081
  activeConversation?.title ?? ""
14892
15082
  ) : null;
14893
15083
  const pendingInteractivePrompt = serverInteractivePrompt ?? planImplementationPromptVM;
14894
- const activeRuntimeSession = runtimeSessionsBySessionId.get(activeConversationId ?? "") ?? null;
14895
15084
  useEffect4(() => {
14896
15085
  const provider = normalizeOptionalText2(
14897
15086
  activeRuntimeSession?.provider ?? activeConversation?.provider
@@ -14915,8 +15104,10 @@ function useAgentGUINodeController({
14915
15104
  ]);
14916
15105
  const activeActivityDisplayStatus = activeConversationId ? agentActivityDisplayStatuses.get(activeConversationId) ?? null : null;
14917
15106
  const activeHasPendingSubmittedTurn = activeConversationId ? Boolean(pendingTurnIdBySessionIdRef.current[activeConversationId]) : false;
14918
- const activeSubmitBlocked = activeSessionState ? resolveSubmitAvailability(activeSessionState).state === "blocked" : false;
14919
- const activeConversationBusy = agentActivityDisplayStatusBusy(activeActivityDisplayStatus) || activeHasPendingSubmittedTurn || activeSubmitBlocked;
15107
+ const activeSessionStateSubmitBlocked = activeSessionState ? resolveSubmitAvailability(activeSessionState).state === "blocked" : false;
15108
+ const activeRuntimeSubmitBlocked = activeRuntimeSession ? resolveSubmitAvailability(activeRuntimeSession).state === "blocked" : false;
15109
+ const activeSubmitBlocked = activeSessionStateSubmitBlocked || activeRuntimeSubmitBlocked;
15110
+ const activeConversationBusy = agentActivityDisplayStatusBusy(activeActivityDisplayStatus) || conversationBusyStatus2(activeConversation?.status ?? null) || activeHasPendingSubmittedTurn || activeSubmitBlocked;
14920
15111
  const activeSessionResumable = activeRuntimeSession?.resumable ?? activeConversation?.resumable ?? activeSessionState?.resumable;
14921
15112
  const normalizedActiveConversationId = activeConversationId ?? "";
14922
15113
  const activeConversationActivationState = activeConversationId ? activation.stateFor(activeConversationId) : null;
@@ -14964,8 +15155,9 @@ function useAgentGUINodeController({
14964
15155
  hasProviderSessionNotFoundError,
14965
15156
  pendingApproval
14966
15157
  ]);
14967
- const canSubmit = !providerTargetsLoading && activeLiveState !== "activating" && activeLiveState !== "failed" && !activeConversationResumeUnavailable && (activeConversationId !== null || effectiveSelectedProviderTarget.disabled !== true) && (composerTargetData.provider !== "openclaw" || openclawGateway?.status === "ready") && pendingApproval === null && pendingInteractivePrompt === null && sessionChrome.auth === null && !isCreatingConversation && !isSubmitting && !isInterrupting;
14968
- const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
15158
+ const canSubmit = !providerTargetsLoading && activeLiveState !== "activating" && activeLiveState !== "failed" && !activeConversationResumeUnavailable && (activeConversationId !== null || effectiveSelectedProviderTarget.disabled !== true) && (composerTargetData.provider !== "openclaw" || openclawGateway?.status === "ready") && pendingApproval === null && pendingInteractivePrompt === null && sessionChrome.auth === null && !activeConversationBusy && !isCreatingConversation && !isSubmitting && !isInterrupting;
15159
+ const activeConversationCreatePending = Boolean(activeConversationId) && isCreatingConversation && startingConversationIdRef.current === activeConversationId;
15160
+ const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationCreatePending || activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
14969
15161
  useEffect4(() => {
14970
15162
  const firstVersion = minFiniteMessageVersion(activeMessages);
14971
15163
  const lastVersion = maxFiniteMessageVersion(activeMessages);
@@ -15486,6 +15678,12 @@ function useAgentGUINodeController({
15486
15678
  const stableRequestDeleteProjectConversations = useStableControllerEventCallback(requestDeleteProjectConversations);
15487
15679
  const stableCancelDeleteProjectConversations = useStableControllerEventCallback(cancelDeleteProjectConversations);
15488
15680
  const stableConfirmDeleteProjectConversations = useStableControllerEventCallback(confirmDeleteProjectConversations);
15681
+ const stableRequestDeleteConversations = useStableControllerEventCallback(
15682
+ requestDeleteConversations
15683
+ );
15684
+ const stableCancelDeleteConversations = useStableControllerEventCallback(
15685
+ cancelDeleteConversations
15686
+ );
15489
15687
  const stableConfirmDeleteConversations = useStableControllerEventCallback(
15490
15688
  confirmDeleteConversations
15491
15689
  );
@@ -15545,6 +15743,8 @@ function useAgentGUINodeController({
15545
15743
  requestDeleteProjectConversations: stableRequestDeleteProjectConversations,
15546
15744
  cancelDeleteProjectConversations: stableCancelDeleteProjectConversations,
15547
15745
  confirmDeleteProjectConversations: stableConfirmDeleteProjectConversations,
15746
+ requestDeleteConversations: stableRequestDeleteConversations,
15747
+ cancelDeleteConversations: stableCancelDeleteConversations,
15548
15748
  confirmDeleteConversations: stableConfirmDeleteConversations,
15549
15749
  toggleConversationPinned: stableToggleConversationPinned,
15550
15750
  markConversationUnread: stableMarkConversationUnread,
@@ -15558,6 +15758,7 @@ function useAgentGUINodeController({
15558
15758
  }),
15559
15759
  [
15560
15760
  stableCancelDeleteConversation,
15761
+ stableCancelDeleteConversations,
15561
15762
  stableCancelDeleteProjectConversations,
15562
15763
  stableConfirmDeleteConversation,
15563
15764
  stableConfirmDeleteConversations,
@@ -15572,6 +15773,7 @@ function useAgentGUINodeController({
15572
15773
  stableRemoveQueuedPrompt,
15573
15774
  stableRenameConversation,
15574
15775
  stableRequestDeleteConversation,
15776
+ stableRequestDeleteConversations,
15575
15777
  stableRequestDeleteProjectConversations,
15576
15778
  stableRetryActivation,
15577
15779
  stableRetryOpenclawGateway,
@@ -15623,6 +15825,10 @@ function useAgentGUINodeController({
15623
15825
  isInterrupting,
15624
15826
  isCancelPending,
15625
15827
  isRespondingApproval,
15828
+ canCancel,
15829
+ canSubmitInteractive,
15830
+ canGoalControl,
15831
+ canUploadAttachment,
15626
15832
  promptImagesSupported,
15627
15833
  compactSupported,
15628
15834
  goalPauseSupported,
@@ -15633,11 +15839,13 @@ function useAgentGUINodeController({
15633
15839
  isDeletingProjectConversations,
15634
15840
  pendingDeleteConversation,
15635
15841
  pendingDeleteProjectConversations,
15842
+ pendingDeleteConversations,
15636
15843
  pendingApproval,
15637
15844
  pendingInteractivePrompt,
15638
15845
  activeLiveState,
15639
15846
  activationError,
15640
15847
  openclawGateway,
15848
+ activeConversationBusy,
15641
15849
  canSubmit,
15642
15850
  composerSettings: stableComposerSettings,
15643
15851
  queuedPrompts,
@@ -15668,6 +15876,10 @@ function useAgentGUINodeController({
15668
15876
  availableCommands,
15669
15877
  availableSkills,
15670
15878
  canSubmit,
15879
+ canCancel,
15880
+ canSubmitInteractive,
15881
+ canGoalControl,
15882
+ canUploadAttachment,
15671
15883
  canQueueWhileBusy,
15672
15884
  conversation,
15673
15885
  conversationFilter,
@@ -15705,6 +15917,7 @@ function useAgentGUINodeController({
15705
15917
  hasSentUserMessage,
15706
15918
  pendingDeleteConversation,
15707
15919
  pendingDeleteProjectConversations,
15920
+ pendingDeleteConversations,
15708
15921
  pendingApproval,
15709
15922
  pendingInteractivePrompt,
15710
15923
  effectiveSelectedProviderTarget.disabled,
@@ -15728,6 +15941,10 @@ function normalizeProjectConversationPath(path) {
15728
15941
  }
15729
15942
  return normalized.replace(/\/+$/, "") || "/";
15730
15943
  }
15944
+ function projectConversationSectionKey(path) {
15945
+ const normalizedPath = normalizeProjectConversationPath(path);
15946
+ return normalizedPath ? `project:${normalizedPath}` : "";
15947
+ }
15731
15948
  function omitConversationLocalState(current, conversationIds) {
15732
15949
  let changed = false;
15733
15950
  const next = { ...current };
@@ -15905,9 +16122,9 @@ import {
15905
16122
  Fragment as Fragment8,
15906
16123
  memo as memo2,
15907
16124
  useCallback as useCallback10,
15908
- useEffect as useEffect14,
16125
+ useEffect as useEffect15,
15909
16126
  useLayoutEffect as useLayoutEffect4,
15910
- useMemo as useMemo9,
16127
+ useMemo as useMemo10,
15911
16128
  useRef as useRef12,
15912
16129
  useState as useState14
15913
16130
  } from "react";
@@ -16115,7 +16332,11 @@ import {
16115
16332
  cn as cn3
16116
16333
  } from "@tutti-os/ui-system";
16117
16334
  import { WorkspaceUserProjectSelect as WorkspaceUserProjectSelect2 } from "@tutti-os/workspace-user-project/ui";
16118
- import { BareIconButton, ScrollArea } from "@tutti-os/ui-system/components";
16335
+ import {
16336
+ BareIconButton,
16337
+ Input as Input2,
16338
+ ScrollArea
16339
+ } from "@tutti-os/ui-system/components";
16119
16340
  import {
16120
16341
  CreateChatIcon,
16121
16342
  FolderIcon as FolderIcon2,
@@ -17266,9 +17487,9 @@ function AgentGoalBanner({
17266
17487
  // agent-gui/agentGuiNode/AgentComposer.tsx
17267
17488
  import {
17268
17489
  useCallback as useCallback9,
17269
- useEffect as useEffect13,
17490
+ useEffect as useEffect14,
17270
17491
  useLayoutEffect as useLayoutEffect3,
17271
- useMemo as useMemo8,
17492
+ useMemo as useMemo9,
17272
17493
  useRef as useRef11,
17273
17494
  useState as useState13
17274
17495
  } from "react";
@@ -17490,6 +17711,11 @@ var CLAUDE_CODE_FALLBACK_COMMANDS = [
17490
17711
  { name: REVIEW_COMMAND }
17491
17712
  ];
17492
17713
  var CURSOR_FALLBACK_COMMANDS = [];
17714
+ var OPENCODE_FALLBACK_COMMANDS = [
17715
+ { name: "compact" },
17716
+ { name: "goal" },
17717
+ { name: REVIEW_COMMAND }
17718
+ ];
17493
17719
  var CLAUDE_CODE_SLASH_PALETTE_COMMANDS = /* @__PURE__ */ new Set([
17494
17720
  "compact",
17495
17721
  "context",
@@ -17527,13 +17753,18 @@ var PROVIDER_SLASH_POLICY = {
17527
17753
  immediateCommands: /* @__PURE__ */ new Set(),
17528
17754
  reviewPickerCommands: /* @__PURE__ */ new Set(),
17529
17755
  fallbackCommands: CURSOR_FALLBACK_COMMANDS
17756
+ },
17757
+ opencode: {
17758
+ immediateCommands: /* @__PURE__ */ new Set(),
17759
+ reviewPickerCommands: /* @__PURE__ */ new Set([REVIEW_COMMAND]),
17760
+ fallbackCommands: OPENCODE_FALLBACK_COMMANDS
17530
17761
  }
17531
17762
  };
17532
17763
  function providerSlashPolicy(provider) {
17533
- return provider === "codex" || provider === "claude-code" || provider === "cursor" ? PROVIDER_SLASH_POLICY[provider] : void 0;
17764
+ return provider === "codex" || provider === "claude-code" || provider === "cursor" || provider === "opencode" ? PROVIDER_SLASH_POLICY[provider] : void 0;
17534
17765
  }
17535
17766
  function isACPProvider(provider) {
17536
- return provider === "codex" || provider === "claude-code" || provider === "cursor";
17767
+ return provider === "codex" || provider === "claude-code" || provider === "cursor" || provider === "opencode";
17537
17768
  }
17538
17769
  function resolveSlashCommandsForProvider({
17539
17770
  provider,
@@ -17541,6 +17772,7 @@ function resolveSlashCommandsForProvider({
17541
17772
  hasCompactableContext = true,
17542
17773
  compactSupported,
17543
17774
  planSupported = false,
17775
+ goalSupported = true,
17544
17776
  browserSupported = false,
17545
17777
  computerSupported = false
17546
17778
  }) {
@@ -17556,7 +17788,7 @@ function resolveSlashCommandsForProvider({
17556
17788
  );
17557
17789
  const commandEntries = mergedEntries.filter((entry) => {
17558
17790
  const commandName = normalizedCommandName(entry);
17559
- return commandName !== "plan" && isSlashPaletteCommandVisible(provider, commandName);
17791
+ return commandName !== "plan" && (goalSupported !== false || commandName !== "goal") && isSlashPaletteCommandVisible(provider, commandName);
17560
17792
  });
17561
17793
  const planEntries = planSupported && isACPProvider(provider) ? [PLAN_MODE_COMMAND] : [];
17562
17794
  const capabilityEntries = [];
@@ -17942,7 +18174,9 @@ function slashPaletteEntryIcon(entry) {
17942
18174
 
17943
18175
  // agent-gui/agentGuiNode/AgentQueuedPromptPanel.tsx
17944
18176
  import {
18177
+ useEffect as useEffect9,
17945
18178
  useLayoutEffect,
18179
+ useMemo as useMemo4,
17946
18180
  useRef as useRef7,
17947
18181
  useState as useState8
17948
18182
  } from "react";
@@ -17956,9 +18190,81 @@ import {
17956
18190
  import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
17957
18191
  var EMPTY_WORKSPACE_APP_ICONS = [];
17958
18192
  function queuedPromptImages(queuedPrompt) {
17959
- return agentPromptContentImageBlocks(
17960
- queuedPrompt.content
18193
+ return agentPromptContentImageBlocks(queuedPrompt.content);
18194
+ }
18195
+ function queuedPromptImageDataUrl(image) {
18196
+ const data = image.data?.trim() ?? "";
18197
+ const mimeType = image.mimeType.trim();
18198
+ if (!data || !mimeType) {
18199
+ return null;
18200
+ }
18201
+ return data.startsWith("data:") ? data : `data:${mimeType};base64,${data}`;
18202
+ }
18203
+ function queuedPromptImageKey(queuedPrompt, image, index) {
18204
+ return [
18205
+ queuedPrompt.id,
18206
+ index,
18207
+ image.attachmentId?.trim() ?? "",
18208
+ image.path?.trim() ?? "",
18209
+ image.name?.trim() ?? "",
18210
+ image.mimeType
18211
+ ].join(":");
18212
+ }
18213
+ function useQueuedPromptImageSources(input) {
18214
+ const runtime = useOptionalAgentActivityRuntime();
18215
+ const [sources, setSources] = useState8(() => /* @__PURE__ */ new Map());
18216
+ const workspaceId = input.workspaceId?.trim() ?? "";
18217
+ const agentSessionId = input.agentSessionId?.trim() ?? "";
18218
+ const missingImages = useMemo4(
18219
+ () => input.images.filter(({ image, key }) => {
18220
+ const attachmentId = image.attachmentId?.trim() ?? "";
18221
+ const path = image.path?.trim() ?? "";
18222
+ return !queuedPromptImageDataUrl(image) && !sources.has(key) && Boolean(attachmentId || path) && Boolean(workspaceId);
18223
+ }),
18224
+ [input.images, sources, workspaceId]
17961
18225
  );
18226
+ useEffect9(() => {
18227
+ if (!runtime?.readSessionAttachment && !runtime?.readPromptAsset || missingImages.length === 0) {
18228
+ return;
18229
+ }
18230
+ let canceled = false;
18231
+ for (const { image, key } of missingImages) {
18232
+ const attachmentId = image.attachmentId?.trim() ?? "";
18233
+ const path = image.path?.trim() ?? "";
18234
+ const readImage = attachmentId ? runtime.readSessionAttachment?.({
18235
+ workspaceId,
18236
+ agentSessionId,
18237
+ attachmentId
18238
+ }) : runtime.readPromptAsset?.({
18239
+ workspaceId,
18240
+ agentSessionId,
18241
+ mimeType: image.mimeType,
18242
+ name: image.name,
18243
+ path
18244
+ });
18245
+ if (!readImage) {
18246
+ continue;
18247
+ }
18248
+ void readImage.then((asset) => {
18249
+ if (canceled) {
18250
+ return;
18251
+ }
18252
+ setSources((current) => {
18253
+ if (current.has(key)) {
18254
+ return current;
18255
+ }
18256
+ const next = new Map(current);
18257
+ next.set(key, `data:${asset.mimeType};base64,${asset.data}`);
18258
+ return next;
18259
+ });
18260
+ }).catch(() => {
18261
+ });
18262
+ }
18263
+ return () => {
18264
+ canceled = true;
18265
+ };
18266
+ }, [agentSessionId, missingImages, runtime, workspaceId]);
18267
+ return sources;
17962
18268
  }
17963
18269
  function queuedPromptDisplayText(queuedPrompt) {
17964
18270
  const prompt = agentPromptContentDisplayText(queuedPrompt.content);
@@ -17981,7 +18287,9 @@ function AgentQueuedPromptPanel({
17981
18287
  onSendQueuedPromptNext,
17982
18288
  onRemoveQueuedPrompt,
17983
18289
  onEditQueuedPrompt,
18290
+ agentSessionId = null,
17984
18291
  onLinkClick,
18292
+ workspaceId = null,
17985
18293
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS
17986
18294
  }) {
17987
18295
  "use memo";
@@ -17991,6 +18299,20 @@ function AgentQueuedPromptPanel({
17991
18299
  const pointerHandledEditPromptIdRef = useRef7(null);
17992
18300
  const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState8(false);
17993
18301
  const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState8(280);
18302
+ const queuedPromptImageEntries = useMemo4(
18303
+ () => queuedPrompts.flatMap(
18304
+ (queuedPrompt) => queuedPromptImages(queuedPrompt).slice(0, 3).map((image, index) => ({
18305
+ image,
18306
+ key: queuedPromptImageKey(queuedPrompt, image, index)
18307
+ }))
18308
+ ),
18309
+ [queuedPrompts]
18310
+ );
18311
+ const queuedPromptImageSources = useQueuedPromptImageSources({
18312
+ agentSessionId,
18313
+ images: queuedPromptImageEntries,
18314
+ workspaceId
18315
+ });
17994
18316
  const singlePromptHasImages = queuedPrompts.length === 1 && queuedPromptImages(queuedPrompts[0]).length > 0;
17995
18317
  const canExpand = queuedPrompts.length > 1 || singlePromptHasImages || isSinglePromptOverflowing;
17996
18318
  const panelStyle = {
@@ -18141,7 +18463,15 @@ function AgentQueuedPromptPanel({
18141
18463
  }
18142
18464
  ) : null,
18143
18465
  images.length > 0 ? /* @__PURE__ */ jsx25("div", { className: AgentGUINode_styles_default.composerQueuedPromptImages, children: images.slice(0, 3).map((image, index) => {
18144
- const src = `data:${image.mimeType};base64,${image.data}`;
18466
+ const imageKey = queuedPromptImageKey(
18467
+ queuedPrompt,
18468
+ image,
18469
+ index
18470
+ );
18471
+ const src = queuedPromptImageSources.get(imageKey) ?? queuedPromptImageDataUrl(image);
18472
+ if (!src) {
18473
+ return null;
18474
+ }
18145
18475
  return /* @__PURE__ */ jsx25(
18146
18476
  ZoomableImage,
18147
18477
  {
@@ -18151,7 +18481,7 @@ function AgentQueuedPromptPanel({
18151
18481
  src,
18152
18482
  wrapElement: "span"
18153
18483
  },
18154
- `${queuedPrompt.id}:image:${index}`
18484
+ imageKey
18155
18485
  );
18156
18486
  }) }) : null
18157
18487
  ] }) }),
@@ -18228,8 +18558,8 @@ function AgentQueuedPromptPanel({
18228
18558
  import {
18229
18559
  Fragment as Fragment4,
18230
18560
  cloneElement,
18231
- useEffect as useEffect9,
18232
- useMemo as useMemo4,
18561
+ useEffect as useEffect10,
18562
+ useMemo as useMemo5,
18233
18563
  useState as useState9
18234
18564
  } from "react";
18235
18565
  import { ChevronDown, ZapIcon as ZapIcon2 } from "lucide-react";
@@ -18731,11 +19061,11 @@ function AgentProjectDropdown({
18731
19061
  }) {
18732
19062
  "use memo";
18733
19063
  const agentHostApi = useAgentHostApi();
18734
- const resolvedLabels = useMemo4(
19064
+ const resolvedLabels = useMemo5(
18735
19065
  () => resolveWorkspaceUserProjectSelectLabels(i18n, labels),
18736
19066
  [i18n, labels]
18737
19067
  );
18738
- const userProjectApi = useMemo4(
19068
+ const userProjectApi = useMemo5(
18739
19069
  () => !previewMode && agentHostApi.userProjects ? {
18740
19070
  ...agentHostApi.userProjects,
18741
19071
  selectDirectory: selectProjectDirectory ?? agentHostApi.workspace.selectDirectory
@@ -18967,7 +19297,7 @@ function AgentProjectMissingStatusProbe({
18967
19297
  "use memo";
18968
19298
  const agentHostApi = useAgentHostApi();
18969
19299
  const selectedPath = composerSettings.selectedProjectPath?.trim() ?? "";
18970
- useEffect9(() => {
19300
+ useEffect10(() => {
18971
19301
  let canceled = false;
18972
19302
  const userProjects = agentHostApi.userProjects;
18973
19303
  if (!userProjects || !composerSettings.projectLocked || !selectedPath) {
@@ -19338,9 +19668,9 @@ function ComposerModelOptionTooltip({
19338
19668
  import {
19339
19669
  forwardRef as forwardRef3,
19340
19670
  useCallback as useCallback6,
19341
- useEffect as useEffect10,
19671
+ useEffect as useEffect11,
19342
19672
  useImperativeHandle as useImperativeHandle2,
19343
- useMemo as useMemo5,
19673
+ useMemo as useMemo6,
19344
19674
  useRef as useRef8,
19345
19675
  useState as useState10
19346
19676
  } from "react";
@@ -19457,7 +19787,7 @@ function hasWorkspaceFileDropData(dataTransfer) {
19457
19787
  WORKSPACE_FILE_DROP_MIME_TYPE
19458
19788
  );
19459
19789
  }
19460
- function readWorkspaceFileDropEntries(dataTransfer, options = {}) {
19790
+ function readWorkspaceFileDropEntries(dataTransfer) {
19461
19791
  if (!hasWorkspaceFileDropData(dataTransfer)) {
19462
19792
  return [];
19463
19793
  }
@@ -19482,16 +19812,7 @@ function readWorkspaceFileDropEntries(dataTransfer, options = {}) {
19482
19812
  })
19483
19813
  );
19484
19814
  }
19485
- if (options.includeLegacyPaths === false || !Array.isArray(parsed.paths)) {
19486
- return [];
19487
- }
19488
- return normalizeWorkspaceFileDropEntries(
19489
- parsed.paths.filter((value) => typeof value === "string").map((path) => ({
19490
- path,
19491
- name: basenameWorkspacePath(path),
19492
- kind: "unknown"
19493
- }))
19494
- );
19815
+ return [];
19495
19816
  } catch {
19496
19817
  return [];
19497
19818
  }
@@ -20029,7 +20350,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20029
20350
  scrollEditorSelectionIntoView(currentEditor);
20030
20351
  });
20031
20352
  };
20032
- const extensions = useMemo5(
20353
+ const extensions = useMemo6(
20033
20354
  () => [
20034
20355
  ...createAgentRichTextInputExtensions(
20035
20356
  {
@@ -20287,9 +20608,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20287
20608
  if (!hasWorkspaceFileDropData(dataTransfer)) {
20288
20609
  return false;
20289
20610
  }
20290
- const entries = readWorkspaceFileDropEntries(dataTransfer, {
20291
- includeLegacyPaths: false
20292
- });
20611
+ const entries = readWorkspaceFileDropEntries(dataTransfer);
20293
20612
  if (entries.length === 0) {
20294
20613
  return false;
20295
20614
  }
@@ -20343,9 +20662,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20343
20662
  if (!currentEditor || currentEditor.isDestroyed) {
20344
20663
  return true;
20345
20664
  }
20346
- const entries = readWorkspaceFileDropEntries(dataTransfer, {
20347
- includeLegacyPaths: false
20348
- });
20665
+ const entries = readWorkspaceFileDropEntries(dataTransfer);
20349
20666
  if (entries.length === 0) {
20350
20667
  return true;
20351
20668
  }
@@ -20426,10 +20743,10 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20426
20743
  }
20427
20744
  onSubmitRef.current();
20428
20745
  };
20429
- useEffect10(() => {
20746
+ useEffect11(() => {
20430
20747
  editorRef.current = editor;
20431
20748
  }, [editor]);
20432
- useEffect10(
20749
+ useEffect11(
20433
20750
  () => () => {
20434
20751
  if (scrollFrameRef.current !== null && typeof window.cancelAnimationFrame === "function") {
20435
20752
  window.cancelAnimationFrame(scrollFrameRef.current);
@@ -20437,7 +20754,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20437
20754
  },
20438
20755
  []
20439
20756
  );
20440
- useEffect10(() => {
20757
+ useEffect11(() => {
20441
20758
  if (!contextMenu) {
20442
20759
  return;
20443
20760
  }
@@ -20543,7 +20860,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20543
20860
  }),
20544
20861
  []
20545
20862
  );
20546
- useEffect10(() => {
20863
+ useEffect11(() => {
20547
20864
  if (!editor) {
20548
20865
  return;
20549
20866
  }
@@ -20554,7 +20871,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20554
20871
  editor.state.tr.setMeta("agentRichTextPlaceholder", placeholder)
20555
20872
  );
20556
20873
  }, [disabled, editor, placeholder]);
20557
- useEffect10(() => {
20874
+ useEffect11(() => {
20558
20875
  if (!editor || editor.isDestroyed) {
20559
20876
  return;
20560
20877
  }
@@ -20796,7 +21113,7 @@ function AgentSlashStatusPanel({
20796
21113
  }
20797
21114
 
20798
21115
  // agent-gui/agentGuiNode/AgentReviewPickerPanel.tsx
20799
- import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef9, useState as useState11 } from "react";
21116
+ import { useCallback as useCallback7, useEffect as useEffect12, useMemo as useMemo7, useRef as useRef9, useState as useState11 } from "react";
20800
21117
  import { menuItemClassName } from "@tutti-os/ui-system";
20801
21118
 
20802
21119
  // agent-gui/agentGuiNode/AgentReviewBranchController.ts
@@ -20925,7 +21242,7 @@ function AgentReviewPickerPanel({
20925
21242
  currentBranch: null,
20926
21243
  error: null
20927
21244
  });
20928
- useEffect11(() => {
21245
+ useEffect12(() => {
20929
21246
  const controller = new AgentReviewBranchController();
20930
21247
  reviewBranchControllerRef.current = controller;
20931
21248
  const unsubscribe = controller.subscribe(setBranchState);
@@ -20935,7 +21252,7 @@ function AgentReviewPickerPanel({
20935
21252
  reviewBranchControllerRef.current = null;
20936
21253
  };
20937
21254
  }, []);
20938
- useEffect11(() => {
21255
+ useEffect12(() => {
20939
21256
  const controller = reviewBranchControllerRef.current;
20940
21257
  if (!controller) {
20941
21258
  return;
@@ -20945,7 +21262,7 @@ function AgentReviewPickerPanel({
20945
21262
  controller.ensureLoaded();
20946
21263
  }
20947
21264
  }, [onRequestGitBranches, stage]);
20948
- useEffect11(() => {
21265
+ useEffect12(() => {
20949
21266
  searchInputRef.current?.focus();
20950
21267
  }, [stage]);
20951
21268
  const submit = useCallback7(
@@ -20966,7 +21283,7 @@ function AgentReviewPickerPanel({
20966
21283
  }, []);
20967
21284
  const trimmedQuery = query.trim();
20968
21285
  const normalizedQuery = trimmedQuery.toLowerCase();
20969
- const entries = useMemo6(() => {
21286
+ const entries = useMemo7(() => {
20970
21287
  if (stage === "root") {
20971
21288
  const options = [
20972
21289
  {
@@ -21035,7 +21352,7 @@ function AgentReviewPickerPanel({
21035
21352
  goToStage
21036
21353
  ]);
21037
21354
  const safeHighlightedIndex = entries.length === 0 ? -1 : Math.min(highlightedIndex, entries.length - 1);
21038
- useEffect11(() => {
21355
+ useEffect12(() => {
21039
21356
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
21040
21357
  }, [safeHighlightedIndex]);
21041
21358
  const searchPlaceholder = stage === "base" ? labels.branchPlaceholder : stage === "commit" ? labels.commitPlaceholder : stage === "custom" ? labels.customPlaceholder : labels.searchPlaceholder;
@@ -21158,9 +21475,9 @@ function AgentReviewPickerPanel({
21158
21475
  import {
21159
21476
  forwardRef as forwardRef4,
21160
21477
  useCallback as useCallback8,
21161
- useEffect as useEffect12,
21478
+ useEffect as useEffect13,
21162
21479
  useLayoutEffect as useLayoutEffect2,
21163
- useMemo as useMemo7,
21480
+ useMemo as useMemo8,
21164
21481
  useRef as useRef10,
21165
21482
  useState as useState12
21166
21483
  } from "react";
@@ -21326,7 +21643,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
21326
21643
  },
21327
21644
  [forwardedRef, surfaceRef]
21328
21645
  );
21329
- useEffect12(() => {
21646
+ useEffect13(() => {
21330
21647
  if (!open || !onDismiss) {
21331
21648
  return;
21332
21649
  }
@@ -21369,7 +21686,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
21369
21686
  window.removeEventListener("blur", onDismiss);
21370
21687
  };
21371
21688
  }, [anchorRef, dismissBoundaryRef, onDismiss, open]);
21372
- const style = useMemo7(() => {
21689
+ const style = useMemo8(() => {
21373
21690
  const baseStyle = {
21374
21691
  position: "fixed",
21375
21692
  left: `${frame?.left ?? 0}px`,
@@ -21557,7 +21874,7 @@ function AgentUsageChip({
21557
21874
  closeUsagePopover
21558
21875
  ]
21559
21876
  );
21560
- useEffect13(
21877
+ useEffect14(
21561
21878
  () => () => {
21562
21879
  clearUsagePopoverHoverTimer();
21563
21880
  clearUsagePopoverCloseTimer();
@@ -21790,7 +22107,7 @@ function AgentComposerHandoffIcon({
21790
22107
  }) {
21791
22108
  const [isLottieReady, setIsLottieReady] = useState13(false);
21792
22109
  const shouldLoadAnimation = !disabled && isPlaying;
21793
- useEffect13(() => {
22110
+ useEffect14(() => {
21794
22111
  if (!shouldLoadAnimation) {
21795
22112
  return;
21796
22113
  }
@@ -21884,6 +22201,8 @@ function AgentComposer({
21884
22201
  previewMode = false,
21885
22202
  workspaceReferencePickerOpen = false,
21886
22203
  promptImagesSupported = true,
22204
+ canGoalControl = true,
22205
+ canUploadAttachment = true,
21887
22206
  composerFocusRequestSequence = null,
21888
22207
  layoutMode = "dock",
21889
22208
  providerSelectLabel = "",
@@ -21914,7 +22233,7 @@ function AgentComposer({
21914
22233
  }) {
21915
22234
  "use memo";
21916
22235
  const draftPrompt = draftContent.prompt;
21917
- const goalDraftObjective = goalDraftObjectiveFromPrompt(draftPrompt);
22236
+ const goalDraftObjective = canGoalControl ? goalDraftObjectiveFromPrompt(draftPrompt) : null;
21918
22237
  const isGoalModeActive = goalDraftObjective !== null;
21919
22238
  const draftImages = draftContent.images;
21920
22239
  const draftFiles = draftContent.files ?? [];
@@ -21923,7 +22242,7 @@ function AgentComposer({
21923
22242
  const agentHostApi = useOptionalAgentHostApi();
21924
22243
  const getReferenceForFile = agentHostApi?.workspace.getReferenceForFile;
21925
22244
  const promptFileUploadSupported = Boolean(
21926
- agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.file ?? true)
22245
+ canUploadAttachment && agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.file ?? true)
21927
22246
  );
21928
22247
  const promptFilesSupported = Boolean(
21929
22248
  resolveDroppedFileReferences && promptFileUploadSupported
@@ -21990,19 +22309,21 @@ function AgentComposer({
21990
22309
  const promptBeforeSelection = editorHandleRef.current?.getPromptTextBeforeSelection() ?? "";
21991
22310
  const skillQueryDraft = promptBeforeSelection || paletteDraftPrompt;
21992
22311
  const skillQueryMatch = getAgentComposerTriggerQueryMatch(skillQueryDraft);
21993
- const resolvedSlashCommands = useMemo8(
22312
+ const resolvedSlashCommands = useMemo9(
21994
22313
  () => resolveSlashCommandsForProvider({
21995
22314
  provider,
21996
22315
  commands: availableCommands,
21997
22316
  hasCompactableContext,
21998
22317
  compactSupported,
21999
22318
  planSupported: composerSettings.supportsPlanMode,
22319
+ goalSupported: canGoalControl,
22000
22320
  browserSupported: Boolean(composerSettings.supportsBrowser),
22001
22321
  computerSupported: Boolean(composerSettings.supportsComputerUse)
22002
22322
  }),
22003
22323
  [
22004
22324
  availableCommands,
22005
22325
  compactSupported,
22326
+ canGoalControl,
22006
22327
  composerSettings.supportsPlanMode,
22007
22328
  composerSettings.supportsBrowser,
22008
22329
  composerSettings.supportsComputerUse,
@@ -22010,11 +22331,11 @@ function AgentComposer({
22010
22331
  provider
22011
22332
  ]
22012
22333
  );
22013
- const filteredCommands = useMemo8(
22334
+ const filteredCommands = useMemo9(
22014
22335
  () => slashQuery === null ? [] : filterSlashCommands(resolvedSlashCommands, slashQuery),
22015
22336
  [resolvedSlashCommands, slashQuery]
22016
22337
  );
22017
- const filteredSkills = useMemo8(
22338
+ const filteredSkills = useMemo9(
22018
22339
  () => skillQueryMatch === null ? [] : filterProviderSkillsForTrigger({
22019
22340
  skills: availableSkills,
22020
22341
  query: skillQueryMatch.query,
@@ -22022,7 +22343,7 @@ function AgentComposer({
22022
22343
  }),
22023
22344
  [availableSkills, skillQueryMatch]
22024
22345
  );
22025
- const availableCapabilities = useMemo8(() => {
22346
+ const availableCapabilities = useMemo9(() => {
22026
22347
  const entries = [];
22027
22348
  if (composerSettings.supportsBrowser) {
22028
22349
  entries.push({
@@ -22047,7 +22368,7 @@ function AgentComposer({
22047
22368
  labels.browserUseCapabilityLabel,
22048
22369
  labels.computerUseCapabilityLabel
22049
22370
  ]);
22050
- const slashPaletteEntries = useMemo8(() => {
22371
+ const slashPaletteEntries = useMemo9(() => {
22051
22372
  const commandEntries = filteredCommands.flatMap((command) => {
22052
22373
  if (isSlashCommandCapability(command)) {
22053
22374
  const browserConnectionMode = capabilityMenuState?.browserUse?.connectionMode ?? null;
@@ -22144,10 +22465,10 @@ function AgentComposer({
22144
22465
  slashPaletteEntries.length
22145
22466
  );
22146
22467
  const [mentionPaletteFrame, setMentionPaletteFrame] = useState13(null);
22147
- useEffect13(() => {
22468
+ useEffect14(() => {
22148
22469
  setHighlightedIndex(0);
22149
22470
  }, [skillQueryMatch?.prefix, skillQueryMatch?.query, slashQuery]);
22150
- useEffect13(() => {
22471
+ useEffect14(() => {
22151
22472
  const preferredKey = shouldResetMentionHighlightToFilter && mentionSearchState.mode === "browse" ? `category:${mentionSearchState.filter}` : null;
22152
22473
  if (shouldResetMentionHighlightToFilter) {
22153
22474
  const nextKey = repairMentionPaletteHighlight({
@@ -22179,7 +22500,7 @@ function AgentComposer({
22179
22500
  mentionSearchState,
22180
22501
  shouldResetMentionHighlightToFilter
22181
22502
  ]);
22182
- useEffect13(() => {
22503
+ useEffect14(() => {
22183
22504
  const controller = new AgentMentionSearchController({
22184
22505
  contextMentionProviders
22185
22506
  });
@@ -22191,7 +22512,7 @@ function AgentComposer({
22191
22512
  mentionControllerRef.current = null;
22192
22513
  };
22193
22514
  }, [contextMentionProviders]);
22194
- useEffect13(() => {
22515
+ useEffect14(() => {
22195
22516
  const isExternalDraftReplacement = draftPromptRef.current !== draftPrompt;
22196
22517
  draftPromptRef.current = draftPrompt;
22197
22518
  setPaletteDraftPrompt(goalDraftObjective ?? draftPrompt);
@@ -22203,16 +22524,16 @@ function AgentComposer({
22203
22524
  });
22204
22525
  }
22205
22526
  }, [draftPrompt, goalDraftObjective]);
22206
- useEffect13(() => {
22527
+ useEffect14(() => {
22207
22528
  draftImagesRef.current = draftImages;
22208
22529
  }, [draftImages]);
22209
- useEffect13(() => {
22530
+ useEffect14(() => {
22210
22531
  draftFilesRef.current = draftFiles;
22211
22532
  }, [draftFiles]);
22212
- useEffect13(() => {
22533
+ useEffect14(() => {
22213
22534
  draftLargeTextsRef.current = draftLargeTexts;
22214
22535
  }, [draftLargeTexts]);
22215
- useEffect13(() => {
22536
+ useEffect14(() => {
22216
22537
  if (previousSlashStatusAgentSessionIdRef.current === slashStatusAgentSessionId) {
22217
22538
  return;
22218
22539
  }
@@ -22252,7 +22573,7 @@ function AgentComposer({
22252
22573
  },
22253
22574
  [clearSlashCommandDraft, onSubmit]
22254
22575
  );
22255
- const reviewBranchLoader = useMemo8(() => {
22576
+ const reviewBranchLoader = useMemo9(() => {
22256
22577
  if (!onRequestGitBranches) {
22257
22578
  return null;
22258
22579
  }
@@ -22444,7 +22765,7 @@ function AgentComposer({
22444
22765
  if (!agentComposerDraftHasContent(nextDraftContent)) {
22445
22766
  return;
22446
22767
  }
22447
- if (currentDraftImages.length > 0 && !promptImagesSupported) {
22768
+ if (currentDraftImages.length > 0 && (!canUploadAttachment || !promptImagesSupported)) {
22448
22769
  onPromptImagesUnsupported?.();
22449
22770
  return;
22450
22771
  }
@@ -22726,7 +23047,7 @@ function AgentComposer({
22726
23047
  const handlePaletteKeyDown = useStableEventCallback(
22727
23048
  (event) => handleFileMentionKeyDown(event) || handleSlashPaletteKeyDown(event) || handleSlashCommandMenuKeyDown(event) || handlePlanModeToggleKeyDown(event)
22728
23049
  );
22729
- useEffect13(() => {
23050
+ useEffect14(() => {
22730
23051
  if (!showPalette || workspaceReferencePickerOpen) {
22731
23052
  return;
22732
23053
  }
@@ -22792,12 +23113,12 @@ function AgentComposer({
22792
23113
  },
22793
23114
  [onLinkAction, workspacePath]
22794
23115
  );
22795
- useEffect13(() => {
23116
+ useEffect14(() => {
22796
23117
  if (!showFileMentionPalette && shouldCenterMentionHighlight) {
22797
23118
  setShouldCenterMentionHighlight(false);
22798
23119
  }
22799
23120
  }, [shouldCenterMentionHighlight, showFileMentionPalette]);
22800
- useEffect13(() => {
23121
+ useEffect14(() => {
22801
23122
  if (!showFileMentionPalette) {
22802
23123
  return;
22803
23124
  }
@@ -22834,7 +23155,7 @@ function AgentComposer({
22834
23155
  onDraftContentChange({ ...draftContent, prompt: nextGoalPrompt });
22835
23156
  return;
22836
23157
  }
22837
- const nextGoalObjective = goalDraftObjectiveFromPrompt(nextDraft);
23158
+ const nextGoalObjective = canGoalControl ? goalDraftObjectiveFromPrompt(nextDraft) : null;
22838
23159
  if (nextGoalObjective !== null) {
22839
23160
  const nextGoalPrompt = buildGoalModePrompt(nextGoalObjective);
22840
23161
  draftPromptRef.current = nextGoalPrompt;
@@ -22868,7 +23189,7 @@ function AgentComposer({
22868
23189
  if (images.length === 0) {
22869
23190
  return;
22870
23191
  }
22871
- if (!promptImagesSupported) {
23192
+ if (!canUploadAttachment || !promptImagesSupported) {
22872
23193
  onPromptImagesUnsupported?.();
22873
23194
  return;
22874
23195
  }
@@ -22880,7 +23201,7 @@ function AgentComposer({
22880
23201
  if (remainingSlots === 0) {
22881
23202
  return;
22882
23203
  }
22883
- const uploadPromptContent = agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.image ?? true) ? agentActivityRuntime.uploadPromptContent : void 0;
23204
+ const uploadPromptContent = canUploadAttachment && agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.image ?? true) ? agentActivityRuntime.uploadPromptContent : void 0;
22884
23205
  const nextImages = images.slice(0, remainingSlots).map((image) => ({
22885
23206
  id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,
22886
23207
  name: image.name,
@@ -22960,6 +23281,7 @@ function AgentComposer({
22960
23281
  },
22961
23282
  [
22962
23283
  agentActivityRuntime,
23284
+ canUploadAttachment,
22963
23285
  onDraftContentChange,
22964
23286
  onPromptImagesUnsupported,
22965
23287
  promptImagesSupported,
@@ -23044,7 +23366,7 @@ ${item.text}` : item.text;
23044
23366
  if (!normalizedText.trim()) {
23045
23367
  return;
23046
23368
  }
23047
- const uploadPromptContent = agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.file ?? true) ? agentActivityRuntime.uploadPromptContent : void 0;
23369
+ const uploadPromptContent = canUploadAttachment && agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.file ?? true) ? agentActivityRuntime.uploadPromptContent : void 0;
23048
23370
  if (!uploadPromptContent) {
23049
23371
  const currentPrompt = draftPromptRef.current;
23050
23372
  const nextPrompt = currentPrompt.trim() ? `${currentPrompt}
@@ -23129,7 +23451,12 @@ ${normalizedText}` : normalizedText;
23129
23451
  });
23130
23452
  });
23131
23453
  },
23132
- [agentActivityRuntime, onDraftContentChange, workspaceId]
23454
+ [
23455
+ agentActivityRuntime,
23456
+ canUploadAttachment,
23457
+ onDraftContentChange,
23458
+ workspaceId
23459
+ ]
23133
23460
  );
23134
23461
  const applyReferencePickResult = useCallback9(
23135
23462
  async (result) => {
@@ -23284,7 +23611,7 @@ ${normalizedText}` : normalizedText;
23284
23611
  window.removeEventListener("scroll", syncMentionPaletteFrame, true);
23285
23612
  };
23286
23613
  }, [showFileMentionPalette, syncMentionPaletteFrame]);
23287
- const mentionPaletteStyle = useMemo8(
23614
+ const mentionPaletteStyle = useMemo9(
23288
23615
  () => ({
23289
23616
  position: "fixed",
23290
23617
  left: `${mentionPaletteFrame?.left ?? 0}px`,
@@ -23301,11 +23628,11 @@ ${normalizedText}` : normalizedText;
23301
23628
  const mentionPaletteHeightPx = mentionPaletteFrame?.height ?? MENTION_PALETTE_MIN_HEIGHT_PX;
23302
23629
  const isHeroLayout = layoutMode === "hero";
23303
23630
  const composerClassName = isHeroLayout ? AgentGUINode_styles_default.composerHero : AgentGUINode_styles_default.composer;
23304
- const providerSwitchTargets = useMemo8(
23631
+ const providerSwitchTargets = useMemo9(
23305
23632
  () => providerTargets.filter(Boolean),
23306
23633
  [providerTargets]
23307
23634
  );
23308
- const enabledProviderSwitchTargets = useMemo8(
23635
+ const enabledProviderSwitchTargets = useMemo9(
23309
23636
  () => providerSwitchTargets.filter((target) => target.disabled !== true),
23310
23637
  [providerSwitchTargets]
23311
23638
  );
@@ -23316,7 +23643,7 @@ ${normalizedText}` : normalizedText;
23316
23643
  const providerMenuTargets = selectedProviderSwitchTarget && !enabledProviderSwitchTargets.some(
23317
23644
  (target) => target.targetId === selectedProviderSwitchTarget.targetId
23318
23645
  ) ? [selectedProviderSwitchTarget, ...enabledProviderSwitchTargets] : enabledProviderSwitchTargets;
23319
- const enabledHandoffProviderTargets = useMemo8(
23646
+ const enabledHandoffProviderTargets = useMemo9(
23320
23647
  () => (handoffProviderTargets ?? providerMenuTargets).filter(
23321
23648
  (target) => target.disabled !== true
23322
23649
  ),
@@ -23367,7 +23694,7 @@ ${normalizedText}` : normalizedText;
23367
23694
  );
23368
23695
  const [fileDropOverlayHost, setFileDropOverlayHost] = useState13(null);
23369
23696
  const [fileDropOverlayActive, setFileDropOverlayActive] = useState13(false);
23370
- useEffect13(() => {
23697
+ useEffect14(() => {
23371
23698
  const composer = composerRef.current;
23372
23699
  const dropTarget = composer?.closest("#agent-gui-detail") ?? composer;
23373
23700
  if (!dropTarget) {
@@ -23514,7 +23841,7 @@ ${normalizedText}` : normalizedText;
23514
23841
  promptImagesSupported,
23515
23842
  scheduleComposerFocus
23516
23843
  ]);
23517
- useEffect13(() => {
23844
+ useEffect14(() => {
23518
23845
  if (!isActive) {
23519
23846
  wasActiveRef.current = false;
23520
23847
  return;
@@ -23524,7 +23851,7 @@ ${normalizedText}` : normalizedText;
23524
23851
  }
23525
23852
  wasActiveRef.current = true;
23526
23853
  }, [isActive, scheduleComposerFocus]);
23527
- useEffect13(() => {
23854
+ useEffect14(() => {
23528
23855
  if (composerFocusRequestSequence === null || composerFocusRequestSequence === lastComposerFocusRequestRef.current) {
23529
23856
  return;
23530
23857
  }
@@ -23706,11 +24033,11 @@ ${normalizedText}` : normalizedText;
23706
24033
  isHeroLayout,
23707
24034
  paletteDraftPrompt
23708
24035
  ]);
23709
- const inputShellStyle = useMemo8(
24036
+ const inputShellStyle = useMemo9(
23710
24037
  () => showFileMentionPalette || showFloatingCommandMenu ? { zIndex: composerPaletteZIndex } : void 0,
23711
24038
  [showFileMentionPalette, showFloatingCommandMenu]
23712
24039
  );
23713
- const promptInputAreaStyle = useMemo8(
24040
+ const promptInputAreaStyle = useMemo9(
23714
24041
  () => isHeroLayout ? void 0 : {
23715
24042
  "--agent-gui-composer-attachment-height": `${dockComposerAttachmentHeight}px`,
23716
24043
  "--agent-gui-composer-input-height": `${dockComposerInputHeight}px`,
@@ -23750,7 +24077,7 @@ ${normalizedText}` : normalizedText;
23750
24077
  const effectivePlaceholder = disabledReasonText || placeholder;
23751
24078
  const visibleDraftFiles = draftFiles;
23752
24079
  const visibleDraftLargeTexts = draftLargeTexts;
23753
- useEffect13(() => {
24080
+ useEffect14(() => {
23754
24081
  if (previousSelectedProjectPathRef.current === selectedProjectPath) {
23755
24082
  return;
23756
24083
  }
@@ -23766,7 +24093,7 @@ ${normalizedText}` : normalizedText;
23766
24093
  sessionCwd: selectedProjectPath || null
23767
24094
  });
23768
24095
  }, [currentUserId, fileMentionSuggestion, selectedProjectPath, workspaceId]);
23769
- useEffect13(() => {
24096
+ useEffect14(() => {
23770
24097
  setDismissedPromptRequestId(null);
23771
24098
  }, [activePromptRequestId]);
23772
24099
  const submitInteractivePromptAndDismiss = useCallback9(
@@ -23940,7 +24267,9 @@ ${normalizedText}` : normalizedText;
23940
24267
  onSendQueuedPromptNext,
23941
24268
  onRemoveQueuedPrompt,
23942
24269
  onEditQueuedPrompt,
24270
+ agentSessionId: slashStatusAgentSessionId,
23943
24271
  onLinkClick: handleLinkClick,
24272
+ workspaceId,
23944
24273
  workspaceAppIcons
23945
24274
  }
23946
24275
  )
@@ -24176,7 +24505,7 @@ ${normalizedText}` : normalizedText;
24176
24505
  onFileMentionSuggestionChange: handleFileMentionSuggestionChange,
24177
24506
  onFileMentionSuggestionKeyDown: handleFileMentionKeyDown,
24178
24507
  onLinkClick: handleLinkClick,
24179
- promptImagesSupported,
24508
+ promptImagesSupported: canUploadAttachment && promptImagesSupported,
24180
24509
  onPromptImagesUnsupported,
24181
24510
  onPasteImages: handlePastedImages,
24182
24511
  onPasteLargeText: handlePastedLargeText,
@@ -24630,7 +24959,7 @@ ${normalizedText}` : normalizedText;
24630
24959
  ] })
24631
24960
  }
24632
24961
  ) : null,
24633
- isGoalModeActive ? /* @__PURE__ */ jsx31(
24962
+ canGoalControl && isGoalModeActive ? /* @__PURE__ */ jsx31(
24634
24963
  "button",
24635
24964
  {
24636
24965
  type: "button",
@@ -25125,7 +25454,7 @@ function groupConversations(conversations, labels, userProjects = [], options =
25125
25454
  const normalizeProjectPath = (path) => normalizeConversationProjectPathCached(path, normalizedProjectPathByPath);
25126
25455
  userProjects.forEach((project, projectOrder) => {
25127
25456
  const normalizedPath = normalizeProjectPath(project.path);
25128
- const sectionId = `project:${normalizedPath}`;
25457
+ const sectionId = conversationProjectSectionId(project, normalizedPath);
25129
25458
  if (projectGroups.has(sectionId)) {
25130
25459
  return;
25131
25460
  }
@@ -25175,7 +25504,10 @@ function groupConversations(conversations, labels, userProjects = [], options =
25175
25504
  continue;
25176
25505
  }
25177
25506
  const normalizedPath = normalizeProjectPath(conversation.project.path);
25178
- const sectionId = `project:${normalizedPath}`;
25507
+ const sectionId = conversationProjectSectionId(
25508
+ conversation.project,
25509
+ normalizedPath
25510
+ );
25179
25511
  const existing = projectGroups.get(sectionId);
25180
25512
  if (existing) {
25181
25513
  existing.items.push(conversation);
@@ -25208,6 +25540,17 @@ function groupConversations(conversations, labels, userProjects = [], options =
25208
25540
  );
25209
25541
  return groups;
25210
25542
  }
25543
+ function filterConversationSectionsBySearchMatches(sections, matchingConversations) {
25544
+ const matchingConversationIds = new Set(
25545
+ matchingConversations.map((conversation) => conversation.id)
25546
+ );
25547
+ return sections.map((section) => ({
25548
+ ...section,
25549
+ items: section.items.filter(
25550
+ (item) => matchingConversationIds.has(item.id)
25551
+ )
25552
+ })).filter((section) => section.items.length > 0);
25553
+ }
25211
25554
  function resolveConversationProjectUpdatedAtUnixMs(project) {
25212
25555
  if (!project) {
25213
25556
  return 0;
@@ -25226,6 +25569,9 @@ function normalizeConversationProjectPathCached(path, normalizedPathByPath) {
25226
25569
  normalizedPathByPath.set(path, normalized);
25227
25570
  return normalized;
25228
25571
  }
25572
+ function conversationProjectSectionId(project, normalizedPath) {
25573
+ return project.sectionKey?.trim() || `project:${normalizedPath}`;
25574
+ }
25229
25575
  function conversationMetaKind(conversation) {
25230
25576
  if (conversation.status === "working") {
25231
25577
  return "loading";
@@ -25408,12 +25754,13 @@ function resolveAgentGUIHeroIconUrl(provider) {
25408
25754
  const normalizedProvider = normalizeManagedAgentProvider(provider);
25409
25755
  return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
25410
25756
  }
25757
+ var HERO_USES_PROVIDER_RAIL_ICON = /* @__PURE__ */ new Set(["cursor", "opencode"]);
25411
25758
  function agentGUIProviderIconPresentation(provider, iconUrl) {
25412
25759
  const normalizedProvider = normalizeManagedAgentProvider(provider);
25413
25760
  const providerRailIconUrl = MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] ?? null;
25414
25761
  return {
25415
25762
  provider: normalizedProvider,
25416
- iconUrl: (normalizedProvider === "cursor" ? providerRailIconUrl : null) || iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
25763
+ iconUrl: (HERO_USES_PROVIDER_RAIL_ICON.has(normalizedProvider) ? providerRailIconUrl : null) || iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
25417
25764
  };
25418
25765
  }
25419
25766
  function agentGUIProviderRailIconPresentation(provider, iconUrl) {
@@ -25421,7 +25768,7 @@ function agentGUIProviderRailIconPresentation(provider, iconUrl) {
25421
25768
  const providerRailIconUrl = MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] ?? null;
25422
25769
  return {
25423
25770
  provider: normalizedProvider,
25424
- iconUrl: (normalizedProvider === "cursor" ? providerRailIconUrl : null) || iconUrl?.trim() || providerRailIconUrl || resolveAgentGUIHeroIconUrl(normalizedProvider)
25771
+ iconUrl: (HERO_USES_PROVIDER_RAIL_ICON.has(normalizedProvider) ? providerRailIconUrl : null) || iconUrl?.trim() || providerRailIconUrl || resolveAgentGUIHeroIconUrl(normalizedProvider)
25425
25772
  };
25426
25773
  }
25427
25774
  function shouldEmphasizeEmptyHeroProvider(label) {
@@ -25437,7 +25784,7 @@ function agentGuiPerfNowMs() {
25437
25784
  }
25438
25785
  function useDelayedBoolean(value, delayMs) {
25439
25786
  const [delayedValue, setDelayedValue] = useState14(false);
25440
- useEffect14(() => {
25787
+ useEffect15(() => {
25441
25788
  if (!value) {
25442
25789
  setDelayedValue(false);
25443
25790
  return void 0;
@@ -25663,6 +26010,7 @@ function AgentGUINodeView({
25663
26010
  renderSidebarFooter,
25664
26011
  renderProviderRailEmpty,
25665
26012
  renderProviderUnavailableState,
26013
+ renderProviderReadinessGateState,
25666
26014
  providerRailAllPresentation,
25667
26015
  onLinkAction,
25668
26016
  onHandoffConversation,
@@ -25727,7 +26075,7 @@ function AgentGUINodeView({
25727
26075
  newConversationRequestSequence
25728
26076
  );
25729
26077
  const workspaceReferencePickerResolverRef = useRef12(null);
25730
- const emptyReferencePickResult = useMemo9(
26078
+ const emptyReferencePickResult = useMemo10(
25731
26079
  () => ({ files: [], mentionItems: [] }),
25732
26080
  []
25733
26081
  );
@@ -25829,7 +26177,7 @@ function AgentGUINodeView({
25829
26177
  },
25830
26178
  [hostLocalFileSourceId, settleReferencePicker]
25831
26179
  );
25832
- const openclawGateway = useMemo9(
26180
+ const openclawGateway = useMemo10(
25833
26181
  () => viewModel.openclawGateway ?? (viewModel.data.provider === "openclaw" ? { status: "starting", error: null } : null),
25834
26182
  [viewModel.data.provider, viewModel.openclawGateway]
25835
26183
  );
@@ -25846,9 +26194,21 @@ function AgentGUINodeView({
25846
26194
  actions.toggleConversationPinned
25847
26195
  );
25848
26196
  const removeProject = useStableEventCallback2(actions.removeProject);
26197
+ const requestDeleteProjectConversations = useStableEventCallback2(
26198
+ actions.requestDeleteProjectConversations
26199
+ );
26200
+ const cancelDeleteProjectConversations = useStableEventCallback2(
26201
+ actions.cancelDeleteProjectConversations
26202
+ );
25849
26203
  const confirmDeleteProjectConversations = useStableEventCallback2(
25850
26204
  actions.confirmDeleteProjectConversations
25851
26205
  );
26206
+ const requestDeleteConversations = useStableEventCallback2(
26207
+ actions.requestDeleteConversations
26208
+ );
26209
+ const cancelDeleteConversations = useStableEventCallback2(
26210
+ actions.cancelDeleteConversations
26211
+ );
25852
26212
  const confirmDeleteConversations = useStableEventCallback2(
25853
26213
  actions.confirmDeleteConversations
25854
26214
  );
@@ -25894,7 +26254,7 @@ function AgentGUINodeView({
25894
26254
  viewModel.composerSettings.selectedProjectPath
25895
26255
  ]
25896
26256
  );
25897
- useEffect14(() => {
26257
+ useEffect15(() => {
25898
26258
  if (newConversationRequestSequence === null || handledNewConversationRequestSequenceRef.current === newConversationRequestSequence) {
25899
26259
  return;
25900
26260
  }
@@ -25907,7 +26267,7 @@ function AgentGUINodeView({
25907
26267
  newConversationRequestSequence,
25908
26268
  requestCreateConversation
25909
26269
  ]);
25910
- const effectiveWorkspaceAppIcons = useMemo9(
26270
+ const effectiveWorkspaceAppIcons = useMemo10(
25911
26271
  () => mergeWorkspaceAppIconsFromCommands({
25912
26272
  commands: viewModel.availableCommands,
25913
26273
  workspaceAppIcons,
@@ -25984,7 +26344,7 @@ function AgentGUINodeView({
25984
26344
  },
25985
26345
  [onConversationRailWidthChanged]
25986
26346
  );
25987
- useEffect14(() => {
26347
+ useEffect15(() => {
25988
26348
  if (isRailResizing || railResizeWidthPx === null) {
25989
26349
  return;
25990
26350
  }
@@ -26038,7 +26398,7 @@ function AgentGUINodeView({
26038
26398
  const effectiveRailSlashStatusLimits = railSlashStatusLimits ?? slashStatusLimits;
26039
26399
  const shouldShowProviderRailConfigButton = viewModel.conversationFilter.kind === "all" || viewModel.selectedProviderTarget?.disabled !== true;
26040
26400
  const shouldShowProviderRailConfigMenu = shouldShowProviderRailConfigButton && viewModel.conversationFilter.kind !== "all";
26041
- const effectiveProviderAuthAccountLabel = useMemo9(() => {
26401
+ const effectiveProviderAuthAccountLabel = useMemo10(() => {
26042
26402
  const provider = (effectiveRailConfigProvider ?? viewModel.data.provider)?.trim() ?? "";
26043
26403
  if (!provider) {
26044
26404
  return null;
@@ -26062,19 +26422,13 @@ function AgentGUINodeView({
26062
26422
  }, []);
26063
26423
  const [renameConversationTarget, setRenameConversationTarget] = useState14(null);
26064
26424
  const [renameConversationDialogOpen, setRenameConversationDialogOpen] = useState14(false);
26065
- const requestRenameConversation = useCallback10(
26066
- (agentSessionId) => {
26067
- const target = viewModel.conversations.find(
26068
- (conversation) => conversation.id === agentSessionId
26069
- ) ?? (viewModel.activeConversation?.id === agentSessionId ? viewModel.activeConversation : null);
26070
- if (target) {
26071
- setRenameConversationTarget(target);
26072
- setRenameConversationDialogOpen(true);
26073
- }
26074
- },
26075
- [viewModel.activeConversation, viewModel.conversations]
26425
+ const requestRenameConversation = useStableEventCallback2(
26426
+ (conversation) => {
26427
+ setRenameConversationTarget(conversation);
26428
+ setRenameConversationDialogOpen(true);
26429
+ }
26076
26430
  );
26077
- const conversationRailStoreState = useMemo9(
26431
+ const conversationRailStoreState = useMemo10(
26078
26432
  () => ({
26079
26433
  activeConversationId: viewModel.activeConversationId,
26080
26434
  pendingDeleteConversationId: viewModel.pendingDeleteConversation?.id ?? null,
@@ -26099,8 +26453,14 @@ function AgentGUINodeView({
26099
26453
  onSelectConversation: selectConversation,
26100
26454
  onToggleConversationPinned: toggleConversationPinned,
26101
26455
  onMarkConversationUnread: actions.markConversationUnread,
26456
+ pendingDeleteProjectConversations: viewModel.pendingDeleteProjectConversations,
26457
+ pendingDeleteConversations: viewModel.pendingDeleteConversations,
26102
26458
  onRemoveProject: removeProject,
26459
+ onRequestDeleteProjectConversations: requestDeleteProjectConversations,
26460
+ onCancelDeleteProjectConversations: cancelDeleteProjectConversations,
26103
26461
  onConfirmDeleteProjectConversations: confirmDeleteProjectConversations,
26462
+ onRequestDeleteConversations: requestDeleteConversations,
26463
+ onCancelDeleteConversations: cancelDeleteConversations,
26104
26464
  onConfirmDeleteConversations: confirmDeleteConversations,
26105
26465
  onRequestDeleteConversation: requestDeleteConversation,
26106
26466
  onRequestRenameConversation: requestRenameConversation,
@@ -26111,6 +26471,8 @@ function AgentGUINodeView({
26111
26471
  selectProjectDirectory
26112
26472
  }),
26113
26473
  [
26474
+ cancelDeleteProjectConversations,
26475
+ cancelDeleteConversations,
26114
26476
  cancelDeleteConversation,
26115
26477
  confirmDeleteConversation,
26116
26478
  confirmDeleteConversations,
@@ -26125,6 +26487,8 @@ function AgentGUINodeView({
26125
26487
  actions.updateConversationFilter,
26126
26488
  previewMode,
26127
26489
  removeProject,
26490
+ requestDeleteProjectConversations,
26491
+ requestDeleteConversations,
26128
26492
  requestCreateConversation,
26129
26493
  requestDeleteConversation,
26130
26494
  requestRenameConversation,
@@ -26142,6 +26506,8 @@ function AgentGUINodeView({
26142
26506
  viewModel.isDeletingProjectConversations,
26143
26507
  viewModel.isLoadingConversations,
26144
26508
  viewModel.pendingDeleteConversation?.id,
26509
+ viewModel.pendingDeleteProjectConversations,
26510
+ viewModel.pendingDeleteConversations,
26145
26511
  workspaceUserProjectI18n
26146
26512
  ]
26147
26513
  );
@@ -26158,7 +26524,7 @@ function AgentGUINodeView({
26158
26524
  conversationRailStore,
26159
26525
  conversationRailStoreState
26160
26526
  );
26161
- const agentTargetPresentations = useMemo9(
26527
+ const agentTargetPresentations = useMemo10(
26162
26528
  () => viewModel.providerTargets.flatMap(
26163
26529
  (target) => target.agentTargetId ? [
26164
26530
  {
@@ -26210,6 +26576,17 @@ function AgentGUINodeView({
26210
26576
  onRequestComposerFocus: requestComposerFocus
26211
26577
  }
26212
26578
  ),
26579
+ renderSidebarFooter ? /* @__PURE__ */ jsx34(
26580
+ "div",
26581
+ {
26582
+ className: `${AgentGUINode_styles_default.providerRailFooter} nodrag tsh-desktop-no-drag`,
26583
+ "data-testid": "agent-gui-sidebar-footer-slot",
26584
+ children: renderSidebarFooter({
26585
+ currentUserId: viewModel.currentUserId,
26586
+ activeConversation: viewModel.activeConversation
26587
+ })
26588
+ }
26589
+ ) : null,
26213
26590
  shouldShowProviderRailConfigButton ? /* @__PURE__ */ jsx34(
26214
26591
  "div",
26215
26592
  {
@@ -26251,17 +26628,6 @@ function AgentGUINodeView({
26251
26628
  }
26252
26629
  )
26253
26630
  }
26254
- ) : null,
26255
- renderSidebarFooter ? /* @__PURE__ */ jsx34(
26256
- "div",
26257
- {
26258
- className: `${AgentGUINode_styles_default.providerRailFooter} nodrag tsh-desktop-no-drag`,
26259
- "data-testid": "agent-gui-sidebar-footer-slot",
26260
- children: renderSidebarFooter({
26261
- currentUserId: viewModel.currentUserId,
26262
- activeConversation: viewModel.activeConversation
26263
- })
26264
- }
26265
26631
  ) : null
26266
26632
  ]
26267
26633
  }
@@ -26345,6 +26711,7 @@ function AgentGUINodeView({
26345
26711
  workspaceAppIcons: effectiveWorkspaceAppIcons,
26346
26712
  workspaceUserProjectI18n,
26347
26713
  renderProviderUnavailableState,
26714
+ renderProviderReadinessGateState,
26348
26715
  previewMode
26349
26716
  }
26350
26717
  ) })
@@ -26396,7 +26763,7 @@ function AgentGUINodeView({
26396
26763
  }
26397
26764
  )
26398
26765
  ] });
26399
- return previewMode ? content : /* @__PURE__ */ jsx34(TooltipProvider3, { children: content });
26766
+ return /* @__PURE__ */ jsx34(TooltipProvider3, { children: /* @__PURE__ */ jsx34(AgentMentionTooltipProviderScope, { withTooltipProvider: false, children: content }) });
26400
26767
  }
26401
26768
  var AgentGUIRenameConversationDialog = memo2(
26402
26769
  function AgentGUIRenameConversationDialog2({
@@ -26412,7 +26779,7 @@ var AgentGUIRenameConversationDialog = memo2(
26412
26779
  const [isSaving, setIsSaving] = useState14(false);
26413
26780
  const inputRef = useRef12(null);
26414
26781
  const trimmedTitle = title.trim();
26415
- useEffect14(() => {
26782
+ useEffect15(() => {
26416
26783
  if (!open || !conversation) {
26417
26784
  setTitle("");
26418
26785
  setIsSaving(false);
@@ -26420,7 +26787,7 @@ var AgentGUIRenameConversationDialog = memo2(
26420
26787
  }
26421
26788
  setTitle(conversationPlainTitle(conversation, labels, uiLanguage));
26422
26789
  }, [conversation, labels, open, uiLanguage]);
26423
- useEffect14(() => {
26790
+ useEffect15(() => {
26424
26791
  if (!open) {
26425
26792
  return;
26426
26793
  }
@@ -26452,7 +26819,7 @@ var AgentGUIRenameConversationDialog = memo2(
26452
26819
  ConfirmationDialog,
26453
26820
  {
26454
26821
  cancelLabel: labels.cancel,
26455
- className: "sm:max-w-[480px]",
26822
+ className: "bg-[var(--background-fronted)] sm:max-w-[480px]",
26456
26823
  confirmBusy: isSaving,
26457
26824
  confirmDisabled: !trimmedTitle,
26458
26825
  confirmLabel: labels.renameSessionSave,
@@ -26492,11 +26859,12 @@ var AgentGUIRenameConversationDialog = memo2(
26492
26859
  onConfirm: confirmRename,
26493
26860
  onOpenChange,
26494
26861
  children: /* @__PURE__ */ jsx34(
26495
- "input",
26862
+ Input2,
26496
26863
  {
26497
26864
  ref: inputRef,
26498
26865
  "aria-label": labels.renameSessionTitle,
26499
- className: "h-10 w-full rounded-md border border-border bg-background px-3 text-[14px] font-medium leading-5 text-text-primary shadow-none outline-none transition-colors placeholder:text-text-tertiary focus:border-primary",
26866
+ className: "h-9",
26867
+ variant: "md",
26500
26868
  placeholder: labels.renameSessionPlaceholder,
26501
26869
  value: title,
26502
26870
  onChange: (event) => setTitle(event.currentTarget.value),
@@ -26596,7 +26964,8 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26596
26964
  onRequestComposerFocus,
26597
26965
  contextMentionProviders,
26598
26966
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS3,
26599
- renderProviderUnavailableState
26967
+ renderProviderUnavailableState,
26968
+ renderProviderReadinessGateState
26600
26969
  }) {
26601
26970
  "use memo";
26602
26971
  const timelineRef = useRef12(null);
@@ -26622,11 +26991,11 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26622
26991
  const emptyProviderReadinessGate = !hasActiveConversation ? selectedProviderTargetComingSoon ? { status: "coming_soon" } : viewModel.providerReadinessGate : null;
26623
26992
  const activePrompt = viewModel.pendingInteractivePrompt ?? viewModel.pendingApproval;
26624
26993
  const activePromptRequestId = activePrompt?.requestId ?? null;
26625
- const sessionChrome = useMemo9(
26994
+ const sessionChrome = useMemo10(
26626
26995
  () => ({ ...viewModel.sessionChrome, approval: null }),
26627
26996
  [viewModel.sessionChrome]
26628
26997
  );
26629
- const rawSlashStatus = useMemo9(
26998
+ const rawSlashStatus = useMemo10(
26630
26999
  () => resolveSlashStatus({
26631
27000
  rawState: viewModel.sessionChrome.rawState,
26632
27001
  limits: slashStatusLimits,
@@ -26639,7 +27008,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26639
27008
  ]
26640
27009
  );
26641
27010
  const slashStatus = useStableSlashStatus(rawSlashStatus);
26642
- const displayedInlineNotice = useMemo9(() => {
27011
+ const displayedInlineNotice = useMemo10(() => {
26643
27012
  const inlineNotice = viewModel.inlineNotice;
26644
27013
  const inlineNoticeMessage = inlineNotice?.message.trim() ?? "";
26645
27014
  if (!inlineNotice || inlineNoticeMessage === "") {
@@ -26663,7 +27032,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26663
27032
  viewModel.activeLiveState,
26664
27033
  viewModel.inlineNotice
26665
27034
  ]);
26666
- const inlineNoticeChrome = useMemo9(() => {
27035
+ const inlineNoticeChrome = useMemo10(() => {
26667
27036
  if (!displayedInlineNotice) {
26668
27037
  return null;
26669
27038
  }
@@ -26694,7 +27063,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26694
27063
  detailStatus: activeDetailStatus,
26695
27064
  conversation
26696
27065
  });
26697
- const activeConversationTurnBusy = viewModel.isSubmitting || derivedBusyStatus !== null;
27066
+ const activeConversationTurnBusy = viewModel.isSubmitting || viewModel.activeConversationBusy || derivedBusyStatus !== null;
26698
27067
  const isComposerSending = viewModel.isSubmitting || activeConversationTurnBusy || !hasActiveConversation && viewModel.isCreatingConversation;
26699
27068
  const isCollaboratorConversation = isDifferentKnownConversationOwner({
26700
27069
  conversationUserId: viewModel.activeConversation?.userId,
@@ -26706,14 +27075,14 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26706
27075
  const submitDisabled = isCollaboratorConversation || !isAgentProviderReady || !viewModel.canSubmit && !canQueueWhileBusy;
26707
27076
  const hasNonRetryableRecoveryFailure = sessionChrome.recovery?.kind === "failed" && sessionChrome.recovery.canRetry === false;
26708
27077
  const composerDisabled = hasNonRetryableRecoveryFailure || isCollaboratorConversation || !isAgentProviderReady || !canQueueWhileBusy && (viewModel.pendingApproval !== null || viewModel.pendingInteractivePrompt !== null || viewModel.isSubmitting || viewModel.isInterrupting || viewModel.isCreatingConversation);
26709
- const showStopButton = !viewModel.isSubmitting && viewModel.activeLiveState !== "failed" && sessionChrome.auth === null && (activeConversationTurnBusy || viewModel.pendingApproval !== null || viewModel.pendingInteractivePrompt !== null || viewModel.isInterrupting);
27078
+ const showStopButton = viewModel.canCancel && !viewModel.isSubmitting && viewModel.activeLiveState !== "failed" && sessionChrome.auth === null && (activeConversationTurnBusy || viewModel.pendingApproval !== null || viewModel.pendingInteractivePrompt !== null || viewModel.isInterrupting);
26710
27079
  const syncStatus = resolveSyncIndicatorStatus(
26711
27080
  viewModel.activeConversation?.syncState?.status
26712
27081
  );
26713
27082
  const syncLabel = syncStateLabel(syncStatus, labels);
26714
27083
  const showSyncIndicator = Boolean(viewModel.activeConversation?.syncState);
26715
27084
  const showFailedSyncLabel = showSyncIndicator && syncStatus === "failed";
26716
- const conversationFlowLabels = useMemo9(
27085
+ const conversationFlowLabels = useMemo10(
26717
27086
  () => ({
26718
27087
  thinkingLabel: labels.thinkingLabel,
26719
27088
  toolCallsLabel: labels.toolCallsLabel,
@@ -26729,7 +27098,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26729
27098
  labels.userMessageLocator
26730
27099
  ]
26731
27100
  );
26732
- const conversationFlowEmpty = useMemo9(
27101
+ const conversationFlowEmpty = useMemo10(
26733
27102
  () => /* @__PURE__ */ jsxs21(
26734
27103
  "div",
26735
27104
  {
@@ -26743,7 +27112,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26743
27112
  ),
26744
27113
  [labels.conversationUnavailable]
26745
27114
  );
26746
- const chromeLabels = useMemo9(
27115
+ const chromeLabels = useMemo10(
26747
27116
  () => ({
26748
27117
  approvalRequired: labels.approvalRequired,
26749
27118
  authRequired: labels.authRequired,
@@ -26764,7 +27133,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26764
27133
  viewModel.isCancelPending
26765
27134
  ]
26766
27135
  );
26767
- const goalBannerLabels = useMemo9(
27136
+ const goalBannerLabels = useMemo10(
26768
27137
  () => ({
26769
27138
  titleActive: labels.goalTitleActive,
26770
27139
  titlePaused: labels.goalTitlePaused,
@@ -26794,7 +27163,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26794
27163
  labels.goalClearAction
26795
27164
  ]
26796
27165
  );
26797
- const interactivePromptLabels = useMemo9(
27166
+ const interactivePromptLabels = useMemo10(
26798
27167
  () => ({
26799
27168
  approvalLead: labels.approvalRequired,
26800
27169
  planLead: labels.planLead,
@@ -26832,7 +27201,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
26832
27201
  labels.planImplementationSkip
26833
27202
  ]
26834
27203
  );
26835
- const composerLabels = useMemo9(
27204
+ const composerLabels = useMemo10(
26836
27205
  () => ({
26837
27206
  send: labels.send,
26838
27207
  modelLabel: labels.modelLabel,
@@ -27186,7 +27555,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27186
27555
  const agentTargetId = viewModel.data.agentTargetId;
27187
27556
  return !agentTargetId || target.targetId === agentTargetId || target.agentTargetId === agentTargetId;
27188
27557
  }) ?? viewModel.selectedProviderTarget;
27189
- const bottomDockComposerProps = useMemo9(
27558
+ const bottomDockComposerProps = useMemo10(
27190
27559
  () => ({
27191
27560
  workspaceId: viewModel.workspaceId,
27192
27561
  workspacePath: viewModel.workspacePath,
@@ -27226,6 +27595,8 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27226
27595
  composerFocusRequestSequence,
27227
27596
  isActive,
27228
27597
  promptImagesSupported: viewModel.promptImagesSupported,
27598
+ canGoalControl: viewModel.canGoalControl,
27599
+ canUploadAttachment: viewModel.canUploadAttachment,
27229
27600
  providerSelectLabel: labels.providerSwitchLabel,
27230
27601
  handoffLabel: labels.handoffConversation,
27231
27602
  handoffMenuLabel: labels.handoffConversationMenu,
@@ -27335,6 +27706,8 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27335
27706
  viewModel.isInterrupting,
27336
27707
  viewModel.isRespondingApproval,
27337
27708
  viewModel.promptImagesSupported,
27709
+ viewModel.canGoalControl,
27710
+ viewModel.canUploadAttachment,
27338
27711
  viewModel.queuedPrompts,
27339
27712
  viewModel.usage,
27340
27713
  viewModel.workspaceId,
@@ -27344,7 +27717,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27344
27717
  selectHomeComposerAgentTargetAndFocus
27345
27718
  ]
27346
27719
  );
27347
- const emptyHeroComposerProps = useMemo9(
27720
+ const emptyHeroComposerProps = useMemo10(
27348
27721
  () => ({
27349
27722
  ...bottomDockComposerProps,
27350
27723
  layoutMode: "hero"
@@ -27354,13 +27727,14 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27354
27727
  const emptyHeroProvider = viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider;
27355
27728
  const emptyHeroProviderLabel = labels.emptyProviderForProvider?.(emptyHeroProvider) ?? labels.emptyProvider ?? "";
27356
27729
  const emptyHeroLabel = labels.emptyForProvider?.(emptyHeroProvider) ?? labels.empty;
27357
- const emptyHeroIconPresentations = useMemo9(
27730
+ const emptyHeroIconPresentations = useMemo10(
27358
27731
  () => viewModel.conversationFilter.kind === "all" ? agentGUILaunchpadIconPresentations() : [agentGUIProviderIconPresentation(emptyHeroProvider)],
27359
27732
  [emptyHeroProvider, viewModel.conversationFilter]
27360
27733
  );
27361
27734
  const disabledProviderTarget = selectedProviderTargetComingSoon ? viewModel.selectedProviderTarget ?? null : null;
27362
27735
  const shouldRenderProviderUnavailableState = !hasActiveConversation && disabledProviderTarget !== null && renderProviderUnavailableState !== void 0;
27363
- const bottomDockStoreState = useMemo9(
27736
+ const shouldRenderProviderReadinessGateState = !hasActiveConversation && emptyProviderReadinessGate !== null && renderProviderReadinessGateState !== void 0;
27737
+ const bottomDockStoreState = useMemo10(
27364
27738
  () => ({
27365
27739
  // The lifted prompt is rendered from props on the pane; the store still
27366
27740
  // carries it so the snapshot revision tracks prompt changes.
@@ -27396,7 +27770,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27396
27770
  viewModel.drainingQueuedPromptId ?? "",
27397
27771
  viewModel.isRespondingApproval ? "1" : "0"
27398
27772
  ].join("|");
27399
- useEffect14(() => {
27773
+ useEffect15(() => {
27400
27774
  setBottomDockDismissedPromptRequestId(null);
27401
27775
  }, [activePromptRequestId]);
27402
27776
  useLayoutEffect4(() => {
@@ -27593,7 +27967,7 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27593
27967
  observer.disconnect();
27594
27968
  };
27595
27969
  }, [bottomDockStoreRevision, viewModel.activeConversationId]);
27596
- useEffect14(() => {
27970
+ useEffect15(() => {
27597
27971
  const timeline = timelineRef.current;
27598
27972
  const activeConversationId = viewModel.activeConversationId;
27599
27973
  if (!timeline || !activeConversationId) {
@@ -27728,12 +28102,25 @@ var AgentGUIDetailPane = memo2(function AgentGUIDetailPane2({
27728
28102
  disabledProviderTarget.provider
27729
28103
  ),
27730
28104
  unavailableReason: disabledProviderTarget.unavailableReason ?? null
27731
- }) }) : emptyProviderReadinessGate ? /* @__PURE__ */ jsx34(
28105
+ }) }) : emptyProviderReadinessGate ? shouldRenderProviderReadinessGateState ? /* @__PURE__ */ jsx34(Fragment9, { children: renderProviderReadinessGateState?.({
28106
+ provider: emptyHeroProvider,
28107
+ providerLabel: emptyHeroProviderLabel || resolveAgentGuiWorkbenchProviderLabel(emptyHeroProvider),
28108
+ target: viewModel.selectedProviderTarget ?? null,
28109
+ iconUrl: resolveAgentGUIHeroIconUrl(emptyHeroProvider),
28110
+ gate: emptyProviderReadinessGate,
28111
+ showAllProviders: viewModel.conversationFilter.kind === "all"
28112
+ }) }) : /* @__PURE__ */ jsx34(
27732
28113
  AgentGUIProviderReadinessGatePane,
27733
28114
  {
27734
28115
  provider: emptyHeroProvider,
27735
28116
  gate: emptyProviderReadinessGate,
27736
28117
  showAllProviders: viewModel.conversationFilter.kind === "all",
28118
+ emptyLabel: emptyHeroLabel,
28119
+ emptyProvider: emptyHeroProviderLabel,
28120
+ providerTargets: composerProviderTargets,
28121
+ selectedProviderTarget: viewModel.selectedProviderTarget,
28122
+ onProviderSelect: canSwitchComposerProvider && viewModel.activeConversationId === null ? selectHomeComposerAgentTargetAndFocus : void 0,
28123
+ providerSelectLabel: labels.providerSwitchLabel,
27737
28124
  labels
27738
28125
  }
27739
28126
  ) : /* @__PURE__ */ jsx34(
@@ -27890,7 +28277,7 @@ function useOptionalStableEventCallback(callback) {
27890
28277
  useLayoutEffect4(() => {
27891
28278
  callbackRef.current = callback;
27892
28279
  }, [callback]);
27893
- return useMemo9(() => {
28280
+ return useMemo10(() => {
27894
28281
  if (callback == null) {
27895
28282
  return void 0;
27896
28283
  }
@@ -27981,11 +28368,17 @@ var AgentGUIProviderReadinessGatePane = memo2(
27981
28368
  provider,
27982
28369
  gate,
27983
28370
  showAllProviders = false,
28371
+ emptyLabel,
28372
+ emptyProvider,
28373
+ providerTargets,
28374
+ selectedProviderTarget,
28375
+ onProviderSelect,
28376
+ providerSelectLabel,
27984
28377
  labels
27985
28378
  }) {
27986
28379
  "use memo";
27987
28380
  const heroIconUrl = resolveAgentGUIHeroIconUrl(provider);
27988
- const launchpadIconPresentations = useMemo9(
28381
+ const launchpadIconPresentations = useMemo10(
27989
28382
  () => agentGUILaunchpadIconPresentations(),
27990
28383
  []
27991
28384
  );
@@ -27996,6 +28389,7 @@ var AgentGUIProviderReadinessGatePane = memo2(
27996
28389
  showAllProviders: showAllProvidersChecking
27997
28390
  });
27998
28391
  const action = providerGateAction(gate.status);
28392
+ const useSharedHeroTitle = gate.status === "not_installed" || gate.status === "auth_required";
27999
28393
  const pendingLabel = pendingAction === "install" ? labels.providerGatePendingInstall : pendingAction === "login" ? labels.providerGatePendingLogin : pendingAction === "refresh" ? labels.providerGatePendingRefresh : null;
28000
28394
  return /* @__PURE__ */ jsx34("div", { className: AgentGUINode_styles_default.emptyHero, children: /* @__PURE__ */ jsxs21(
28001
28395
  "div",
@@ -28004,9 +28398,10 @@ var AgentGUIProviderReadinessGatePane = memo2(
28004
28398
  "data-testid": "agent-gui-provider-readiness-gate",
28005
28399
  role: "status",
28006
28400
  children: [
28007
- showAllProvidersChecking ? /* @__PURE__ */ jsx34(
28401
+ showAllProviders ? /* @__PURE__ */ jsx34(
28008
28402
  AgentGUIAllProviderGridIcon,
28009
28403
  {
28404
+ activeProvider: provider,
28010
28405
  className: AgentGUINode_styles_default.emptyHeroLaunchpadIcon,
28011
28406
  icons: launchpadIconPresentations
28012
28407
  }
@@ -28020,8 +28415,25 @@ var AgentGUIProviderReadinessGatePane = memo2(
28020
28415
  alt: ""
28021
28416
  }
28022
28417
  ),
28023
- /* @__PURE__ */ jsx34("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: content.title }),
28024
- /* @__PURE__ */ jsx34("p", { className: AgentGUINode_styles_default.emptyProviderGateDescription, children: content.description }),
28418
+ /* @__PURE__ */ jsx34("h2", { className: AgentGUINode_styles_default.emptyHeroTitle, children: useSharedHeroTitle ? /* @__PURE__ */ jsx34(
28419
+ EmptyHeroTitle,
28420
+ {
28421
+ label: emptyLabel,
28422
+ providerLabel: emptyProvider,
28423
+ providerSelectLabel,
28424
+ providerTargets,
28425
+ selectedProviderTarget,
28426
+ onProviderSelect
28427
+ }
28428
+ ) : content.title }),
28429
+ /* @__PURE__ */ jsx34(
28430
+ "p",
28431
+ {
28432
+ className: AgentGUINode_styles_default.emptyProviderGateDescription,
28433
+ "data-testid": "agent-gui-provider-readiness-gate-description",
28434
+ children: content.description
28435
+ }
28436
+ ),
28025
28437
  pendingLabel && !action ? /* @__PURE__ */ jsx34(
28026
28438
  "div",
28027
28439
  {
@@ -28148,22 +28560,36 @@ function AgentGUIUnifiedProviderIcon({
28148
28560
  }
28149
28561
  ) });
28150
28562
  }
28563
+ function agentGUIHeroStripOpacity(distance) {
28564
+ if (distance <= 0) {
28565
+ return 1;
28566
+ }
28567
+ return Math.max(0.15, 1 - distance * 0.4);
28568
+ }
28151
28569
  function AgentGUILaunchpadIconGrid({
28152
28570
  activeProvider,
28153
28571
  icons
28154
28572
  }) {
28155
28573
  const normalizedActiveProvider = activeProvider ? normalizeManagedAgentProvider(activeProvider) : null;
28156
- return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map((icon) => {
28157
- return /* @__PURE__ */ jsx34(
28158
- "span",
28159
- {
28160
- className: AgentGUINode_styles_default.providerRailLaunchpadItem,
28161
- "data-provider-active": normalizedActiveProvider === null ? void 0 : normalizeManagedAgentProvider(icon.provider) === normalizedActiveProvider,
28162
- children: /* @__PURE__ */ jsx34(AgentGUIProviderIconVisual, { imageClassName: "", icon })
28163
- },
28164
- `${icon.provider}:${icon.iconUrl}`
28165
- );
28166
- }) });
28574
+ const activeIndex = normalizedActiveProvider === null ? -1 : icons.findIndex(
28575
+ (icon) => normalizeManagedAgentProvider(icon.provider) === normalizedActiveProvider
28576
+ );
28577
+ const renderItem = (icon, distance, isActive) => /* @__PURE__ */ jsx34(
28578
+ "span",
28579
+ {
28580
+ className: AgentGUINode_styles_default.providerRailLaunchpadItem,
28581
+ "data-provider-active": normalizedActiveProvider === null ? void 0 : isActive,
28582
+ style: { opacity: agentGUIHeroStripOpacity(distance) },
28583
+ children: /* @__PURE__ */ jsx34(AgentGUIProviderIconVisual, { imageClassName: "", icon })
28584
+ },
28585
+ `${icon.provider}:${icon.iconUrl}`
28586
+ );
28587
+ if (activeIndex < 0) {
28588
+ return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map((icon) => renderItem(icon, 0, false)) });
28589
+ }
28590
+ return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailLaunchpadIcon, children: icons.map(
28591
+ (icon, index) => renderItem(icon, Math.abs(index - activeIndex), index === activeIndex)
28592
+ ) });
28167
28593
  }
28168
28594
  function AgentGUIProviderIconVisual({
28169
28595
  ariaHidden = false,
@@ -28301,7 +28727,7 @@ var AgentGUIBottomDockPane = memo2(function AgentGUIBottomDockPane2({
28301
28727
  const goalTokenBudget = goal ? numberValue2(goal.tokenBudget) : null;
28302
28728
  const goalTokensUsed = goal ? numberValue2(goal.tokensUsed) : null;
28303
28729
  const goalTimeUsedSeconds = goal ? numberValue2(goal.timeUsedSeconds) : null;
28304
- const showGoalBanner = isGoalBannerVisible(goalObjective, goalStatus);
28730
+ const showGoalBanner = composerProps.canGoalControl && isGoalBannerVisible(goalObjective, goalStatus);
28305
28731
  return /* @__PURE__ */ jsxs21(
28306
28732
  "div",
28307
28733
  {
@@ -28417,7 +28843,7 @@ function syncAgentGUIConversationRailStore(store, next) {
28417
28843
  Object.assign(store, next);
28418
28844
  }
28419
28845
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
28420
- 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.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.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onMarkConversationUnread === next.onMarkConversationUnread && 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.onRequestRenameConversation === next.onRequestRenameConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
28846
+ return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.pendingDeleteProjectConversations === next.pendingDeleteProjectConversations && current.pendingDeleteConversations === next.pendingDeleteConversations && 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.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.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onMarkConversationUnread === next.onMarkConversationUnread && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onRequestDeleteProjectConversations === next.onRequestDeleteProjectConversations && current.onCancelDeleteProjectConversations === next.onCancelDeleteProjectConversations && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversations === next.onRequestDeleteConversations && current.onCancelDeleteConversations === next.onCancelDeleteConversations && current.onConfirmDeleteConversations === next.onConfirmDeleteConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onRequestRenameConversation === next.onRequestRenameConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
28421
28847
  }
28422
28848
  var AgentGUIConversationRailStorePane = memo2(
28423
28849
  function AgentGUIConversationRailStorePane2({
@@ -28449,6 +28875,18 @@ function normalizeConversationRailProjectPath(path) {
28449
28875
  }
28450
28876
  return normalized.replace(/\/+$/, "") || "/";
28451
28877
  }
28878
+ function preserveAdvancedConversationRailPageState(existing, nextCursor) {
28879
+ if (!existing) {
28880
+ return null;
28881
+ }
28882
+ if (existing.hasMore === false) {
28883
+ return existing;
28884
+ }
28885
+ if (existing.nextCursor && existing.nextCursor !== nextCursor) {
28886
+ return existing;
28887
+ }
28888
+ return null;
28889
+ }
28452
28890
  function conversationRailPageCursor(conversations) {
28453
28891
  let boundary = null;
28454
28892
  for (const conversation of conversations) {
@@ -28552,7 +28990,10 @@ function updateConversationSectionsFromSummaries(previous, conversations, option
28552
28990
  if ((conversation.pinnedAtUnixMs ?? 0) > 0) {
28553
28991
  continue;
28554
28992
  }
28555
- const sectionId = conversation.project ? `project:${normalizeConversationProjectPath(conversation.project.path)}` : "conversations";
28993
+ if (conversation.project) {
28994
+ continue;
28995
+ }
28996
+ const sectionId = "conversations";
28556
28997
  const items = summarySectionItemsById.get(sectionId) ?? [];
28557
28998
  items.push(conversation);
28558
28999
  summarySectionItemsById.set(sectionId, items);
@@ -28561,36 +29002,83 @@ function updateConversationSectionsFromSummaries(previous, conversations, option
28561
29002
  let changed = false;
28562
29003
  const nextSections = previous.map((section) => {
28563
29004
  let sectionChanged = false;
29005
+ if (section.kind === "pinned") {
29006
+ const pinnedSummaryItems = conversations.filter(
29007
+ (conversation) => (conversation.pinnedAtUnixMs ?? 0) > 0
29008
+ );
29009
+ const items2 = section.items.map((item) => {
29010
+ seenIds.add(item.id);
29011
+ const summary = summariesById.get(item.id);
29012
+ if (!summary) {
29013
+ return item;
29014
+ }
29015
+ if ((summary.pinnedAtUnixMs ?? 0) <= 0) {
29016
+ sectionChanged = true;
29017
+ return null;
29018
+ }
29019
+ if (conversationSummariesRenderEqual2(item, summary)) {
29020
+ return item;
29021
+ }
29022
+ sectionChanged = true;
29023
+ return summary;
29024
+ }).filter(
29025
+ (item) => item !== null
29026
+ );
29027
+ const existingIds = new Set(items2.map((item) => item.id));
29028
+ const mergedItems2 = [
29029
+ ...items2,
29030
+ ...pinnedSummaryItems.filter((item) => !existingIds.has(item.id))
29031
+ ];
29032
+ if (mergedItems2.length !== items2.length) {
29033
+ sectionChanged = true;
29034
+ }
29035
+ for (const item of pinnedSummaryItems) {
29036
+ seenIds.add(item.id);
29037
+ }
29038
+ const stableItems2 = stabilizeConversationSectionItems(
29039
+ section.items,
29040
+ sortPinnedConversations(mergedItems2)
29041
+ );
29042
+ if (!sectionChanged && stableItems2 === section.items) {
29043
+ return section;
29044
+ }
29045
+ changed = true;
29046
+ return {
29047
+ ...section,
29048
+ items: stableItems2
29049
+ };
29050
+ }
28564
29051
  const summaryItems = summarySectionItemsById.get(section.id) ?? [];
28565
- const summaryIdsForSection = new Set(summaryItems.map((item) => item.id));
28566
29052
  const items = section.items.map((item) => {
28567
29053
  seenIds.add(item.id);
28568
29054
  const summary = summariesById.get(item.id);
28569
29055
  if (!summary) {
28570
29056
  return item;
28571
29057
  }
29058
+ if ((summary.pinnedAtUnixMs ?? 0) > 0) {
29059
+ sectionChanged = true;
29060
+ return null;
29061
+ }
28572
29062
  const nextItem = section.project ? {
28573
29063
  ...summary,
28574
29064
  project: section.project
28575
- } : summary;
29065
+ } : {
29066
+ ...summary,
29067
+ project: null
29068
+ };
28576
29069
  if (conversationSummariesRenderEqual2(item, nextItem)) {
28577
29070
  return item;
28578
29071
  }
28579
29072
  sectionChanged = true;
28580
29073
  return nextItem;
28581
- }).filter((item) => {
28582
- const summary = summariesById.get(item.id);
28583
- if (!summary || summaryIdsForSection.has(item.id)) {
28584
- return true;
28585
- }
28586
- sectionChanged = true;
28587
- return false;
28588
- });
29074
+ }).filter(
29075
+ (item) => item !== null
29076
+ );
28589
29077
  const nextSection = sectionChanged ? {
28590
29078
  ...section,
28591
29079
  items
28592
29080
  } : section;
28593
- if (section.kind === "pinned" || summaryItems.length === 0) {
29081
+ if (summaryItems.length === 0) {
28594
29082
  if (sectionChanged) {
28595
29083
  changed = true;
28596
29084
  }
@@ -28620,15 +29108,27 @@ function updateConversationSectionsFromSummaries(previous, conversations, option
28620
29108
  };
28621
29109
  });
28622
29110
  const existingSectionIds = new Set(nextSections.map((section) => section.id));
29111
+ const newPinnedConversations = existingSectionIds.has("pinned") || !options.sectionPinnedLabel ? [] : conversations.filter(
29112
+ (conversation) => (conversation.pinnedAtUnixMs ?? 0) > 0 && !seenIds.has(conversation.id)
29113
+ );
28623
29114
  const newConversations = [...summarySectionItemsById.entries()].flatMap(
28624
29115
  ([sectionId, items]) => existingSectionIds.has(sectionId) ? [] : items.filter((conversation) => !seenIds.has(conversation.id))
28625
29116
  );
28626
- if (newConversations.length === 0) {
29117
+ if (newPinnedConversations.length === 0 && newConversations.length === 0) {
28627
29118
  return changed ? nextSections : previous;
28628
29119
  }
28629
29120
  const sectionsWithInsertions = [...nextSections];
29121
+ if (newPinnedConversations.length > 0 && options.sectionPinnedLabel) {
29122
+ sectionsWithInsertions.unshift({
29123
+ id: "pinned",
29124
+ kind: "pinned",
29125
+ label: options.sectionPinnedLabel,
29126
+ project: null,
29127
+ items: sortPinnedConversations(newPinnedConversations)
29128
+ });
29129
+ }
28630
29130
  for (const conversation of newConversations) {
28631
- const targetSectionId = conversation.project ? `project:${normalizeConversationProjectPath(conversation.project.path)}` : "conversations";
29131
+ const targetSectionId = "conversations";
28632
29132
  const targetIndex = sectionsWithInsertions.findIndex(
28633
29133
  (section) => section.id === targetSectionId
28634
29134
  );
@@ -28642,16 +29142,32 @@ function updateConversationSectionsFromSummaries(previous, conversations, option
28642
29142
  }
28643
29143
  sectionsWithInsertions.push({
28644
29144
  id: targetSectionId,
28645
- kind: conversation.project ? "project" : "conversations",
28646
- label: conversation.project?.label ?? options.sectionConversationsLabel,
28647
- project: conversation.project ?? null,
29145
+ kind: "conversations",
29146
+ label: options.sectionConversationsLabel,
29147
+ project: null,
28648
29148
  items: [conversation]
28649
29149
  });
28650
29150
  }
28651
29151
  return sectionsWithInsertions;
28652
29152
  }
29153
+ function sortPinnedConversations(conversations) {
29154
+ return [...conversations].sort(
29155
+ (left, right) => (right.pinnedAtUnixMs ?? 0) - (left.pinnedAtUnixMs ?? 0) || (right.sortTimeUnixMs ?? right.updatedAtUnixMs) - (left.sortTimeUnixMs ?? left.updatedAtUnixMs) || left.id.localeCompare(right.id)
29156
+ );
29157
+ }
28653
29158
  function projectRuntimeSectionsToConversationSections(input) {
28654
- const pinned = [];
29159
+ const pinned = input.pinned ? buildAgentGUIConversationSummaries({
29160
+ conversationFilter: input.conversationFilter,
29161
+ provider: AGENT_GUI_CONVERSATION_RAIL_PROJECTION_PROVIDER,
29162
+ snapshot: {
29163
+ composerOptionsByProvider: {},
29164
+ presences: [],
29165
+ sessionMessagesById: {},
29166
+ sessions: input.pinned.sessions,
29167
+ workspaceId: input.workspaceId
29168
+ },
29169
+ userProjects: []
29170
+ }).filter((conversation) => (conversation.pinnedAtUnixMs ?? 0) > 0) : [];
28655
29171
  const result = [];
28656
29172
  for (const section of input.sections) {
28657
29173
  const project = section.userProject ? {
@@ -28660,6 +29176,7 @@ function projectRuntimeSectionsToConversationSections(input) {
28660
29176
  label: section.userProject.label,
28661
29177
  lastUsedAtUnixMs: section.userProject.lastUsedAtUnixMs,
28662
29178
  path: section.userProject.path,
29179
+ sectionKey: section.userProject.sectionKey,
28663
29180
  updatedAtUnixMs: section.userProject.updatedAtUnixMs
28664
29181
  } : null;
28665
29182
  const conversations = buildAgentGUIConversationSummaries({
@@ -28693,14 +29210,16 @@ function projectRuntimeSectionsToConversationSections(input) {
28693
29210
  });
28694
29211
  }
28695
29212
  if (pinned.length > 0) {
29213
+ const pinnedById = /* @__PURE__ */ new Map();
29214
+ for (const conversation of pinned) {
29215
+ pinnedById.set(conversation.id, conversation);
29216
+ }
28696
29217
  result.unshift({
28697
29218
  id: "pinned",
28698
29219
  kind: "pinned",
28699
29220
  label: input.labels.sectionPinned,
28700
29221
  project: null,
28701
- items: pinned.sort(
28702
- (left, right) => (right.pinnedAtUnixMs ?? 0) - (left.pinnedAtUnixMs ?? 0) || (right.sortTimeUnixMs ?? right.updatedAtUnixMs) - (left.sortTimeUnixMs ?? left.updatedAtUnixMs) || left.id.localeCompare(right.id)
28703
- )
29222
+ items: sortPinnedConversations([...pinnedById.values()])
28704
29223
  });
28705
29224
  }
28706
29225
  return result;
@@ -28712,18 +29231,17 @@ function conversationSyncStatesRenderEqual(left, right) {
28712
29231
  return left === right || (!left || !right ? (left ?? null) === (right ?? null) : left.workspaceId === right.workspaceId && left.agentSessionId === right.agentSessionId && left.status === right.status && left.pendingTimelineItemCount === right.pendingTimelineItemCount && left.pendingStatePatchCount === right.pendingStatePatchCount && left.attemptCount === right.attemptCount && left.failedReportCount === right.failedReportCount && left.lastError === right.lastError && left.lastAttemptAtUnixMs === right.lastAttemptAtUnixMs && left.lastSyncedAtUnixMs === right.lastSyncedAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs);
28713
29232
  }
28714
29233
  function conversationProjectsRenderEqual2(left, right) {
28715
- 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);
29234
+ return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.label === right.label && left.sectionKey === right.sectionKey && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs);
28716
29235
  }
28717
29236
  var agentGUIProviderRailOrder = [
28718
29237
  "codex",
28719
29238
  "claude-code",
28720
29239
  "cursor",
28721
29240
  "tutti-agent",
28722
- "opencode",
28723
29241
  "nexight",
29242
+ "opencode",
28724
29243
  "hermes",
28725
- "openclaw",
28726
- "gemini"
29244
+ "openclaw"
28727
29245
  ];
28728
29246
  var agentGUIProviderRailDefaultProviders = [
28729
29247
  "codex",
@@ -28746,7 +29264,10 @@ function agentGUILaunchpadIconPresentations() {
28746
29264
  agentGUIProviderRailIconPresentation("codex"),
28747
29265
  agentGUIProviderRailIconPresentation("claude-code"),
28748
29266
  agentGUIProviderRailIconPresentation("cursor"),
28749
- agentGUIProviderRailIconPresentation("tutti")
29267
+ agentGUIProviderRailIconPresentation("tutti"),
29268
+ agentGUIProviderRailIconPresentation("opencode"),
29269
+ agentGUIProviderRailIconPresentation("hermes"),
29270
+ agentGUIProviderRailIconPresentation("openclaw")
28750
29271
  ];
28751
29272
  }
28752
29273
  function agentGUIConversationProviderIconUrl(provider) {
@@ -28827,7 +29348,7 @@ var AgentGUIProviderRail = memo2(function AgentGUIProviderRail2({
28827
29348
  onUpdateConversationFilter
28828
29349
  }) {
28829
29350
  "use memo";
28830
- const providerRailOrderStorageKey = useMemo9(
29351
+ const providerRailOrderStorageKey = useMemo10(
28831
29352
  () => agentGUIProviderRailOrderStorageKey(workspaceId),
28832
29353
  [workspaceId]
28833
29354
  );
@@ -28845,7 +29366,7 @@ var AgentGUIProviderRail = memo2(function AgentGUIProviderRail2({
28845
29366
  },
28846
29367
  []
28847
29368
  );
28848
- useEffect14(() => {
29369
+ useEffect15(() => {
28849
29370
  setProviderRailOrder(
28850
29371
  parseAgentGUIProviderRailOrder(
28851
29372
  globalThis.localStorage?.getItem(providerRailOrderStorageKey)
@@ -28862,7 +29383,7 @@ var AgentGUIProviderRail = memo2(function AgentGUIProviderRail2({
28862
29383
  },
28863
29384
  [providerRailOrderStorageKey]
28864
29385
  );
28865
- const railProviderTargets = useMemo9(
29386
+ const railProviderTargets = useMemo10(
28866
29387
  () => agentGUIProviderRailTargets(
28867
29388
  providerTargets,
28868
29389
  providerTargetsLoading,
@@ -28876,7 +29397,7 @@ var AgentGUIProviderRail = memo2(function AgentGUIProviderRail2({
28876
29397
  providerTargetsLoading
28877
29398
  ]
28878
29399
  );
28879
- const providerTiles = useMemo9(() => {
29400
+ const providerTiles = useMemo10(() => {
28880
29401
  const targets = [...railProviderTargets];
28881
29402
  const orderedTargets = providerRailMode === "exact" ? targets : (() => {
28882
29403
  const originalIndexByTarget = /* @__PURE__ */ new Map();
@@ -28900,7 +29421,7 @@ var AgentGUIProviderRail = memo2(function AgentGUIProviderRail2({
28900
29421
  })();
28901
29422
  return applyAgentGUIProviderRailOrder(orderedTargets, providerRailOrder);
28902
29423
  }, [providerRailMode, providerRailOrder, railProviderTargets]);
28903
- const visibleProviderTiles = useMemo9(() => {
29424
+ const visibleProviderTiles = useMemo10(() => {
28904
29425
  if (!providerTiles.some((target) => target.provider === "tutti-agent")) {
28905
29426
  return providerTiles;
28906
29427
  }
@@ -29249,7 +29770,7 @@ var AgentGUIAccountRewardToast = memo2(function AgentGUIAccountRewardToast2({
29249
29770
  labels
29250
29771
  }) {
29251
29772
  "use memo";
29252
- useEffect14(() => {
29773
+ useEffect15(() => {
29253
29774
  if (!toast2.visible) {
29254
29775
  return;
29255
29776
  }
@@ -29657,27 +30178,28 @@ function useAgentGUIConversationRail({
29657
30178
  const workspaceIdRef = useRef12(workspaceId);
29658
30179
  const runtimeListSessionSections = agentActivityRuntime.listSessionSections;
29659
30180
  const runtimeListSessionSectionPage = agentActivityRuntime.listSessionSectionPage;
30181
+ const runtimeListPinnedSessionsPage = agentActivityRuntime.listPinnedSessionsPage;
29660
30182
  const runtimeSectionsEnabled = !previewMode && Boolean(runtimeListSessionSections) && Boolean(runtimeListSessionSectionPage);
29661
30183
  const sectionAgentTargetId = conversationFilter.kind === "agentTarget" ? conversationFilter.agentTargetId.trim() : sectionAgentTargetFallbackId?.trim() ?? "";
29662
- const userProjectPaths = useMemo9(
30184
+ const userProjectPaths = useMemo10(
29663
30185
  () => userProjects.map((project) => project.path.trim()).filter((path) => path.length > 0),
29664
30186
  [userProjects]
29665
30187
  );
29666
- const userProjectPathKey = useMemo9(
30188
+ const userProjectPathKey = useMemo10(
29667
30189
  () => JSON.stringify(userProjectPaths),
29668
30190
  [userProjectPaths]
29669
30191
  );
29670
- const sectionProjectionLabels = useMemo9(
30192
+ const sectionProjectionLabels = useMemo10(
29671
30193
  () => ({
29672
30194
  sectionConversations: labels.sectionConversations,
29673
30195
  sectionPinned: labels.sectionPinned
29674
30196
  }),
29675
30197
  [labels.sectionConversations, labels.sectionPinned]
29676
30198
  );
29677
- useEffect14(() => {
30199
+ useEffect15(() => {
29678
30200
  conversationsRef.current = conversations;
29679
30201
  }, [conversations]);
29680
- useEffect14(() => {
30202
+ useEffect15(() => {
29681
30203
  const workspaceChanged = workspaceIdRef.current !== workspaceId;
29682
30204
  workspaceIdRef.current = workspaceId;
29683
30205
  pagingRequestSequenceRef.current += 1;
@@ -29697,13 +30219,13 @@ function useAgentGUIConversationRail({
29697
30219
  pagingAbortControllersRef.current.clear();
29698
30220
  };
29699
30221
  }, [conversationFilter, userProjectPathKey, workspaceId]);
29700
- const conversationMembershipKey = useMemo9(
30222
+ const conversationMembershipKey = useMemo10(
29701
30223
  () => conversations.map(
29702
30224
  (conversation) => `${conversation.id}:${conversation.pinnedAtUnixMs ?? 0}`
29703
30225
  ).join("|"),
29704
30226
  [conversations]
29705
30227
  );
29706
- useEffect14(() => {
30228
+ useEffect15(() => {
29707
30229
  if (!runtimeSectionsEnabled || !runtimeListSessionSections) {
29708
30230
  setRuntimeRailSectionsPending(false);
29709
30231
  return;
@@ -29723,13 +30245,17 @@ function useAgentGUIConversationRail({
29723
30245
  const sections = projectRuntimeSectionsToConversationSections({
29724
30246
  conversationFilter,
29725
30247
  labels: sectionProjectionLabels,
30248
+ pinned: page.pinned,
29726
30249
  sections: page.sections,
29727
30250
  workspaceId: page.workspaceId
29728
30251
  });
29729
30252
  const sectionsWithSummaries = updateConversationSectionsFromSummaries(
29730
30253
  sections,
29731
30254
  conversationsRef.current,
29732
- { sectionConversationsLabel: labels.sectionConversations }
30255
+ {
30256
+ sectionConversationsLabel: labels.sectionConversations,
30257
+ sectionPinnedLabel: labels.sectionPinned
30258
+ }
29733
30259
  );
29734
30260
  setRuntimeRailSections(
29735
30261
  (current) => stabilizeConversationSections(
@@ -29738,13 +30264,30 @@ function useAgentGUIConversationRail({
29738
30264
  )
29739
30265
  );
29740
30266
  setRuntimeRailSectionsPending(false);
29741
- setSectionPageStates(() => {
30267
+ setSectionPageStates((current) => {
29742
30268
  const next = /* @__PURE__ */ new Map();
30269
+ if (page.pinned) {
30270
+ const nextCursor = page.pinned.nextCursor ?? null;
30271
+ const preserved = preserveAdvancedConversationRailPageState(
30272
+ current.get("pinned"),
30273
+ nextCursor
30274
+ );
30275
+ next.set("pinned", {
30276
+ hasMore: preserved?.hasMore ?? page.pinned.hasMore,
30277
+ isLoading: false,
30278
+ nextCursor: preserved?.nextCursor ?? nextCursor
30279
+ });
30280
+ }
29743
30281
  for (const section of page.sections) {
30282
+ const nextCursor = section.nextCursor ?? null;
30283
+ const preserved = preserveAdvancedConversationRailPageState(
30284
+ current.get(section.sectionKey),
30285
+ nextCursor
30286
+ );
29744
30287
  next.set(section.sectionKey, {
29745
- hasMore: section.hasMore,
30288
+ hasMore: preserved?.hasMore ?? section.hasMore,
29746
30289
  isLoading: false,
29747
- nextCursor: section.nextCursor ?? null
30290
+ nextCursor: preserved?.nextCursor ?? nextCursor
29748
30291
  });
29749
30292
  }
29750
30293
  return next;
@@ -29770,7 +30313,7 @@ function useAgentGUIConversationRail({
29770
30313
  userProjectPathKey,
29771
30314
  workspaceId
29772
30315
  ]);
29773
- useEffect14(() => {
30316
+ useEffect15(() => {
29774
30317
  if (!runtimeSectionsEnabled) {
29775
30318
  return;
29776
30319
  }
@@ -29780,27 +30323,32 @@ function useAgentGUIConversationRail({
29780
30323
  );
29781
30324
  setRuntimeRailSections(
29782
30325
  (current) => updateConversationSectionsFromSummaries(current, filteredConversations, {
29783
- sectionConversationsLabel: labels.sectionConversations
30326
+ sectionConversationsLabel: labels.sectionConversations,
30327
+ sectionPinnedLabel: labels.sectionPinned
29784
30328
  })
29785
30329
  );
29786
30330
  }, [
29787
30331
  conversationFilter,
29788
30332
  conversations,
29789
30333
  labels.sectionConversations,
30334
+ labels.sectionPinned,
29790
30335
  runtimeSectionsEnabled
29791
30336
  ]);
29792
30337
  const loadMoreSectionConversations = useCallback10(
29793
30338
  (section) => {
29794
- if (!runtimeListSessionSectionPage || previewMode || conversationQuery.trim()) {
29795
- return;
29796
- }
29797
- if (section.kind === "pinned") {
30339
+ if (previewMode || conversationQuery.trim()) {
29798
30340
  return;
29799
30341
  }
29800
30342
  const currentPageState = sectionPageStates.get(section.id);
29801
30343
  if (currentPageState?.isLoading || currentPageState?.hasMore === false) {
29802
30344
  return;
29803
30345
  }
30346
+ if (section.kind === "pinned" && !runtimeListPinnedSessionsPage) {
30347
+ return;
30348
+ }
30349
+ if (section.kind !== "pinned" && !runtimeListSessionSectionPage) {
30350
+ return;
30351
+ }
29804
30352
  const fallbackCursor = conversationRailPageCursor(section.items);
29805
30353
  const cursor = currentPageState?.nextCursor ?? fallbackCursor;
29806
30354
  const requestSequence = pagingRequestSequenceRef.current;
@@ -29815,7 +30363,82 @@ function useAgentGUIConversationRail({
29815
30363
  });
29816
30364
  return next;
29817
30365
  });
29818
- void runtimeListSessionSectionPage({
30366
+ if (section.kind === "pinned") {
30367
+ const listPinnedSessionsPage = runtimeListPinnedSessionsPage;
30368
+ if (!listPinnedSessionsPage) {
30369
+ return;
30370
+ }
30371
+ void listPinnedSessionsPage({
30372
+ agentTargetId: sectionAgentTargetId || void 0,
30373
+ cursor: cursor || void 0,
30374
+ limit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
30375
+ signal: abortController.signal,
30376
+ workspaceId
30377
+ }).then((page) => {
30378
+ if (abortController.signal.aborted || requestSequence !== pagingRequestSequenceRef.current) {
30379
+ return;
30380
+ }
30381
+ const pageConversations = buildAgentGUIConversationSummaries({
30382
+ conversationFilter,
30383
+ provider: AGENT_GUI_CONVERSATION_RAIL_PROJECTION_PROVIDER,
30384
+ snapshot: {
30385
+ composerOptionsByProvider: {},
30386
+ presences: [],
30387
+ sessionMessagesById: {},
30388
+ sessions: page.sessions,
30389
+ workspaceId
30390
+ },
30391
+ userProjects: []
30392
+ }).filter((conversation) => (conversation.pinnedAtUnixMs ?? 0) > 0);
30393
+ setRuntimeRailSections((current) => {
30394
+ if (!current) {
30395
+ return current;
30396
+ }
30397
+ return current.map(
30398
+ (candidate) => candidate.id === section.id ? {
30399
+ ...candidate,
30400
+ items: mergeConversationRailPageItems(
30401
+ candidate.items,
30402
+ pageConversations
30403
+ )
30404
+ } : candidate
30405
+ );
30406
+ });
30407
+ setSectionPageStates((current) => {
30408
+ const next = new Map(current);
30409
+ next.set(section.id, {
30410
+ hasMore: page.hasMore,
30411
+ isLoading: false,
30412
+ nextCursor: page.nextCursor ?? null
30413
+ });
30414
+ return next;
30415
+ });
30416
+ }).catch(() => {
30417
+ if (abortController.signal.aborted || requestSequence !== pagingRequestSequenceRef.current) {
30418
+ return;
30419
+ }
30420
+ setSectionPageStates((current) => {
30421
+ const next = new Map(current);
30422
+ const existing = next.get(section.id);
30423
+ next.set(section.id, {
30424
+ hasMore: existing?.hasMore ?? true,
30425
+ isLoading: false,
30426
+ nextCursor: existing?.nextCursor ?? null
30427
+ });
30428
+ return next;
30429
+ });
30430
+ }).finally(() => {
30431
+ if (pagingAbortControllersRef.current.get(section.id) === abortController) {
30432
+ pagingAbortControllersRef.current.delete(section.id);
30433
+ }
30434
+ });
30435
+ return;
30436
+ }
30437
+ const listSessionSectionPage = runtimeListSessionSectionPage;
30438
+ if (!listSessionSectionPage) {
30439
+ return;
30440
+ }
30441
+ void listSessionSectionPage({
29819
30442
  agentTargetId: sectionAgentTargetId || void 0,
29820
30443
  cursor: cursor || void 0,
29821
30444
  limit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
@@ -29888,6 +30511,7 @@ function useAgentGUIConversationRail({
29888
30511
  conversationFilter,
29889
30512
  conversationQuery,
29890
30513
  previewMode,
30514
+ runtimeListPinnedSessionsPage,
29891
30515
  runtimeListSessionSectionPage,
29892
30516
  sectionAgentTargetId,
29893
30517
  sectionPageStates,
@@ -29930,8 +30554,14 @@ var AgentGUIConversationRailPane = memo2(
29930
30554
  onOpenProjectFiles,
29931
30555
  onOpenConversationWindow,
29932
30556
  selectProjectDirectory,
30557
+ pendingDeleteProjectConversations,
30558
+ pendingDeleteConversations,
29933
30559
  onRemoveProject,
30560
+ onRequestDeleteProjectConversations,
30561
+ onCancelDeleteProjectConversations,
29934
30562
  onConfirmDeleteProjectConversations,
30563
+ onRequestDeleteConversations,
30564
+ onCancelDeleteConversations,
29935
30565
  onConfirmDeleteConversations,
29936
30566
  onRequestDeleteConversation,
29937
30567
  onRequestRenameConversation,
@@ -29967,7 +30597,7 @@ var AgentGUIConversationRailPane = memo2(
29967
30597
  userProjects,
29968
30598
  workspaceId
29969
30599
  });
29970
- useEffect14(() => {
30600
+ useEffect15(() => {
29971
30601
  const timer = window.setInterval(() => {
29972
30602
  setCurrentTimeMs(Date.now());
29973
30603
  }, 6e4);
@@ -29975,11 +30605,11 @@ var AgentGUIConversationRailPane = memo2(
29975
30605
  window.clearInterval(timer);
29976
30606
  };
29977
30607
  }, []);
29978
- const displayConversations = useMemo9(
30608
+ const displayConversations = useMemo10(
29979
30609
  () => runtimeSectionsEnabled ? runtimeRailSections?.flatMap((section) => section.items) ?? [] : runtimeRailSections ? runtimeRailSections.flatMap((section) => section.items) : conversations,
29980
30610
  [conversations, runtimeRailSections, runtimeSectionsEnabled]
29981
30611
  );
29982
- const filteredConversationResult = useMemo9(() => {
30612
+ const filteredConversationResult = useMemo10(() => {
29983
30613
  const startedAtMs = agentGuiPerfNowMs();
29984
30614
  const query = conversationQuery.trim().toLowerCase();
29985
30615
  const items = !query ? displayConversations : displayConversations.filter(
@@ -29991,18 +30621,12 @@ var AgentGUIConversationRailPane = memo2(
29991
30621
  };
29992
30622
  }, [conversationQuery, displayConversations, labels, uiLanguage]);
29993
30623
  const filteredConversations = filteredConversationResult.items;
29994
- const groupedConversationResult = useMemo9(() => {
30624
+ const groupedConversationResult = useMemo10(() => {
29995
30625
  const startedAtMs = agentGuiPerfNowMs();
29996
30626
  const query = conversationQuery.trim();
29997
- const rawGroups = runtimeSectionsEnabled || runtimeRailSections ? runtimeRailSections ? !query ? runtimeRailSections : runtimeRailSections.map((section) => ({
29998
- ...section,
29999
- items: section.items.filter(
30000
- (item) => filteredConversations.some(
30001
- (conversation) => conversation.id === item.id
30002
- )
30003
- )
30004
- })).filter(
30005
- (section) => section.kind !== "pinned" || section.items.length > 0
30627
+ const rawGroups = runtimeSectionsEnabled || runtimeRailSections ? runtimeRailSections ? !query ? runtimeRailSections : filterConversationSectionsBySearchMatches(
30628
+ runtimeRailSections,
30629
+ filteredConversations
30006
30630
  ) : [] : groupConversations(filteredConversations, labels, userProjects, {
30007
30631
  includeEmptyConversations: !query
30008
30632
  });
@@ -30035,13 +30659,13 @@ var AgentGUIConversationRailPane = memo2(
30035
30659
  return next;
30036
30660
  });
30037
30661
  }, []);
30038
- const groupedConversationIdentityKey = useMemo9(
30662
+ const groupedConversationIdentityKey = useMemo10(
30039
30663
  () => groupedConversations.map(
30040
30664
  (section) => `${section.id}:${section.items.map((item) => item.id).join(",")}`
30041
30665
  ).join("|"),
30042
30666
  [groupedConversations]
30043
30667
  );
30044
- const projectConversationCountsByPath = useMemo9(() => {
30668
+ const projectConversationCountsByPath = useMemo10(() => {
30045
30669
  const counts = /* @__PURE__ */ new Map();
30046
30670
  for (const conversation of displayConversations) {
30047
30671
  const normalizedPath = normalizeConversationRailProjectPath(
@@ -30158,7 +30782,7 @@ var AgentGUIConversationRailPane = memo2(
30158
30782
  const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
30159
30783
  const projectConversationCount = normalizedProjectPath ? projectConversationCountsByPath.get(normalizedProjectPath) ?? 0 : 0;
30160
30784
  const sectionPageState = sectionPageStates.get(section.id);
30161
- const sectionHasMore = !conversationQuery.trim() && section.kind !== "pinned" && sectionPageState?.hasMore === true;
30785
+ const sectionHasMore = !conversationQuery.trim() && sectionPageState?.hasMore === true;
30162
30786
  return /* @__PURE__ */ jsxs21(Fragment8, { children: [
30163
30787
  showProjectRailHeader ? /* @__PURE__ */ jsx34(
30164
30788
  AgentGUIProjectRailHeader,
@@ -30192,6 +30816,8 @@ var AgentGUIConversationRailPane = memo2(
30192
30816
  onConfirmDeleteConversation,
30193
30817
  onCreateConversation,
30194
30818
  onLoadMoreConversations: loadMoreSectionConversations,
30819
+ onRequestDeleteProjectConversations,
30820
+ onRequestDeleteConversations,
30195
30821
  onRequestDeleteConversation,
30196
30822
  onRequestRenameConversation,
30197
30823
  onSelectConversation,
@@ -30213,29 +30839,34 @@ var AgentGUIConversationRailPane = memo2(
30213
30839
  {
30214
30840
  cancelLabel: labels.cancel,
30215
30841
  className: AGENT_GUI_CONFIRMATION_DIALOG_CLASS_NAME,
30216
- confirmBusy: (pendingProjectAction?.kind === "batch-delete" || pendingProjectAction?.kind === "batch-delete-conversations") && isDeletingProjectConversations,
30217
- confirmLabel: pendingProjectAction?.kind === "batch-delete" ? labels.batchDeleteProjectSessionsConfirm : pendingProjectAction?.kind === "batch-delete-conversations" ? labels.batchDeleteConversationsConfirm : labels.removeProject,
30218
- description: pendingProjectAction?.kind === "batch-delete" ? labels.batchDeleteProjectSessionsBody(
30219
- pendingProjectAction.conversationCount,
30220
- pendingProjectAction.label
30221
- ) : pendingProjectAction?.kind === "batch-delete-conversations" ? labels.batchDeleteConversationsBody(
30222
- pendingProjectAction.conversationCount
30842
+ confirmBusy: pendingDeleteProjectConversations?.conversationCount === null || pendingDeleteConversations?.conversationCount === null || (pendingDeleteProjectConversations !== null || pendingDeleteConversations !== null) && isDeletingProjectConversations,
30843
+ confirmDisabled: pendingDeleteProjectConversations?.conversationCount === null || pendingDeleteConversations?.conversationCount === null,
30844
+ confirmLabel: pendingDeleteProjectConversations ? labels.batchDeleteProjectSessionsConfirm : pendingDeleteConversations ? labels.batchDeleteConversationsConfirm : labels.removeProject,
30845
+ description: pendingDeleteProjectConversations ? pendingDeleteProjectConversations.conversationCount === null ? labels.loadingConversations : labels.batchDeleteProjectSessionsBody(
30846
+ pendingDeleteProjectConversations.conversationCount,
30847
+ pendingDeleteProjectConversations.label
30848
+ ) : pendingDeleteConversations ? pendingDeleteConversations.conversationCount === null ? labels.loadingConversations : labels.batchDeleteConversationsBody(
30849
+ pendingDeleteConversations.conversationCount
30223
30850
  ) : pendingProjectAction ? labels.removeProjectConfirmDescription(
30224
30851
  pendingProjectAction.label
30225
30852
  ) : void 0,
30226
- onCancel: () => setPendingProjectAction(null),
30227
- onConfirm: () => {
30228
- const action = pendingProjectAction;
30853
+ onCancel: () => {
30229
30854
  setPendingProjectAction(null);
30230
- if (!action) {
30855
+ onCancelDeleteProjectConversations();
30856
+ onCancelDeleteConversations();
30857
+ },
30858
+ onConfirm: () => {
30859
+ if (pendingDeleteProjectConversations) {
30860
+ onConfirmDeleteProjectConversations();
30231
30861
  return;
30232
30862
  }
30233
- if (action.kind === "batch-delete") {
30234
- onConfirmDeleteProjectConversations(action.path);
30863
+ if (pendingDeleteConversations) {
30864
+ onConfirmDeleteConversations();
30235
30865
  return;
30236
30866
  }
30237
- if (action.kind === "batch-delete-conversations") {
30238
- onConfirmDeleteConversations(action.sessionIds);
30867
+ const action = pendingProjectAction;
30868
+ setPendingProjectAction(null);
30869
+ if (!action) {
30239
30870
  return;
30240
30871
  }
30241
30872
  onRemoveProject(action.path);
@@ -30243,11 +30874,13 @@ var AgentGUIConversationRailPane = memo2(
30243
30874
  onOpenChange: (open) => {
30244
30875
  if (!open) {
30245
30876
  setPendingProjectAction(null);
30877
+ onCancelDeleteProjectConversations();
30878
+ onCancelDeleteConversations();
30246
30879
  }
30247
30880
  },
30248
- open: pendingProjectAction !== null,
30881
+ open: pendingDeleteProjectConversations !== null || pendingDeleteConversations !== null || pendingProjectAction !== null,
30249
30882
  overlayClassName: AGENT_GUI_CONFIRMATION_DIALOG_OVERLAY_CLASS_NAME,
30250
- title: pendingProjectAction?.kind === "batch-delete" ? labels.batchDeleteProjectSessionsTitle : pendingProjectAction?.kind === "batch-delete-conversations" ? labels.batchDeleteConversationsTitle : labels.removeProjectConfirmTitle,
30883
+ title: pendingDeleteProjectConversations ? labels.batchDeleteProjectSessionsTitle : pendingDeleteConversations ? labels.batchDeleteConversationsTitle : labels.removeProjectConfirmTitle,
30251
30884
  tone: "destructive"
30252
30885
  }
30253
30886
  )
@@ -30284,6 +30917,8 @@ var AgentGUIConversationRailSection = memo2(
30284
30917
  onMarkConversationUnread,
30285
30918
  onOpenProjectFiles,
30286
30919
  onOpenConversationWindow,
30920
+ onRequestDeleteProjectConversations,
30921
+ onRequestDeleteConversations,
30287
30922
  onRequestDeleteConversation,
30288
30923
  onRequestRenameConversation,
30289
30924
  onCancelDeleteConversation,
@@ -30295,7 +30930,7 @@ var AgentGUIConversationRailSection = memo2(
30295
30930
  AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
30296
30931
  );
30297
30932
  const visibleItemCount = isSectionCollapsed ? 0 : Math.min(visibleItemLimit, section.items.length);
30298
- const visibleItems = useMemo9(() => {
30933
+ const visibleItems = useMemo10(() => {
30299
30934
  if (isSectionCollapsed) {
30300
30935
  return [];
30301
30936
  }
@@ -30502,13 +31137,7 @@ var AgentGUIConversationRailSection = memo2(
30502
31137
  {
30503
31138
  className: `${AgentGUINode_styles_default.composerMenuItem} nodrag [-webkit-app-region:no-drag]`,
30504
31139
  onSelect: () => {
30505
- const label = projectLabel || projectPath;
30506
- setPendingProjectAction({
30507
- kind: "batch-delete",
30508
- conversationCount: projectConversationCount,
30509
- label,
30510
- path: projectPath
30511
- });
31140
+ onRequestDeleteProjectConversations(projectPath);
30512
31141
  },
30513
31142
  children: /* @__PURE__ */ jsx34("span", { children: labels.batchDeleteProjectSessions })
30514
31143
  }
@@ -30584,12 +31213,7 @@ var AgentGUIConversationRailSection = memo2(
30584
31213
  {
30585
31214
  className: `${AgentGUINode_styles_default.composerMenuItem} nodrag [-webkit-app-region:no-drag]`,
30586
31215
  onSelect: () => {
30587
- setPendingProjectAction({
30588
- kind: "batch-delete-conversations",
30589
- conversationCount: section.items.length,
30590
- label: section.label,
30591
- sessionIds: section.items.map((item) => item.id)
30592
- });
31216
+ onRequestDeleteConversations();
30593
31217
  },
30594
31218
  children: /* @__PURE__ */ jsx34("span", { children: labels.batchDeleteConversations })
30595
31219
  }
@@ -30721,8 +31345,8 @@ var AgentGUIConversationRailItem = memo2(
30721
31345
  onRequestDeleteConversation(item.id);
30722
31346
  }, [item.id, onRequestDeleteConversation]);
30723
31347
  const handleRequestRename = useCallback10(() => {
30724
- onRequestRenameConversation(item.id);
30725
- }, [item.id, onRequestRenameConversation]);
31348
+ onRequestRenameConversation(item);
31349
+ }, [item, onRequestRenameConversation]);
30726
31350
  const handleContextMenuRename = useCallback10(() => {
30727
31351
  if (contextMenuRenameRequestedRef.current) {
30728
31352
  return;
@@ -30961,7 +31585,7 @@ function AgentGUIProjectRailHeader({
30961
31585
  }) {
30962
31586
  "use memo";
30963
31587
  const agentHostApi = useAgentHostApi();
30964
- const userProjectApi = useMemo9(
31588
+ const userProjectApi = useMemo10(
30965
31589
  () => agentHostApi.userProjects ? {
30966
31590
  ...agentHostApi.userProjects,
30967
31591
  selectDirectory: selectProjectDirectory ?? agentHostApi.workspace.selectDirectory
@@ -31263,7 +31887,7 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
31263
31887
  import { Info as Info3 } from "lucide-react";
31264
31888
  import {
31265
31889
  useCallback as useCallback11,
31266
- useEffect as useEffect15,
31890
+ useEffect as useEffect16,
31267
31891
  useLayoutEffect as useLayoutEffect5,
31268
31892
  useRef as useRef13,
31269
31893
  useState as useState15
@@ -31346,7 +31970,7 @@ function AgentProbeInfoPopover({
31346
31970
  maxWidth: availableWidth
31347
31971
  });
31348
31972
  }, []);
31349
- useEffect15(() => {
31973
+ useEffect16(() => {
31350
31974
  if (!isOpen) {
31351
31975
  return;
31352
31976
  }
@@ -31492,22 +32116,12 @@ var AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS = [
31492
32116
  {
31493
32117
  id: "opencode",
31494
32118
  // i18n-check-ignore: Provider brand name.
31495
- label: "OpenCode",
32119
+ label: "Open Code",
31496
32120
  toolIds: ["opencode-cli"],
31497
32121
  agentIds: ["opencode"],
31498
32122
  runtimeManaged: true,
31499
32123
  helperProvider: "opencode",
31500
32124
  aliases: ["open code", "open-code", "opencode-ai"]
31501
- },
31502
- {
31503
- id: "gemini",
31504
- // i18n-check-ignore: Provider brand name.
31505
- label: "Gemini CLI",
31506
- toolIds: ["gemini-cli"],
31507
- agentIds: ["gemini"],
31508
- runtimeManaged: true,
31509
- helperProvider: "gemini",
31510
- aliases: ["gemini cli"]
31511
32125
  }
31512
32126
  ];
31513
32127
  var WORKSPACE_DESKTOP_MANAGED_AGENT_DOCK_PROVIDER_ORDER = AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS.map(
@@ -31865,7 +32479,7 @@ function composerOverridesByAgentTargetIdEqual(left, right) {
31865
32479
  return true;
31866
32480
  }
31867
32481
  function areAgentGUINodePropsEqual(previous, next) {
31868
- 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.accountMenuState === next.accountMenuState && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.providerRailAllPresentation?.iconUrl === next.providerRailAllPresentation?.iconUrl && previous.renderSidebarFooter === next.renderSidebarFooter && previous.providerRailMode === next.providerRailMode && previous.renderProviderRailEmpty === next.renderProviderRailEmpty && previous.renderProviderUnavailableState === next.renderProviderUnavailableState && previous.comingSoonProviders === next.comingSoonProviders && 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.providerAuthAccountLabels === next.providerAuthAccountLabels && 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;
32482
+ 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.accountMenuState === next.accountMenuState && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.providerRailAllPresentation?.iconUrl === next.providerRailAllPresentation?.iconUrl && previous.renderSidebarFooter === next.renderSidebarFooter && previous.providerRailMode === next.providerRailMode && previous.renderProviderRailEmpty === next.renderProviderRailEmpty && previous.renderProviderUnavailableState === next.renderProviderUnavailableState && previous.renderProviderReadinessGateState === next.renderProviderReadinessGateState && previous.comingSoonProviders === next.comingSoonProviders && 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.providerAuthAccountLabels === next.providerAuthAccountLabels && 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;
31869
32483
  }
31870
32484
  var AgentGUINode = memo3(function AgentGUINode2({
31871
32485
  nodeId,
@@ -31899,6 +32513,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
31899
32513
  providerRailMode = "catalog",
31900
32514
  renderProviderRailEmpty,
31901
32515
  renderProviderUnavailableState,
32516
+ renderProviderReadinessGateState,
31902
32517
  renderSidebarFooter,
31903
32518
  comingSoonProviders,
31904
32519
  providerReadinessGates = null,
@@ -31931,11 +32546,11 @@ var AgentGUINode = memo3(function AgentGUINode2({
31931
32546
  }) {
31932
32547
  "use memo";
31933
32548
  const { i18n, locale, t } = useTranslation();
31934
- const workspaceUserProjectI18n = useMemo10(
32549
+ const workspaceUserProjectI18n = useMemo11(
31935
32550
  () => createWorkspaceUserProjectI18nRuntime(i18n),
31936
32551
  [i18n]
31937
32552
  );
31938
- const workspaceFileManagerI18n = useMemo10(
32553
+ const workspaceFileManagerI18n = useMemo11(
31939
32554
  () => typeof i18n?.t === "function" ? createWorkspaceFileManagerI18nRuntime(i18n) : null,
31940
32555
  [i18n]
31941
32556
  );
@@ -32000,7 +32615,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32000
32615
  const isConversationRailManuallyCollapsed = state.conversationRailCollapsed === true;
32001
32616
  const isConversationRailAutoCollapsed = shouldAutoCollapseAgentGUIConversationRail(width);
32002
32617
  const isConversationRailCollapsed = isConversationRailManuallyCollapsed || isConversationRailAutoCollapsed;
32003
- const minSize = useMemo10(
32618
+ const minSize = useMemo11(
32004
32619
  () => ({
32005
32620
  ...resolveCanonicalNodeMinSize("agentGui"),
32006
32621
  width: AGENT_GUI_COLLAPSED_MIN_WIDTH_PX
@@ -32089,7 +32704,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32089
32704
  },
32090
32705
  [actions, onUpdateNode, previewMode]
32091
32706
  );
32092
- const viewActions = useMemo10(
32707
+ const viewActions = useMemo11(
32093
32708
  () => ({
32094
32709
  ...actions,
32095
32710
  createConversation: handleCreateConversation
@@ -32102,7 +32717,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32102
32717
  const selectedProviderTargetLabel = viewModel.selectedProviderTarget?.label ?? resolveAgentGUIProviderDisplayLabel(state.provider, fallbackAgentTitle);
32103
32718
  const displayProviderLabel = viewModel.activeConversation ? resolveAgentGUIProviderDisplayLabel(activeProvider, fallbackAgentTitle) : selectedProviderTargetLabel;
32104
32719
  const activeConversationDockTitle = viewModel.activeConversation ? resolveAgentGUIDockConversationTitle(viewModel.activeConversation) : null;
32105
- useEffect16(() => {
32720
+ useEffect17(() => {
32106
32721
  if (previewMode || !viewModel.activeConversation) {
32107
32722
  return;
32108
32723
  }
@@ -32132,7 +32747,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32132
32747
  state.lastActiveConversationTitle,
32133
32748
  viewModel.activeConversation
32134
32749
  ]);
32135
- const labels = useMemo10(
32750
+ const labels = useMemo11(
32136
32751
  () => ({
32137
32752
  initialPlaceholder: t("agentHost.agentGui.initialPlaceholder", {
32138
32753
  provider: displayProviderLabel
@@ -32731,7 +33346,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32731
33346
  workspaceAppIcons
32732
33347
  ]
32733
33348
  );
32734
- const workspaceFileReferenceCopy = useMemo10(
33349
+ const workspaceFileReferenceCopy = useMemo11(
32735
33350
  () => ({
32736
33351
  t(key, values) {
32737
33352
  const localeKey = workspaceFileReferenceLocaleKeyByPickerKey[key];
@@ -32742,28 +33357,28 @@ var AgentGUINode = memo3(function AgentGUINode2({
32742
33357
  );
32743
33358
  const windowTitle = title;
32744
33359
  const activeProbeProvider = activeProvider;
32745
- const railStatusProvider = useMemo10(
33360
+ const railStatusProvider = useMemo11(
32746
33361
  () => resolveAgentGUIRailStatusProvider({
32747
33362
  conversationFilter: viewModel.conversationFilter,
32748
33363
  providerTargets: viewModel.providerTargets
32749
33364
  }),
32750
33365
  [viewModel.conversationFilter, viewModel.providerTargets]
32751
33366
  );
32752
- const activeAgentProbe = useMemo10(
33367
+ const activeAgentProbe = useMemo11(
32753
33368
  () => findWorkspaceAgentProbeForDockProvider(
32754
33369
  workspaceAgentProbes?.snapshot ?? null,
32755
33370
  activeProbeProvider
32756
33371
  ),
32757
33372
  [activeProbeProvider, workspaceAgentProbes?.snapshot]
32758
33373
  );
32759
- const railAgentProbe = useMemo10(
33374
+ const railAgentProbe = useMemo11(
32760
33375
  () => railStatusProvider ? findWorkspaceAgentProbeForDockProvider(
32761
33376
  workspaceAgentProbes?.snapshot ?? null,
32762
33377
  railStatusProvider
32763
33378
  ) : null,
32764
33379
  [railStatusProvider, workspaceAgentProbes?.snapshot]
32765
33380
  );
32766
- const isActiveAgentProviderReady = useMemo10(() => {
33381
+ const isActiveAgentProviderReady = useMemo11(() => {
32767
33382
  const managedAgent = getAgentHostManagedToolchainAgentByName(
32768
33383
  activeReadinessProvider
32769
33384
  );
@@ -32778,14 +33393,14 @@ var AgentGUINode = memo3(function AgentGUINode2({
32778
33393
  managedAgentsState
32779
33394
  ) === "installed";
32780
33395
  }, [activeReadinessProvider, managedAgentsState]);
32781
- const runtimeSlashStatusQuotas = useMemo10(
33396
+ const runtimeSlashStatusQuotas = useMemo11(
32782
33397
  () => slashStatusQuotasFromRuntimeUsage(
32783
33398
  viewModel.sessionChrome.rawState?.runtimeContext?.usage
32784
33399
  ),
32785
33400
  [viewModel.sessionChrome.rawState?.runtimeContext?.usage]
32786
33401
  );
32787
33402
  const slashStatusQuotaSource = activeAgentProbe?.usage?.quotas && activeAgentProbe.usage.quotas.length > 0 ? activeAgentProbe.usage.quotas : runtimeSlashStatusQuotas;
32788
- const slashStatusLimits = useMemo10(
33403
+ const slashStatusLimits = useMemo11(
32789
33404
  () => slashStatusLimitsFromQuotas(
32790
33405
  slashStatusQuotaSource,
32791
33406
  viewModel.composerSettings.selectedModelValue ?? viewModel.composerSettings.draftSettings.model,
@@ -32799,7 +33414,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32799
33414
  ]
32800
33415
  );
32801
33416
  const railSlashStatusQuotaSource = railStatusProvider && railAgentProbe?.usage?.quotas && railAgentProbe.usage.quotas.length > 0 ? railAgentProbe.usage.quotas : [];
32802
- const railSlashStatusLimits = useMemo10(
33417
+ const railSlashStatusLimits = useMemo11(
32803
33418
  () => slashStatusLimitsFromQuotas(railSlashStatusQuotaSource, null, t),
32804
33419
  [railSlashStatusQuotaSource, t]
32805
33420
  );
@@ -32807,7 +33422,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32807
33422
  const slashStatusUsageCapturedAtUnixMs = slashStatusUsageProbe?.usage?.capturedAtUnixMs ?? null;
32808
33423
  const slashStatusUsageDidFail = workspaceAgentProbes?.usageLoadFailed ?? false;
32809
33424
  const slashStatusUsageAttempted = Boolean(slashStatusUsageProbe?.usage) || Boolean(slashStatusUsageProbe?.lastError);
32810
- const agentProbeLines = useMemo10(() => {
33425
+ const agentProbeLines = useMemo11(() => {
32811
33426
  return buildDockAgentProbeTooltipLines(
32812
33427
  activeAgentProbe,
32813
33428
  workspaceAgentProbes?.isLoadingAvailability ?? false,
@@ -32823,7 +33438,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32823
33438
  workspaceAgentProbes?.isLoadingUsage,
32824
33439
  t
32825
33440
  ]);
32826
- useEffect16(() => {
33441
+ useEffect17(() => {
32827
33442
  if (previewMode || !onAgentProbeDemandChange) {
32828
33443
  return;
32829
33444
  }
@@ -32833,7 +33448,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32833
33448
  onAgentProbeDemandChange(null, probeSourceId);
32834
33449
  };
32835
33450
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
32836
- useEffect16(() => {
33451
+ useEffect17(() => {
32837
33452
  if (previewMode || !onAgentProbeDemandChange || !railStatusProvider || railStatusProvider === activeProbeProvider) {
32838
33453
  return;
32839
33454
  }
@@ -32951,6 +33566,7 @@ var AgentGUINode = memo3(function AgentGUINode2({
32951
33566
  renderSidebarFooter,
32952
33567
  renderProviderRailEmpty,
32953
33568
  renderProviderUnavailableState,
33569
+ renderProviderReadinessGateState,
32954
33570
  providerRailAllPresentation,
32955
33571
  actions: viewActions,
32956
33572
  isActive,
@@ -33044,6 +33660,7 @@ export {
33044
33660
  AgentGUI,
33045
33661
  AgentGuiI18nProvider,
33046
33662
  AgentQueuedPromptRuntimeProvider,
33663
+ agentActivityRuntimeCapabilityEnabled,
33047
33664
  agentGUIDefaultTargetProviders,
33048
33665
  agentGuiDockIconUrl,
33049
33666
  agentGuiDockIconUrls,