@tutti-os/agent-gui 0.0.53 → 0.0.55

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 (79) hide show
  1. package/dist/{AgentMentionSearchController-CExFPobz.d.ts → AgentMentionSearchController-DzhWr0PN.d.ts} +13 -3
  2. package/dist/agent-conversation/index.d.ts +2 -2
  3. package/dist/agent-conversation/index.js +7 -6
  4. package/dist/agent-conversation/index.js.map +1 -1
  5. package/dist/agent-message-center/index.js +15 -12
  6. package/dist/agent-message-center/index.js.map +1 -1
  7. package/dist/{agentGuiNodeTypes-wzOITHRW.d.ts → agentGuiNodeTypes-DCnsaqJr.d.ts} +16 -2
  8. package/dist/app/renderer/agentactivity.css +157 -6
  9. package/dist/{chunk-ZTSS2NU2.js → chunk-2XVECUTU.js} +25 -1
  10. package/dist/chunk-2XVECUTU.js.map +1 -0
  11. package/dist/{chunk-OBFDA7RG.js → chunk-4PSDYKZQ.js} +20 -3
  12. package/dist/chunk-4PSDYKZQ.js.map +1 -0
  13. package/dist/{chunk-BFIYBPFD.js → chunk-6AXH2BOD.js} +5 -5
  14. package/dist/{chunk-4K22O34C.js → chunk-7GM7UQXD.js} +29 -3
  15. package/dist/chunk-7GM7UQXD.js.map +1 -0
  16. package/dist/{chunk-2OLYX32K.js → chunk-7H4IH67L.js} +76 -7
  17. package/dist/chunk-7H4IH67L.js.map +1 -0
  18. package/dist/{chunk-FYVVHRLZ.js → chunk-BGZ2OSDQ.js} +2 -2
  19. package/dist/{chunk-DPG2J7N5.js → chunk-CMOGPJ23.js} +2 -2
  20. package/dist/{chunk-3ZVVFQH5.js → chunk-GBAQVKQN.js} +180 -88
  21. package/dist/chunk-GBAQVKQN.js.map +1 -0
  22. package/dist/{chunk-66EQ6EQO.js → chunk-GL54NRMB.js} +59 -2
  23. package/dist/chunk-GL54NRMB.js.map +1 -0
  24. package/dist/{chunk-Y7ZVTWMZ.js → chunk-H2YWXFYX.js} +2 -2
  25. package/dist/{chunk-UKDC63WG.js → chunk-NBTJEF3H.js} +81 -4
  26. package/dist/chunk-NBTJEF3H.js.map +1 -0
  27. package/dist/{chunk-EFDGMXTB.js → chunk-OQJSZSYB.js} +48 -48
  28. package/dist/chunk-OQJSZSYB.js.map +1 -0
  29. package/dist/{chunk-GWHPTB4L.js → chunk-PBHTLI3E.js} +2 -2
  30. package/dist/{chunk-GWHPTB4L.js.map → chunk-PBHTLI3E.js.map} +1 -1
  31. package/dist/{chunk-5Y3PC7HP.js → chunk-VOXUYDQF.js} +238 -25
  32. package/dist/chunk-VOXUYDQF.js.map +1 -0
  33. package/dist/{chunk-HDBKB5RA.js → chunk-WMQN7SZC.js} +2 -58
  34. package/dist/chunk-WMQN7SZC.js.map +1 -0
  35. package/dist/{chunk-F5DYXCY3.js → chunk-Z2BTIAOC.js} +1 -1
  36. package/dist/chunk-Z2BTIAOC.js.map +1 -0
  37. package/dist/{chunk-PIKG746A.js → chunk-ZFDO72FE.js} +132 -67
  38. package/dist/chunk-ZFDO72FE.js.map +1 -0
  39. package/dist/context-mention-palette/index.d.ts +2 -2
  40. package/dist/context-mention-palette/index.js +8 -8
  41. package/dist/context-mention-provider.d.ts +1 -0
  42. package/dist/i18n/index.d.ts +24 -0
  43. package/dist/i18n/index.js +2 -2
  44. package/dist/index.d.ts +21 -53
  45. package/dist/index.js +1256 -679
  46. package/dist/index.js.map +1 -1
  47. package/dist/queued-prompt-runtime.d.ts +2 -2
  48. package/dist/{types-xMz0lJWt.d.ts → types-B2m7UcBb.d.ts} +8 -0
  49. package/dist/workbench/contribution.d.ts +43 -4
  50. package/dist/workbench/contribution.js +9 -5
  51. package/dist/workbench/index.d.ts +3 -3
  52. package/dist/workbench/index.js +18 -8
  53. package/dist/workbench/launch.d.ts +2 -1
  54. package/dist/workbench/launch.js +2 -2
  55. package/dist/workbench/providerCatalog.d.ts +1 -1
  56. package/dist/workbench/sessionTitle.d.ts +1 -1
  57. package/dist/workbench/sessionTitle.js +3 -3
  58. package/dist/workbench/state.d.ts +1 -1
  59. package/dist/workbench/state.js +2 -2
  60. package/dist/workbench/types.d.ts +8 -8
  61. package/dist/workbench/types.js +1 -1
  62. package/dist/workspace-agent-generated-files.js +3 -3
  63. package/package.json +14 -14
  64. package/dist/chunk-2OLYX32K.js.map +0 -1
  65. package/dist/chunk-3ZVVFQH5.js.map +0 -1
  66. package/dist/chunk-4K22O34C.js.map +0 -1
  67. package/dist/chunk-5Y3PC7HP.js.map +0 -1
  68. package/dist/chunk-66EQ6EQO.js.map +0 -1
  69. package/dist/chunk-EFDGMXTB.js.map +0 -1
  70. package/dist/chunk-F5DYXCY3.js.map +0 -1
  71. package/dist/chunk-HDBKB5RA.js.map +0 -1
  72. package/dist/chunk-OBFDA7RG.js.map +0 -1
  73. package/dist/chunk-PIKG746A.js.map +0 -1
  74. package/dist/chunk-UKDC63WG.js.map +0 -1
  75. package/dist/chunk-ZTSS2NU2.js.map +0 -1
  76. /package/dist/{chunk-BFIYBPFD.js.map → chunk-6AXH2BOD.js.map} +0 -0
  77. /package/dist/{chunk-FYVVHRLZ.js.map → chunk-BGZ2OSDQ.js.map} +0 -0
  78. /package/dist/{chunk-DPG2J7N5.js.map → chunk-CMOGPJ23.js.map} +0 -0
  79. /package/dist/{chunk-Y7ZVTWMZ.js.map → chunk-H2YWXFYX.js.map} +0 -0
package/dist/index.js CHANGED
@@ -18,11 +18,11 @@ import {
18
18
  localAgentGUIProviderTargetId,
19
19
  normalizeAgentGUIProviderTargets,
20
20
  resolveAgentGUIProviderTarget
21
- } from "./chunk-4K22O34C.js";
21
+ } from "./chunk-7GM7UQXD.js";
22
22
  import {
23
23
  AgentInteractivePromptSurface,
24
24
  approvalOptionDisplayLabel
25
- } from "./chunk-BFIYBPFD.js";
25
+ } from "./chunk-6AXH2BOD.js";
26
26
  import {
27
27
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
28
28
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -41,7 +41,7 @@ import {
41
41
  resolveAgentGUIExplicitConversationTitle,
42
42
  resolveAgentGUIProviderDisplayLabel,
43
43
  resolveAgentGUIProviderIdentity
44
- } from "./chunk-DPG2J7N5.js";
44
+ } from "./chunk-CMOGPJ23.js";
45
45
  import {
46
46
  AgentConversationFlow,
47
47
  Button,
@@ -63,13 +63,14 @@ import {
63
63
  skillTriggerForPrefix,
64
64
  toLocalShortDateTime,
65
65
  useProjectedAgentConversation
66
- } from "./chunk-3ZVVFQH5.js";
66
+ } from "./chunk-GBAQVKQN.js";
67
67
  import {
68
68
  AgentMessageMarkdown,
69
+ AgentTargetPresentationProvider,
69
70
  ZoomableImage,
70
71
  cn,
71
72
  resolveWorkspaceLinkAction
72
- } from "./chunk-PIKG746A.js";
73
+ } from "./chunk-ZFDO72FE.js";
73
74
  import {
74
75
  AGENT_MENTION_FILTER_TAB_ORDER,
75
76
  AgentFileMentionPalette,
@@ -77,7 +78,7 @@ import {
77
78
  DEFAULT_AGENT_MENTION_FILTER,
78
79
  agentMentionItemKey,
79
80
  preloadAgentMentionBrowse
80
- } from "./chunk-2OLYX32K.js";
81
+ } from "./chunk-7H4IH67L.js";
81
82
  import {
82
83
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
83
84
  buildWorkspaceAgentActivityListViewModel,
@@ -87,17 +88,13 @@ import {
87
88
  isWorkspaceAgentUntitledTask,
88
89
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
89
90
  selectWorkspaceAgentActivityOverlayMessages
90
- } from "./chunk-GWHPTB4L.js";
91
+ } from "./chunk-PBHTLI3E.js";
91
92
  import {
92
- MANAGED_AGENT_ICON_FALLBACK_URL,
93
- MANAGED_AGENT_ICON_URLS,
94
- Spinner,
95
- normalizeManagedAgentProvider
96
- } from "./chunk-HDBKB5RA.js";
93
+ Spinner
94
+ } from "./chunk-WMQN7SZC.js";
97
95
  import {
98
96
  resolveWorkspaceAgentSessionSortTimeUnixMs
99
97
  } from "./chunk-IBIMGLCD.js";
100
- import "./chunk-MTFSQWZ6.js";
101
98
  import {
102
99
  AGENT_RICH_TEXT_CARET_ANCHOR,
103
100
  exitAgentFileMentionSuggestion,
@@ -105,15 +102,18 @@ import {
105
102
  mentionItemToAttrs,
106
103
  normalizeAgentSessionMentionTitle,
107
104
  parseMentionItemFromHref
108
- } from "./chunk-UKDC63WG.js";
105
+ } from "./chunk-NBTJEF3H.js";
109
106
  import "./chunk-Y35GDLP2.js";
110
107
  import "./chunk-LUGELG5V.js";
111
108
  import {
112
109
  AgentActivityHostProvider,
113
110
  AgentActivityRuntimeProvider,
111
+ MANAGED_AGENT_ICON_FALLBACK_URL,
112
+ MANAGED_AGENT_ICON_URLS,
114
113
  getAgentActivityRuntime,
115
114
  getOptionalAgentActivityRuntime,
116
115
  getOptionalAgentHostApi,
116
+ normalizeManagedAgentProvider,
117
117
  resetAgentActivityRuntimeForTests,
118
118
  setAgentActivityRuntimeForTests,
119
119
  useAgentActivityRuntime,
@@ -121,9 +121,10 @@ import {
121
121
  useAgentHostApi,
122
122
  useOptionalAgentActivityRuntime,
123
123
  useOptionalAgentHostApi
124
- } from "./chunk-66EQ6EQO.js";
124
+ } from "./chunk-GL54NRMB.js";
125
125
  import "./chunk-TYGL25EL.js";
126
126
  import "./chunk-PJP5BUU6.js";
127
+ import "./chunk-MTFSQWZ6.js";
127
128
  import {
128
129
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
129
130
  } from "./chunk-JM24HADP.js";
@@ -137,8 +138,8 @@ import {
137
138
  agentGuiI18nResources,
138
139
  translate,
139
140
  useTranslation
140
- } from "./chunk-Y7ZVTWMZ.js";
141
- import "./chunk-ZTSS2NU2.js";
141
+ } from "./chunk-H2YWXFYX.js";
142
+ import "./chunk-2XVECUTU.js";
142
143
 
143
144
  // shared/agentActivitySnapshotProjection.ts
144
145
  import {
@@ -2338,6 +2339,35 @@ var DEFAULT_AGENT_SETTINGS = {
2338
2339
  hideWorktreeMismatchDropWarning: false
2339
2340
  };
2340
2341
 
2342
+ // agent-gui/agentGuiNode/model/agentGuiConversationFilter.ts
2343
+ function createAgentGUIConversationFilterState(filter = { kind: "all" }) {
2344
+ return {
2345
+ filter: normalizeAgentGUIConversationFilter(filter)
2346
+ };
2347
+ }
2348
+ function normalizeAgentGUIConversationFilter(filter) {
2349
+ if (filter?.kind === "agentTarget") {
2350
+ const agentTargetId = filter.agentTargetId?.trim() ?? "";
2351
+ return agentTargetId ? { kind: "agentTarget", agentTargetId } : { kind: "all" };
2352
+ }
2353
+ return { kind: "all" };
2354
+ }
2355
+ function filterAgentGUIConversationSummaries(conversations, filter) {
2356
+ const normalizedFilter = normalizeAgentGUIConversationFilter(filter);
2357
+ return conversations.filter(
2358
+ (conversation) => matchesAgentGUIConversationFilterAgentTarget(
2359
+ conversation.agentTargetId,
2360
+ normalizedFilter
2361
+ )
2362
+ );
2363
+ }
2364
+ function matchesAgentGUIConversationFilterAgentTarget(agentTargetId, filter) {
2365
+ if (filter.kind === "all") {
2366
+ return true;
2367
+ }
2368
+ return (agentTargetId?.trim() ?? "") === filter.agentTargetId;
2369
+ }
2370
+
2341
2371
  // agent-gui/agentGuiNode/model/agentGuiConversationProjectResolver.ts
2342
2372
  import { resolveWorkspaceUserProjectDisplayLabel } from "@tutti-os/workspace-user-project/core";
2343
2373
  var AGENT_GUI_CONVERSATION_PROJECT_SUMMARY_CACHE_LIMIT = 512;
@@ -2470,6 +2500,7 @@ function resolveAgentGUIConversationSortTimeUnixMs(conversation) {
2470
2500
  return conversation.sortTimeUnixMs ?? conversation.updatedAtUnixMs;
2471
2501
  }
2472
2502
  function buildAgentGUIConversationSummaries({
2503
+ conversationFilter,
2473
2504
  isNoProjectPath,
2474
2505
  snapshot: snapshot3,
2475
2506
  provider,
@@ -2484,15 +2515,25 @@ function buildAgentGUIConversationSummaries({
2484
2515
  userProjects,
2485
2516
  { isNoProjectPath }
2486
2517
  );
2487
- return buildWorkspaceAgentActivityListViewModel(runtimeSnapshot, {
2488
- sessionMessagesById
2489
- }).activities.map(
2518
+ const conversations = buildWorkspaceAgentActivityListViewModel(
2519
+ runtimeSnapshot,
2520
+ {
2521
+ sessionMessagesById
2522
+ }
2523
+ ).activities.map(
2490
2524
  (activity) => conversationSummaryFromActivity(
2491
2525
  activity,
2492
2526
  sessionsById.get(activity.sessionId),
2493
2527
  { projectResolver }
2494
2528
  )
2495
- ).filter(
2529
+ );
2530
+ if (conversationFilter) {
2531
+ return filterAgentGUIConversationSummaries(
2532
+ conversations,
2533
+ normalizeAgentGUIConversationFilter(conversationFilter)
2534
+ );
2535
+ }
2536
+ return conversations.filter(
2496
2537
  (conversation) => conversation.provider === provider || conversation.provider === "unknown"
2497
2538
  );
2498
2539
  }
@@ -2588,6 +2629,7 @@ function conversationSummaryFromAgentSession(session, options = {}) {
2588
2629
  return {
2589
2630
  id: session.agentSessionId.trim(),
2590
2631
  userId: "",
2632
+ agentTargetId: session.agentTargetId ?? null,
2591
2633
  provider,
2592
2634
  resumable: session.resumable,
2593
2635
  title,
@@ -2684,6 +2726,7 @@ function conversationSummaryFromActivity(activity, session, options) {
2684
2726
  return {
2685
2727
  id: activity.sessionId,
2686
2728
  userId: session?.userId?.trim() ?? "",
2729
+ agentTargetId: session?.agentTargetId ?? null,
2687
2730
  provider,
2688
2731
  resumable: session?.resumable,
2689
2732
  title,
@@ -2768,6 +2811,7 @@ function timelineSessionFromItems(timelineItems, conversation) {
2768
2811
  cwd: conversation?.cwd?.trim() ?? "",
2769
2812
  lifecycleStatus: sessionLifecycleStatus(conversation?.status ?? "ready"),
2770
2813
  turnPhase: conversation?.status === "working" ? "working" : "idle",
2814
+ turnLifecycle: conversation?.turnLifecycle ?? null,
2771
2815
  effectiveStatus: conversation?.status ?? "ready",
2772
2816
  status: conversation?.status ?? "ready",
2773
2817
  title: conversation?.title,
@@ -3377,6 +3421,7 @@ function projectWorkspaceAgentMessagesToTimelineItems(messages) {
3377
3421
  ...message.status?.trim() ? { status: message.status.trim() } : {}
3378
3422
  });
3379
3423
  mergedToolPayloadByKey.set(toolKey, mergedPayload);
3424
+ const callType = firstNonEmptyString(stringValue(mergedPayload.callType)) || "tool";
3380
3425
  const workspaceId = workspaceIdFromMessage(message);
3381
3426
  return {
3382
3427
  id,
@@ -3389,7 +3434,7 @@ function projectWorkspaceAgentMessagesToTimelineItems(messages) {
3389
3434
  actorId: message.agentSessionId,
3390
3435
  itemType: toolCallItemType(message.status ?? void 0),
3391
3436
  role: "assistant",
3392
- callType: "tool",
3437
+ callType,
3393
3438
  callId,
3394
3439
  name: firstNonEmptyString(toolName, titleToolName) || "Tool",
3395
3440
  ...message.status !== void 0 ? { status: message.status } : {},
@@ -4830,20 +4875,43 @@ function normalizeQuery(input) {
4830
4875
  return null;
4831
4876
  }
4832
4877
  return {
4878
+ conversationFilter: normalizeAgentGUIConversationListFilter(input),
4833
4879
  workspaceId,
4834
4880
  userId,
4835
4881
  provider,
4836
4882
  sessionOrigin
4837
4883
  };
4838
4884
  }
4885
+ function normalizeAgentGUIConversationListFilter(input) {
4886
+ if (input.conversationFilter) {
4887
+ return normalizeAgentGUIConversationFilter(input.conversationFilter);
4888
+ }
4889
+ return null;
4890
+ }
4891
+ function conversationFilterKey(filter, provider) {
4892
+ if (!filter) {
4893
+ return `legacy-provider:${provider}`;
4894
+ }
4895
+ const normalized = normalizeAgentGUIConversationFilter(filter);
4896
+ if (normalized.kind === "all") {
4897
+ return "all";
4898
+ }
4899
+ return `agent-target:${normalized.agentTargetId}`;
4900
+ }
4839
4901
  function createAgentGUIConversationListQueryKey(input) {
4840
4902
  const normalized = normalizeQuery(input);
4841
- return normalized ? [
4903
+ if (!normalized) {
4904
+ return null;
4905
+ }
4906
+ const providerScope = normalized.conversationFilter ? "conversation-filter" : normalized.provider;
4907
+ const queryKey = [
4842
4908
  normalized.workspaceId,
4843
4909
  normalized.userId,
4844
- normalized.provider,
4910
+ providerScope,
4911
+ conversationFilterKey(normalized.conversationFilter, normalized.provider),
4845
4912
  normalized.sessionOrigin
4846
- ].join("::") : null;
4913
+ ].join("::");
4914
+ return queryKey;
4847
4915
  }
4848
4916
  function createEmptyQueryState(query) {
4849
4917
  const normalized = normalizeQuery(query);
@@ -5531,6 +5599,9 @@ function getWorkspaceAgentSnapshotForConversations(input) {
5531
5599
  const snapshot3 = getAgentActivityRuntime().getSnapshot(input.workspaceId);
5532
5600
  return workspaceAgentSnapshotForConversations(snapshot3);
5533
5601
  }
5602
+ function shouldUseCurrentWorkspaceAgentSnapshotForRefresh(reason) {
5603
+ return reason === "workspace-agent-update" || reason === "session-overlay-update";
5604
+ }
5534
5605
  async function refreshAgentGUIConversationListQuery(query, reason, options = {}) {
5535
5606
  const state = ensureQueryState(query);
5536
5607
  if (!state) {
@@ -5558,7 +5629,9 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5558
5629
  sessionOrigin: state.query.sessionOrigin,
5559
5630
  userId: state.query.userId
5560
5631
  };
5561
- const workspaceAgentSnapshot = reason === "workspace-agent-update" || reason === "session-overlay-update" ? getWorkspaceAgentSnapshotForConversations(workspaceAgentsInput) : await loadWorkspaceAgentSnapshotForConversations(
5632
+ const currentWorkspaceAgentSnapshot = getWorkspaceAgentSnapshotForConversations(workspaceAgentsInput);
5633
+ const canProjectExplicitFilterFromCurrentSnapshot = reason === "projection-sync" && state.query.conversationFilter !== null && currentWorkspaceAgentSnapshot.sessions.length > 0;
5634
+ const workspaceAgentSnapshot = shouldUseCurrentWorkspaceAgentSnapshotForRefresh(reason) || canProjectExplicitFilterFromCurrentSnapshot ? currentWorkspaceAgentSnapshot : await loadWorkspaceAgentSnapshotForConversations(
5562
5635
  workspaceAgentsInput
5563
5636
  );
5564
5637
  if (requestId !== requestIdByQueryKey.get(queryKey)) {
@@ -5613,6 +5686,7 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5613
5686
  return agentSessionId && dirtySessionIds.has(agentSessionId) || syncSessionId && dirtySessionIds.has(syncSessionId);
5614
5687
  }) : workspaceAgentSnapshot.sessions;
5615
5688
  const baseConversations = buildAgentGUIConversationSummaries({
5689
+ ...state.query.conversationFilter ? { conversationFilter: state.query.conversationFilter } : {},
5616
5690
  snapshot: canApplyDirtySessionProjection ? {
5617
5691
  ...workspaceAgentSnapshot,
5618
5692
  sessions: projectionSessions
@@ -6171,6 +6245,7 @@ function useAgentGUIActivation({
6171
6245
  mode: input.mode,
6172
6246
  workspaceId,
6173
6247
  agentSessionId,
6248
+ agentTargetId: input.agentTargetId,
6174
6249
  provider: input.provider,
6175
6250
  cwd: input.cwd,
6176
6251
  initialContent: input.initialContent,
@@ -6481,6 +6556,10 @@ function buildNodeDefaultComposerSettings(data, options) {
6481
6556
  };
6482
6557
  }
6483
6558
  function nodeComposerOverridesForProvider(data) {
6559
+ const agentTargetId = normalizeOptionalText(data.agentTargetId);
6560
+ if (agentTargetId) {
6561
+ return data.composerOverridesByAgentTargetId?.[agentTargetId] ?? null;
6562
+ }
6484
6563
  return data.composerOverridesByProvider?.[data.provider] ?? data.composerOverrides ?? null;
6485
6564
  }
6486
6565
  function composerSupportForProvider(provider) {
@@ -6513,6 +6592,16 @@ function nodeDataFromComposerSettings(current, settings) {
6513
6592
  computerUse: settings.computerUse,
6514
6593
  permissionModeId: normalizePermissionModeId(settings.permissionModeId)
6515
6594
  };
6595
+ const agentTargetId = normalizeOptionalText(current.agentTargetId);
6596
+ if (agentTargetId) {
6597
+ return {
6598
+ ...current,
6599
+ composerOverridesByAgentTargetId: {
6600
+ ...current.composerOverridesByAgentTargetId ?? {},
6601
+ [agentTargetId]: composerOverrides
6602
+ }
6603
+ };
6604
+ }
6516
6605
  return {
6517
6606
  ...current,
6518
6607
  composerOverrides,
@@ -6570,6 +6659,103 @@ function composerDefaultsFromSettings(settings) {
6570
6659
  }
6571
6660
  return Object.keys(defaults).length > 0 ? defaults : null;
6572
6661
  }
6662
+ function composerTargetDataFromProviderTarget(input) {
6663
+ const agentTargetId = normalizeOptionalText2(input.target.agentTargetId);
6664
+ const useLegacyProviderTargetRef = !agentTargetId && input.isExplicit;
6665
+ const providerTargetId = useLegacyProviderTargetRef ? input.target.targetId : null;
6666
+ const providerTargetRef = useLegacyProviderTargetRef ? input.target.ref : null;
6667
+ const currentAgentTargetId = normalizeOptionalText2(
6668
+ input.current.agentTargetId
6669
+ );
6670
+ const currentProviderTargetId = normalizeOptionalText2(
6671
+ input.current.providerTargetId
6672
+ );
6673
+ const canPromoteLegacyComposerOverrides = agentTargetId !== null && currentAgentTargetId === null && currentProviderTargetId === null && input.current.providerTargetRef == null && input.current.provider === input.target.provider && input.current.composerOverrides != null && !input.current.composerOverridesByAgentTargetId?.[agentTargetId];
6674
+ const composerOverridesByAgentTargetId = canPromoteLegacyComposerOverrides ? {
6675
+ ...input.current.composerOverridesByAgentTargetId ?? {},
6676
+ [agentTargetId]: input.current.composerOverrides
6677
+ } : input.current.composerOverridesByAgentTargetId;
6678
+ const currentTargetIdentityChanged = input.current.provider !== input.target.provider || currentAgentTargetId !== null && currentAgentTargetId !== agentTargetId || currentProviderTargetId !== null && currentProviderTargetId !== providerTargetId || input.current.providerTargetRef != null && !agentGUIProviderTargetRefsEqual(
6679
+ input.current.providerTargetRef,
6680
+ providerTargetRef
6681
+ );
6682
+ return {
6683
+ agentTargetId,
6684
+ provider: input.target.provider,
6685
+ providerTargetId,
6686
+ providerTargetRef,
6687
+ targetId: input.target.targetId,
6688
+ data: {
6689
+ ...input.current,
6690
+ provider: input.target.provider,
6691
+ agentTargetId,
6692
+ providerTargetId,
6693
+ providerTargetRef,
6694
+ composerOverrides: canPromoteLegacyComposerOverrides ? null : currentTargetIdentityChanged ? null : input.current.composerOverrides,
6695
+ composerOverridesByAgentTargetId
6696
+ }
6697
+ };
6698
+ }
6699
+ function composerTargetDataFromNodeData(data) {
6700
+ const agentTargetId = normalizeOptionalText2(data.agentTargetId);
6701
+ const providerTargetId = data.providerTargetId ?? null;
6702
+ return {
6703
+ agentTargetId,
6704
+ provider: data.provider,
6705
+ providerTargetId,
6706
+ providerTargetRef: data.providerTargetRef ?? null,
6707
+ targetId: agentTargetId ?? providerTargetId ?? `local:${data.provider}`,
6708
+ data
6709
+ };
6710
+ }
6711
+ function agentGUINodeDataHasComposerTarget(data) {
6712
+ return normalizeOptionalText2(data.agentTargetId) !== null || normalizeOptionalText2(data.providerTargetId) !== null || data.providerTargetRef != null;
6713
+ }
6714
+ function composerOptionsForTarget(input) {
6715
+ if (input.target.agentTargetId) {
6716
+ const targetOptions = input.snapshot.composerOptionsByAgentTargetId?.[input.target.agentTargetId] ?? null;
6717
+ if (targetOptions) {
6718
+ return targetOptions;
6719
+ }
6720
+ return null;
6721
+ }
6722
+ return input.snapshot.composerOptionsByProvider?.[input.target.provider] ?? null;
6723
+ }
6724
+ function composerOptionValues(options) {
6725
+ return new Set(options.map((option) => option.value));
6726
+ }
6727
+ function sanitizeComposerSettingsForOptions(settings, options) {
6728
+ if (!options) {
6729
+ return settings;
6730
+ }
6731
+ const modelValues = composerOptionValues(options.models);
6732
+ const reasoningValues = composerOptionValues(options.reasoningEfforts);
6733
+ const speedValues = composerOptionValues(options.speeds ?? []);
6734
+ const permissionValues = new Set(
6735
+ options.permissionConfig?.modes.map((mode) => mode.id) ?? []
6736
+ );
6737
+ const model = normalizeOptionalText2(settings.model);
6738
+ const reasoningEffort = normalizeOptionalText2(settings.reasoningEffort);
6739
+ const speed = normalizeOptionalText2(settings.speed);
6740
+ const permissionModeId = normalizePermissionModeId(settings.permissionModeId);
6741
+ const modelOptionsAreAuthoritative = options.provider === "claude-code";
6742
+ return {
6743
+ ...settings,
6744
+ model: modelOptionsAreAuthoritative && model && modelValues.size > 0 && !modelValues.has(model) ? null : model,
6745
+ reasoningEffort: reasoningEffort && reasoningValues.size > 0 && !reasoningValues.has(reasoningEffort) ? null : reasoningEffort,
6746
+ speed: speed && speedValues.size > 0 && !speedValues.has(speed) ? null : speed,
6747
+ permissionModeId: permissionModeId && permissionValues.size > 0 && !permissionValues.has(permissionModeId) ? null : permissionModeId
6748
+ };
6749
+ }
6750
+ function sanitizeComposerSettingsForTarget(input) {
6751
+ if (!input.target.agentTargetId) {
6752
+ return input.settings;
6753
+ }
6754
+ return sanitizeComposerSettingsForOptions(input.settings, input.options);
6755
+ }
6756
+ function agentGUIProviderTargetsEqual(left, right) {
6757
+ return left.provider === right.provider && left.targetId === right.targetId && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && agentGUIProviderTargetRefsEqual(left.ref, right.ref);
6758
+ }
6573
6759
  function reportAgentGUIRuntimeError(input) {
6574
6760
  const reportDiagnostic = input.runtime.reportDiagnostic;
6575
6761
  if (!reportDiagnostic) {
@@ -7734,6 +7920,41 @@ function normalizeAgentGUIOpenSessionRequest(request) {
7734
7920
  function recordValue2(value) {
7735
7921
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
7736
7922
  }
7923
+ function numberValue(value) {
7924
+ if (typeof value === "number" && Number.isFinite(value)) {
7925
+ return value;
7926
+ }
7927
+ if (typeof value === "string" && value.trim() !== "") {
7928
+ const parsed = Number(value);
7929
+ return Number.isFinite(parsed) ? parsed : null;
7930
+ }
7931
+ return null;
7932
+ }
7933
+ function activeBackgroundAgentCount(runtimeContext) {
7934
+ const backgroundAgents = recordValue2(runtimeContext?.backgroundAgents);
7935
+ if (!backgroundAgents) {
7936
+ return 0;
7937
+ }
7938
+ const items = Array.isArray(backgroundAgents.items) ? backgroundAgents.items : [];
7939
+ if (items.length === 0) {
7940
+ const count = numberValue(backgroundAgents.count);
7941
+ return count === null ? 0 : Math.max(0, Math.floor(count));
7942
+ }
7943
+ return items.filter((item) => {
7944
+ const record = recordValue2(item);
7945
+ if (!record) {
7946
+ return false;
7947
+ }
7948
+ const status = String(record.status ?? "").trim().toLowerCase();
7949
+ return ![
7950
+ "completed",
7951
+ "failed",
7952
+ "cancelled",
7953
+ "canceled",
7954
+ "stopped"
7955
+ ].includes(status);
7956
+ }).length;
7957
+ }
7737
7958
  function appServerStartupMetadata(runtimeContext) {
7738
7959
  return recordValue2(runtimeContext?.appServerStartup);
7739
7960
  }
@@ -8152,20 +8373,30 @@ function areAgentComposerDraftsEqual(left, right) {
8152
8373
  return file.id === other.id && file.name === other.name && file.mimeType === other.mimeType && file.path === other.path && file.hostPath === other.hostPath && file.assetId === other.assetId && file.sizeBytes === other.sizeBytes && file.uploading === other.uploading && file.uploadError === other.uploadError;
8153
8374
  });
8154
8375
  }
8155
- function nodeDefaultDraftKey(agentProvider) {
8376
+ function nodeDefaultDraftKey(agentProvider, agentTargetId) {
8377
+ const normalizedAgentTargetId = normalizeOptionalText2(agentTargetId);
8378
+ if (normalizedAgentTargetId) {
8379
+ return `${NODE_DEFAULT_DRAFT_KEY}:target:${normalizedAgentTargetId}`;
8380
+ }
8156
8381
  return `${NODE_DEFAULT_DRAFT_KEY}:${agentProvider}`;
8157
8382
  }
8158
- function nodeDefaultDraftContentKey(agentProvider) {
8159
- return nodeDefaultDraftKey(agentProvider);
8383
+ function nodeDefaultDraftContentKey(agentProvider, agentTargetId) {
8384
+ return nodeDefaultDraftKey(agentProvider, agentTargetId);
8160
8385
  }
8161
8386
  function normalizeProjectDraftPath(value) {
8162
8387
  const normalized = value?.trim().replaceAll("\\", "/").replace(/\/+$/, "");
8163
8388
  return normalized ? normalized : null;
8164
8389
  }
8165
8390
  function readNodeDefaultDraftContent(input) {
8166
- return input.drafts[nodeDefaultDraftContentKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? EMPTY_AGENT_COMPOSER_DRAFT;
8391
+ return input.drafts[nodeDefaultDraftContentKey(input.data.provider, input.data.agentTargetId)] ?? input.drafts[nodeDefaultDraftContentKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? EMPTY_AGENT_COMPOSER_DRAFT;
8167
8392
  }
8168
8393
  function readNodeDefaultDraftSettings(input) {
8394
+ const agentTargetId = normalizeOptionalText2(input.data.agentTargetId);
8395
+ if (agentTargetId) {
8396
+ return input.drafts[nodeDefaultDraftKey(input.data.provider, agentTargetId)] ?? buildNodeDefaultComposerSettings(input.data, {
8397
+ defaultReasoningEffort: input.defaultReasoningEffort
8398
+ });
8399
+ }
8169
8400
  return input.drafts[nodeDefaultDraftKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? buildNodeDefaultComposerSettings(input.data, {
8170
8401
  defaultReasoningEffort: input.defaultReasoningEffort
8171
8402
  });
@@ -8249,7 +8480,7 @@ function isCompletedOutcomeToken(value) {
8249
8480
  return value?.trim().toLowerCase() === "completed";
8250
8481
  }
8251
8482
  function hasSessionControlStatePatch(patch) {
8252
- return normalizeOptionalText2(patch.permissionModeId) !== null || patch.settings !== void 0 || patch.runtimeContext !== void 0 || patch.submitAvailability !== void 0 || patch.turn?.submitAvailability !== void 0 || patch.turn?.phase !== void 0;
8483
+ return normalizeOptionalText2(patch.permissionModeId) !== null || patch.settings !== void 0 || patch.runtimeContext !== void 0 || patch.submitAvailability !== void 0 || patch.pendingInteractive !== void 0 || patch.turn?.submitAvailability !== void 0 || patch.turn?.phase !== void 0;
8253
8484
  }
8254
8485
  function mergeSessionControlStatePatch(current, patch) {
8255
8486
  if (!current || !hasSessionControlStatePatch(patch)) {
@@ -8313,6 +8544,10 @@ function mergeSessionControlStatePatch(current, patch) {
8313
8544
  next.submitAvailability = submitAvailability;
8314
8545
  changed = true;
8315
8546
  }
8547
+ if (patch.pendingInteractive !== void 0 && !sameJSONValue(current.pendingInteractive ?? null, patch.pendingInteractive)) {
8548
+ next.pendingInteractive = patch.pendingInteractive;
8549
+ changed = true;
8550
+ }
8316
8551
  if (patch.turn?.phase) {
8317
8552
  next.turnLifecycle = {
8318
8553
  activeTurnId: patch.turn.activeTurnId !== void 0 ? patch.turn.activeTurnId : patch.turn.phase === "settled" ? null : patch.turn.turnId,
@@ -8329,6 +8564,9 @@ function mergeSessionControlStatePatch(current, patch) {
8329
8564
  }
8330
8565
  return changed ? next : current;
8331
8566
  }
8567
+ function sameJSONValue(left, right) {
8568
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
8569
+ }
8332
8570
  function conversationStatusFromSessionState(state) {
8333
8571
  if (state.turnLifecycle?.phase) {
8334
8572
  return conversationStatusFromStatePatch({
@@ -8438,7 +8676,9 @@ function useAgentGUINodeController({
8438
8676
  workspacePath,
8439
8677
  avoidGroupingEdits,
8440
8678
  data,
8679
+ conversationScope = "single-provider",
8441
8680
  providerTargets,
8681
+ providerTargetsLoading = false,
8442
8682
  defaultProviderTargetId = null,
8443
8683
  openSessionRequest = null,
8444
8684
  prefillPromptRequest = null,
@@ -8458,23 +8698,37 @@ function useAgentGUINodeController({
8458
8698
  [providerTargets]
8459
8699
  );
8460
8700
  const normalizedProviderTargets = useMemo4(
8461
- () => normalizedExplicitProviderTargets.length > 0 ? normalizedExplicitProviderTargets : normalizeAgentGUIProviderTargets(null),
8462
- [normalizedExplicitProviderTargets]
8701
+ () => providerTargetsLoading ? [] : providerTargets === void 0 ? normalizeAgentGUIProviderTargets(null) : normalizedExplicitProviderTargets,
8702
+ [normalizedExplicitProviderTargets, providerTargets, providerTargetsLoading]
8463
8703
  );
8464
- const selectedProviderTarget = useMemo4(
8465
- () => resolveAgentGUIProviderTarget({
8704
+ const shouldFallbackToLocalProviderTargets = providerTargets === void 0 && !providerTargetsLoading;
8705
+ const selectedProviderTarget = useMemo4(() => {
8706
+ const resolved = resolveAgentGUIProviderTarget({
8707
+ agentTargetId: data.agentTargetId,
8466
8708
  defaultProviderTargetId,
8709
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
8467
8710
  provider: data.provider,
8468
8711
  providerTargetId: data.providerTargetId,
8469
8712
  providerTargets: normalizedProviderTargets
8470
- }),
8471
- [
8472
- data.provider,
8473
- data.providerTargetId,
8474
- defaultProviderTargetId,
8475
- normalizedProviderTargets
8476
- ]
8477
- );
8713
+ });
8714
+ return resolved ?? {
8715
+ targetId: data.agentTargetId ?? "__loading__",
8716
+ provider: data.provider,
8717
+ ref: {
8718
+ kind: "loading",
8719
+ provider: data.provider
8720
+ },
8721
+ label: data.provider,
8722
+ disabled: true
8723
+ };
8724
+ }, [
8725
+ data.agentTargetId,
8726
+ data.provider,
8727
+ data.providerTargetId,
8728
+ defaultProviderTargetId,
8729
+ normalizedProviderTargets,
8730
+ shouldFallbackToLocalProviderTargets
8731
+ ]);
8478
8732
  const selectedProviderTargetIsExplicit = useMemo4(
8479
8733
  () => normalizedExplicitProviderTargets.some(
8480
8734
  (target) => target.provider === selectedProviderTarget.provider && target.targetId === selectedProviderTarget.targetId && agentGUIProviderTargetRefsEqual(
@@ -8484,6 +8738,56 @@ function useAgentGUINodeController({
8484
8738
  ),
8485
8739
  [normalizedExplicitProviderTargets, selectedProviderTarget]
8486
8740
  );
8741
+ const [homeComposerTargetOverride, setHomeComposerTargetOverride] = useState4(null);
8742
+ const homeComposerTargetOverrideIsExplicit = useMemo4(
8743
+ () => homeComposerTargetOverride ? normalizedExplicitProviderTargets.some(
8744
+ (target) => target.provider === homeComposerTargetOverride.provider && target.targetId === homeComposerTargetOverride.targetId && agentGUIProviderTargetRefsEqual(
8745
+ target.ref,
8746
+ homeComposerTargetOverride.ref
8747
+ )
8748
+ ) : false,
8749
+ [homeComposerTargetOverride, normalizedExplicitProviderTargets]
8750
+ );
8751
+ const effectiveSelectedProviderTarget = homeComposerTargetOverride ?? selectedProviderTarget;
8752
+ const effectiveSelectedProviderTargetIsExplicit = homeComposerTargetOverride ? homeComposerTargetOverrideIsExplicit : selectedProviderTargetIsExplicit;
8753
+ const nodeComposerTargetResolvedByProviderTarget = agentGUINodeDataHasComposerTarget(data) && (normalizeOptionalText2(data.agentTargetId) !== null && selectedProviderTarget.agentTargetId === normalizeOptionalText2(data.agentTargetId) || normalizeOptionalText2(data.providerTargetId) !== null && selectedProviderTarget.targetId === normalizeOptionalText2(data.providerTargetId) || data.providerTargetRef != null && agentGUIProviderTargetRefsEqual(
8754
+ selectedProviderTarget.ref,
8755
+ data.providerTargetRef
8756
+ ));
8757
+ const selectedComposerTargetData = useMemo4(
8758
+ () => homeComposerTargetOverride ? composerTargetDataFromProviderTarget({
8759
+ current: data,
8760
+ isExplicit: homeComposerTargetOverrideIsExplicit,
8761
+ target: homeComposerTargetOverride
8762
+ }) : nodeComposerTargetResolvedByProviderTarget ? composerTargetDataFromProviderTarget({
8763
+ current: data,
8764
+ isExplicit: selectedProviderTargetIsExplicit,
8765
+ target: selectedProviderTarget
8766
+ }) : agentGUINodeDataHasComposerTarget(data) ? composerTargetDataFromNodeData(data) : composerTargetDataFromProviderTarget({
8767
+ current: data,
8768
+ isExplicit: selectedProviderTargetIsExplicit,
8769
+ target: selectedProviderTarget
8770
+ }),
8771
+ [
8772
+ data,
8773
+ homeComposerTargetOverride,
8774
+ homeComposerTargetOverrideIsExplicit,
8775
+ nodeComposerTargetResolvedByProviderTarget,
8776
+ selectedProviderTarget,
8777
+ selectedProviderTargetIsExplicit
8778
+ ]
8779
+ );
8780
+ useEffect4(() => {
8781
+ if (!homeComposerTargetOverride) {
8782
+ return;
8783
+ }
8784
+ if (agentGUIProviderTargetsEqual(
8785
+ homeComposerTargetOverride,
8786
+ selectedProviderTarget
8787
+ )) {
8788
+ setHomeComposerTargetOverride(null);
8789
+ }
8790
+ }, [homeComposerTargetOverride, selectedProviderTarget]);
8487
8791
  const agentActivityDisplayStatusesRef = useRef4(null);
8488
8792
  const agentActivityDisplayStatuses = useMemo4(() => {
8489
8793
  const next = selectSessionDisplayStatuses(agentActivitySnapshot);
@@ -8495,6 +8799,17 @@ function useAgentGUINodeController({
8495
8799
  return stable;
8496
8800
  }, [agentActivitySnapshot]);
8497
8801
  const generatedControllerOwnerKey = useId();
8802
+ const [conversationFilter, setConversationFilter] = useState4(
8803
+ () => createAgentGUIConversationFilterState().filter
8804
+ );
8805
+ const canUseConversationTargetFilter = conversationScope === "multi-provider";
8806
+ const queryConversationFilter = canUseConversationTargetFilter ? conversationFilter : null;
8807
+ useEffect4(() => {
8808
+ if (canUseConversationTargetFilter || conversationFilter.kind === "all") {
8809
+ return;
8810
+ }
8811
+ setConversationFilter({ kind: "all" });
8812
+ }, [canUseConversationTargetFilter, conversationFilter]);
8498
8813
  const conversationListQuery = useMemo4(() => {
8499
8814
  const userId = currentUserId?.trim() ?? "";
8500
8815
  const provider = data.provider?.trim() ?? "";
@@ -8502,12 +8817,13 @@ function useAgentGUINodeController({
8502
8817
  return null;
8503
8818
  }
8504
8819
  return {
8820
+ ...queryConversationFilter ? { conversationFilter: queryConversationFilter } : {},
8505
8821
  workspaceId,
8506
8822
  userId,
8507
8823
  provider: data.provider,
8508
8824
  sessionOrigin: AGENT_GUI_RUNTIME_SESSION_ORIGIN
8509
8825
  };
8510
- }, [currentUserId, data.provider, workspaceId]);
8826
+ }, [currentUserId, data.provider, queryConversationFilter, workspaceId]);
8511
8827
  const conversationListState = useAgentGuiConversationList(
8512
8828
  conversationListQuery
8513
8829
  );
@@ -8601,7 +8917,11 @@ function useAgentGUINodeController({
8601
8917
  sessionViewRef(activeConversationId)
8602
8918
  );
8603
8919
  const activeSessionState = activeSessionView?.controlState ?? null;
8604
- const providerComposerOptions = agentActivitySnapshot.composerOptionsByProvider?.[data.provider] ?? null;
8920
+ const composerTargetData = activeConversationId === null ? selectedComposerTargetData : composerTargetDataFromNodeData(data);
8921
+ const providerComposerOptions = composerOptionsForTarget({
8922
+ snapshot: agentActivitySnapshot,
8923
+ target: composerTargetData
8924
+ });
8605
8925
  const resolvedPromptImagesSupported = resolveAgentActivityCapability2(
8606
8926
  "imageInput",
8607
8927
  {
@@ -8615,6 +8935,10 @@ function useAgentGUINodeController({
8615
8935
  sessionRuntimeContext: activeSessionState?.runtimeContext
8616
8936
  });
8617
8937
  const activeSessionRuntimeContext = activeSessionState?.runtimeContext;
8938
+ const backgroundAgentCount = useMemo4(
8939
+ () => activeBackgroundAgentCount(activeSessionRuntimeContext),
8940
+ [activeSessionRuntimeContext]
8941
+ );
8618
8942
  const composerSupport = useMemo4(
8619
8943
  () => composerSettingsSupportFromOptions(
8620
8944
  providerComposerOptions,
@@ -8622,7 +8946,7 @@ function useAgentGUINodeController({
8622
8946
  ),
8623
8947
  [providerComposerOptions, activeSessionRuntimeContext]
8624
8948
  );
8625
- const supports = composerSupportForProvider(data.provider);
8949
+ const supports = composerSupportForProvider(composerTargetData.provider);
8626
8950
  const usage = useMemo4(
8627
8951
  () => resolveAgentActivityUsage({
8628
8952
  sessionRuntimeContext: activeSessionRuntimeContext
@@ -8824,12 +9148,14 @@ function useAgentGUINodeController({
8824
9148
  agentActivitySnapshot
8825
9149
  );
8826
9150
  const dataRef = useRef4(data);
8827
- const selectedProviderTargetRef = useRef4(selectedProviderTarget);
8828
- selectedProviderTargetRef.current = selectedProviderTarget;
9151
+ const selectedProviderTargetRef = useRef4(effectiveSelectedProviderTarget);
9152
+ selectedProviderTargetRef.current = effectiveSelectedProviderTarget;
8829
9153
  const selectedProviderTargetIsExplicitRef = useRef4(
8830
- selectedProviderTargetIsExplicit
9154
+ effectiveSelectedProviderTargetIsExplicit
8831
9155
  );
8832
- selectedProviderTargetIsExplicitRef.current = selectedProviderTargetIsExplicit;
9156
+ selectedProviderTargetIsExplicitRef.current = effectiveSelectedProviderTargetIsExplicit;
9157
+ const selectedComposerTargetDataRef = useRef4(selectedComposerTargetData);
9158
+ selectedComposerTargetDataRef.current = selectedComposerTargetData;
8833
9159
  const draftSettingsBySessionIdRef = useRef4(draftSettingsBySessionId);
8834
9160
  const onDataChangeRef = useRef4(onDataChange);
8835
9161
  const onRememberComposerDefaultsRef = useRef4(onRememberComposerDefaults);
@@ -9062,6 +9388,12 @@ function useAgentGUINodeController({
9062
9388
  useEffect4(() => {
9063
9389
  isComposerHomeRef.current = isComposerHome;
9064
9390
  }, [isComposerHome]);
9391
+ useEffect4(() => {
9392
+ if (activeConversationId === null && isComposerHome) {
9393
+ return;
9394
+ }
9395
+ setHomeComposerTargetOverride(null);
9396
+ }, [activeConversationId, isComposerHome]);
9065
9397
  useEffect4(() => {
9066
9398
  isCreatingConversationRef.current = isCreatingConversation;
9067
9399
  }, [isCreatingConversation]);
@@ -9173,7 +9505,17 @@ function useAgentGUINodeController({
9173
9505
  const previousQuery = previousSnapshot.query;
9174
9506
  const previousQueryKey = previousQuery ? createAgentGUIConversationListQueryKey(previousQuery) : null;
9175
9507
  const nextQueryKey = conversationListQuery ? createAgentGUIConversationListQueryKey(conversationListQuery) : null;
9176
- if (previousQuery && conversationListQuery && previousQueryKey !== nextQueryKey && previousQuery.workspaceId === conversationListQuery.workspaceId && previousQuery.provider === conversationListQuery.provider && previousQuery.sessionOrigin === conversationListQuery.sessionOrigin && previousSnapshot.conversations.length > 0) {
9508
+ const previousHasExplicitFilter = previousQuery?.conversationFilter != null;
9509
+ const nextHasExplicitFilter = conversationListQuery?.conversationFilter != null;
9510
+ const previousFilterKey = previousQuery ? JSON.stringify(
9511
+ normalizeAgentGUIConversationFilter(previousQuery.conversationFilter)
9512
+ ) : "";
9513
+ const nextFilterKey = conversationListQuery ? JSON.stringify(
9514
+ normalizeAgentGUIConversationFilter(
9515
+ conversationListQuery.conversationFilter
9516
+ )
9517
+ ) : "";
9518
+ if (previousQuery && conversationListQuery && previousQueryKey !== nextQueryKey && previousQuery.workspaceId === conversationListQuery.workspaceId && previousQuery.provider === conversationListQuery.provider && previousHasExplicitFilter === nextHasExplicitFilter && previousFilterKey === nextFilterKey && previousQuery.sessionOrigin === conversationListQuery.sessionOrigin && previousSnapshot.conversations.length > 0) {
9177
9519
  ensureAgentGUIConversationListQuery(conversationListQuery);
9178
9520
  seedAgentGUIConversationListConversationsIfEmpty({
9179
9521
  query: conversationListQuery,
@@ -10337,14 +10679,15 @@ function useAgentGUINodeController({
10337
10679
  useEffect4(() => {
10338
10680
  reloadSelectedConversationRef.current = reloadSelectedConversation;
10339
10681
  }, [reloadSelectedConversation]);
10340
- const loadDraftComposerOptions = useCallback4(
10341
- (options) => {
10342
- const provider = dataRef.current.provider;
10682
+ const loadComposerOptionsForTarget = useCallback4(
10683
+ (targetData, options) => {
10684
+ const provider = targetData.provider;
10685
+ const agentTargetId = targetData.agentTargetId;
10343
10686
  if (isCreatingConversationRef.current) {
10344
10687
  return;
10345
10688
  }
10346
10689
  const settings = readNodeDefaultDraftSettings({
10347
- data: dataRef.current,
10690
+ data: targetData.data,
10348
10691
  defaultReasoningEffort,
10349
10692
  drafts: draftSettingsBySessionIdRef.current
10350
10693
  });
@@ -10355,12 +10698,20 @@ function useAgentGUINodeController({
10355
10698
  cwd: composerOptionsCwd,
10356
10699
  force: options?.force,
10357
10700
  provider,
10701
+ agentTargetId,
10358
10702
  settings
10359
10703
  })
10360
10704
  ).catch(() => void 0);
10361
10705
  },
10362
10706
  [agentActivityRuntime, defaultReasoningEffort, workspaceId, workspacePath]
10363
10707
  );
10708
+ const loadDraftComposerOptions = useCallback4(
10709
+ (options) => {
10710
+ const targetData = activeConversationIdRef.current === null ? selectedComposerTargetDataRef.current : composerTargetDataFromNodeData(dataRef.current);
10711
+ loadComposerOptionsForTarget(targetData, options);
10712
+ },
10713
+ [loadComposerOptionsForTarget]
10714
+ );
10364
10715
  useEffect4(() => {
10365
10716
  if (previewMode) {
10366
10717
  return;
@@ -10368,7 +10719,7 @@ function useAgentGUINodeController({
10368
10719
  if (!supports.model && !supports.reasoning && !supports.permission) {
10369
10720
  return;
10370
10721
  }
10371
- const projectKey = `${data.provider}\0${selectedProjectPath ?? ""}`;
10722
+ const projectKey = `${composerTargetData.agentTargetId ?? composerTargetData.provider}\0${selectedProjectPath ?? ""}`;
10372
10723
  const previousProjectKey = composerOptionsProjectKeyRef.current;
10373
10724
  composerOptionsProjectKeyRef.current = projectKey;
10374
10725
  if (previousProjectKey === null || previousProjectKey === projectKey) {
@@ -10376,7 +10727,8 @@ function useAgentGUINodeController({
10376
10727
  }
10377
10728
  loadDraftComposerOptions({ force: true });
10378
10729
  }, [
10379
- data.provider,
10730
+ composerTargetData.agentTargetId,
10731
+ composerTargetData.provider,
10380
10732
  loadDraftComposerOptions,
10381
10733
  previewMode,
10382
10734
  selectedProjectPath,
@@ -10399,7 +10751,7 @@ function useAgentGUINodeController({
10399
10751
  merge: mergeAgentModelCatalogInvalidationEvents
10400
10752
  },
10401
10753
  (event) => {
10402
- const provider = dataRef.current.provider;
10754
+ const provider = activeConversationIdRef.current === null ? selectedComposerTargetDataRef.current.provider : dataRef.current.provider;
10403
10755
  const currentActiveConversationId = activeConversationIdRef.current;
10404
10756
  if (!event.providers.includes(provider)) {
10405
10757
  return;
@@ -10431,11 +10783,12 @@ function useAgentGUINodeController({
10431
10783
  return;
10432
10784
  }
10433
10785
  loadDraftComposerOptions(
10434
- data.provider === "claude-code" && isComposerHome ? { force: true } : void 0
10786
+ composerTargetData.provider === "claude-code" && isComposerHome ? { force: true } : void 0
10435
10787
  );
10436
10788
  }, [
10437
10789
  activeConversationId,
10438
- data.provider,
10790
+ composerTargetData.agentTargetId,
10791
+ composerTargetData.provider,
10439
10792
  isComposerHome,
10440
10793
  loadDraftComposerOptions,
10441
10794
  previewMode
@@ -11028,7 +11381,13 @@ function useAgentGUINodeController({
11028
11381
  const startConversation = useCallback4(
11029
11382
  (initialContentInput, displayPrompt) => {
11030
11383
  const target = selectedProviderTargetRef.current;
11031
- if (isCreatingConversation || target.disabled === true || data.provider === "openclaw" && openclawGateway?.status !== "ready") {
11384
+ const targetData = selectedComposerTargetDataRef.current;
11385
+ if (isCreatingConversation || target.disabled === true || targetData.provider === "openclaw" && openclawGateway?.status !== "ready") {
11386
+ return;
11387
+ }
11388
+ const agentTargetId = targetData.agentTargetId ?? "";
11389
+ if (!agentTargetId && selectedProviderTargetIsExplicitRef.current) {
11390
+ setDetailError(translate("agentHost.agentGui.agentTargetRequired"));
11032
11391
  return;
11033
11392
  }
11034
11393
  const normalizedInitialContent = Array.isArray(initialContentInput) ? normalizeAgentPromptContentBlocks(
@@ -11036,8 +11395,11 @@ function useAgentGUINodeController({
11036
11395
  ) : textPromptContent(normalizeOptionalPrompt(initialContentInput));
11037
11396
  const initialDisplayPrompt = displayPrompt && displayPrompt.trim() ? displayPrompt : void 0;
11038
11397
  const normalizedInitialPrompt = initialDisplayPrompt ?? agentPromptContentDisplayText(normalizedInitialContent);
11039
- const initialConversationTitle = normalizedInitialPrompt || AGENT_PROVIDER_LABEL[data.provider];
11040
- const submittedHomeDraftKey = nodeDefaultDraftContentKey(data.provider);
11398
+ const initialConversationTitle = normalizedInitialPrompt || AGENT_PROVIDER_LABEL[targetData.provider];
11399
+ const submittedHomeDraftKey = nodeDefaultDraftContentKey(
11400
+ targetData.provider,
11401
+ targetData.agentTargetId
11402
+ );
11041
11403
  const submittedHomeDraft = draftBySessionIdRef.current[submittedHomeDraftKey] ?? EMPTY_AGENT_COMPOSER_DRAFT;
11042
11404
  isCreatingConversationRef.current = true;
11043
11405
  setLocalIsCreatingConversation(true);
@@ -11045,29 +11407,39 @@ function useAgentGUINodeController({
11045
11407
  let pendingCreateAgentSessionId = null;
11046
11408
  let pendingOptimisticConversation = null;
11047
11409
  void (async () => {
11048
- const target2 = selectedProviderTargetRef.current;
11049
- const provider = target2.provider;
11050
- const shouldUseProviderTargetRef = selectedProviderTargetIsExplicitRef.current;
11410
+ const provider = targetData.provider;
11411
+ const agentTargetId2 = targetData.agentTargetId ?? "";
11051
11412
  onDataChangeRef.current(
11052
- (current) => current.provider === provider && (current.providerTargetId ?? null) === (shouldUseProviderTargetRef ? target2.targetId : null) && agentGUIProviderTargetRefsEqual(
11413
+ (current) => current.provider === provider && (current.agentTargetId ?? null) === (agentTargetId2 || null) && (current.providerTargetId ?? null) === targetData.providerTargetId && agentGUIProviderTargetRefsEqual(
11053
11414
  current.providerTargetRef,
11054
- shouldUseProviderTargetRef ? target2.ref : null
11415
+ targetData.providerTargetRef
11055
11416
  ) ? current : {
11056
11417
  ...current,
11057
11418
  provider,
11058
- providerTargetId: shouldUseProviderTargetRef ? target2.targetId : null,
11059
- providerTargetRef: shouldUseProviderTargetRef ? target2.ref : null
11419
+ agentTargetId: agentTargetId2 || null,
11420
+ providerTargetId: targetData.providerTargetId,
11421
+ providerTargetRef: targetData.providerTargetRef
11060
11422
  }
11061
11423
  );
11062
- const currentData = dataRef.current.provider === provider ? dataRef.current : data;
11063
11424
  const selectedProjectPath2 = selectedProjectPathRef.current;
11064
11425
  const initialNodeSettings = readNodeDefaultDraftSettings({
11065
- data: currentData,
11426
+ data: targetData.data,
11066
11427
  defaultReasoningEffort,
11067
11428
  drafts: draftSettingsBySessionIdRef.current
11068
11429
  });
11430
+ const snapshotComposerOptions = composerOptionsForTarget({
11431
+ snapshot: agentActivityRuntime.getSnapshot(workspaceId),
11432
+ target: targetData
11433
+ });
11434
+ const targetSafeInitialNodeSettings = sanitizeComposerSettingsForTarget(
11435
+ {
11436
+ settings: initialNodeSettings,
11437
+ target: targetData,
11438
+ options: snapshotComposerOptions
11439
+ }
11440
+ );
11069
11441
  const initialSettings = resolveEffectiveComposerSettings({
11070
- settings: initialNodeSettings
11442
+ settings: targetSafeInitialNodeSettings
11071
11443
  });
11072
11444
  const currentActiveConversationId = activeConversationIdRef.current;
11073
11445
  const currentActiveConversation = currentActiveConversationId ? resolveConversationSummaryById(
@@ -11075,7 +11447,7 @@ function useAgentGUINodeController({
11075
11447
  currentActiveConversationId,
11076
11448
  transientConversationRef.current
11077
11449
  ) : null;
11078
- const inheritedModel = normalizeOptionalText2(initialNodeSettings.model) === null ? resolveSameProviderActiveSessionModel({
11450
+ const inheritedModel = normalizeOptionalText2(targetSafeInitialNodeSettings.model) === null ? resolveSameProviderActiveSessionModel({
11079
11451
  activeProvider: currentActiveConversation?.provider ?? null,
11080
11452
  agentSessionId: currentActiveConversationId,
11081
11453
  provider,
@@ -11086,7 +11458,11 @@ function useAgentGUINodeController({
11086
11458
  lastActiveModelByProviderRef.current[provider]
11087
11459
  ) : null;
11088
11460
  const effectiveInitialSettings = inheritedModel === null ? initialSettings : { ...initialSettings, model: inheritedModel };
11089
- const snapshotComposerOptions = agentActivityRuntime.getSnapshot(workspaceId).composerOptionsByProvider?.[provider] ?? null;
11461
+ const targetSafeEffectiveInitialSettings = sanitizeComposerSettingsForTarget({
11462
+ settings: effectiveInitialSettings,
11463
+ target: targetData,
11464
+ options: snapshotComposerOptions
11465
+ });
11090
11466
  const snapshotDraftAgentSessionId = normalizedInitialContent.length > 0 && provider === "claude-code" ? draftAgentSessionIdFromComposerOptions(snapshotComposerOptions) : null;
11091
11467
  const draftAgentSessionId = snapshotDraftAgentSessionId && !activatedConversationIdsRef.current.has(
11092
11468
  snapshotDraftAgentSessionId
@@ -11149,11 +11525,11 @@ function useAgentGUINodeController({
11149
11525
  startingConversationIdRef.current = agentSessionId;
11150
11526
  draftSettingsBySessionIdRef.current = {
11151
11527
  ...draftSettingsBySessionIdRef.current,
11152
- [agentSessionId]: effectiveInitialSettings
11528
+ [agentSessionId]: targetSafeEffectiveInitialSettings
11153
11529
  };
11154
11530
  setDraftSettingsBySessionId((current) => ({
11155
11531
  ...current,
11156
- [agentSessionId]: effectiveInitialSettings
11532
+ [agentSessionId]: targetSafeEffectiveInitialSettings
11157
11533
  }));
11158
11534
  const optimisticPromptMessage = createOptimisticPromptMessage({
11159
11535
  workspaceId,
@@ -11185,14 +11561,15 @@ function useAgentGUINodeController({
11185
11561
  return activation.activate({
11186
11562
  mode: "new",
11187
11563
  agentSessionId,
11564
+ agentTargetId: agentTargetId2 || null,
11188
11565
  provider,
11189
- providerTargetRef: shouldUseProviderTargetRef ? target2.ref : null,
11566
+ providerTargetRef: targetData.providerTargetRef,
11190
11567
  cwd: selectedProjectPath2 ?? "",
11191
11568
  initialContent: normalizedInitialContent,
11192
11569
  initialDisplayPrompt,
11193
11570
  metadata: agentSubmitTraceMetadata(submitTrace),
11194
11571
  title: initialConversationTitle,
11195
- settings: effectiveInitialSettings,
11572
+ settings: targetSafeEffectiveInitialSettings,
11196
11573
  openclawGatewayReady: provider === "openclaw" ? openclawGateway?.status === "ready" : void 0
11197
11574
  });
11198
11575
  })().then((result) => {
@@ -11515,9 +11892,13 @@ function useAgentGUINodeController({
11515
11892
  setActiveConversationId(null);
11516
11893
  setIsLoadingMessages(false);
11517
11894
  setDetailError(null);
11895
+ const targetData = selectedComposerTargetDataRef.current;
11518
11896
  setDraftBySessionId((current) => ({
11519
11897
  ...current,
11520
- [nodeDefaultDraftContentKey(dataRef.current.provider)]: {
11898
+ [nodeDefaultDraftContentKey(
11899
+ targetData.provider,
11900
+ targetData.agentTargetId
11901
+ )]: {
11521
11902
  ...emptyAgentComposerDraft(),
11522
11903
  prompt: draftPrompt2
11523
11904
  }
@@ -11580,9 +11961,13 @@ function useAgentGUINodeController({
11580
11961
  setActiveConversationId(null);
11581
11962
  setIsLoadingMessages(false);
11582
11963
  setDetailError(null);
11964
+ const targetData = selectedComposerTargetDataRef.current;
11583
11965
  setDraftBySessionId((current) => ({
11584
11966
  ...current,
11585
- [nodeDefaultDraftContentKey(dataRef.current.provider)]: {
11967
+ [nodeDefaultDraftContentKey(
11968
+ targetData.provider,
11969
+ targetData.agentTargetId
11970
+ )]: {
11586
11971
  prompt: nextDraftPrompt,
11587
11972
  images: []
11588
11973
  }
@@ -12374,7 +12759,8 @@ function useAgentGUINodeController({
12374
12759
  }, [activeConversationId]);
12375
12760
  const updateDraftContent = useCallback4((draftContent2) => {
12376
12761
  const agentSessionId = activeConversationIdRef.current;
12377
- const draftKey = agentSessionId ?? nodeDefaultDraftContentKey(dataRef.current.provider);
12762
+ const targetData = selectedComposerTargetDataRef.current;
12763
+ const draftKey = agentSessionId ?? nodeDefaultDraftContentKey(targetData.provider, targetData.agentTargetId);
12378
12764
  draftBySessionIdRef.current = {
12379
12765
  ...draftBySessionIdRef.current,
12380
12766
  [draftKey]: draftContent2
@@ -12472,9 +12858,13 @@ function useAgentGUINodeController({
12472
12858
  };
12473
12859
  const agentSessionId = activeConversationIdRef.current;
12474
12860
  if (!agentSessionId) {
12475
- const defaultDraftKey = nodeDefaultDraftKey(dataRef.current.provider);
12861
+ const targetData = selectedComposerTargetDataRef.current;
12862
+ const defaultDraftKey = nodeDefaultDraftKey(
12863
+ targetData.provider,
12864
+ targetData.agentTargetId
12865
+ );
12476
12866
  const storedDefaults = readNodeDefaultDraftSettings({
12477
- data: dataRef.current,
12867
+ data: targetData.data,
12478
12868
  defaultReasoningEffort,
12479
12869
  drafts: draftSettingsBySessionIdRef.current
12480
12870
  });
@@ -12488,29 +12878,47 @@ function useAgentGUINodeController({
12488
12878
  browserUse: supportedNextSettings.browserUse ?? previousSettings.browserUse,
12489
12879
  computerUse: supportedNextSettings.computerUse ?? previousSettings.computerUse
12490
12880
  };
12881
+ const snapshotComposerOptions = composerOptionsForTarget({
12882
+ snapshot: agentActivityRuntime.getSnapshot(workspaceId),
12883
+ target: targetData
12884
+ });
12885
+ const targetSafeMerged = sanitizeComposerSettingsForTarget({
12886
+ settings: merged,
12887
+ target: targetData,
12888
+ options: snapshotComposerOptions
12889
+ });
12491
12890
  draftSettingsBySessionIdRef.current = {
12492
12891
  ...draftSettingsBySessionIdRef.current,
12493
- [defaultDraftKey]: merged
12892
+ [defaultDraftKey]: targetSafeMerged
12494
12893
  };
12495
12894
  setDraftSettingsBySessionId((current) => ({
12496
12895
  ...current,
12497
- [defaultDraftKey]: merged
12896
+ [defaultDraftKey]: targetSafeMerged
12498
12897
  }));
12499
12898
  onDataChangeRef.current(
12500
- (current) => nodeDataFromComposerSettings(current, merged)
12899
+ (current) => nodeDataFromComposerSettings(
12900
+ {
12901
+ ...current,
12902
+ provider: targetData.provider,
12903
+ agentTargetId: targetData.agentTargetId,
12904
+ providerTargetId: targetData.providerTargetId,
12905
+ providerTargetRef: targetData.providerTargetRef
12906
+ },
12907
+ targetSafeMerged
12908
+ )
12501
12909
  );
12502
12910
  void onRememberComposerDefaultsRef.current?.({
12503
- provider: dataRef.current.provider,
12504
- defaults: composerDefaultsFromSettings(merged)
12911
+ provider: targetData.provider,
12912
+ defaults: composerDefaultsFromSettings(targetSafeMerged)
12505
12913
  });
12506
12914
  void agentActivityRuntime.trackDraftComposerSettingsChange?.({
12507
12915
  workspaceId,
12508
- provider: dataRef.current.provider,
12916
+ provider: targetData.provider,
12509
12917
  previousSettings,
12510
- nextSettings: merged
12918
+ nextSettings: targetSafeMerged
12511
12919
  });
12512
12920
  loadDraftComposerOptions(
12513
- dataRef.current.provider === "claude-code" ? { force: true } : void 0
12921
+ targetData.provider === "claude-code" ? { force: true } : void 0
12514
12922
  );
12515
12923
  return;
12516
12924
  }
@@ -13322,7 +13730,8 @@ function useAgentGUINodeController({
13322
13730
  return null;
13323
13731
  }
13324
13732
  const previous = projectionConversationRef.current;
13325
- 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) {
13733
+ const turnLifecycle = activeSessionState?.agentSessionId === activeConversation.id ? activeSessionState.turnLifecycle ?? null : null;
13734
+ 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)) {
13326
13735
  return previous;
13327
13736
  }
13328
13737
  const next = activeConversation ? {
@@ -13334,7 +13743,8 @@ function useAgentGUINodeController({
13334
13743
  status: activeConversation.status,
13335
13744
  cwd: activeConversation.cwd,
13336
13745
  updatedAtUnixMs: activeConversation.updatedAtUnixMs,
13337
- syncState: activeConversation.syncState
13746
+ syncState: activeConversation.syncState,
13747
+ turnLifecycle
13338
13748
  } : null;
13339
13749
  projectionConversationRef.current = next;
13340
13750
  return next;
@@ -13347,10 +13757,14 @@ function useAgentGUINodeController({
13347
13757
  activeConversation?.status,
13348
13758
  activeConversation?.title,
13349
13759
  activeConversation?.titleFallback,
13350
- activeConversation?.userId
13760
+ activeConversation?.userId,
13761
+ activeSessionState?.agentSessionId,
13762
+ activeSessionState?.turnLifecycle?.activeTurnId,
13763
+ activeSessionState?.turnLifecycle?.phase,
13764
+ activeSessionState?.turnLifecycle?.settling
13351
13765
  ]);
13352
13766
  const draftContent = activeConversationId ? draftBySessionId[activeConversationId] ?? EMPTY_AGENT_COMPOSER_DRAFT : readNodeDefaultDraftContent({
13353
- data,
13767
+ data: selectedComposerTargetData.data,
13354
13768
  drafts: draftBySessionId
13355
13769
  });
13356
13770
  const draftPrompt = draftContent.prompt;
@@ -13512,16 +13926,65 @@ function useAgentGUINodeController({
13512
13926
  );
13513
13927
  const storedNodeDefaultSettings = useStableComposerSettings(
13514
13928
  readNodeDefaultDraftSettings({
13515
- data,
13929
+ data: activeConversationId === null ? selectedComposerTargetData.data : data,
13516
13930
  defaultReasoningEffort,
13517
13931
  drafts: draftSettingsBySessionId
13518
13932
  })
13519
13933
  );
13934
+ const targetSafeNodeDefaultSettings = useStableComposerSettings(
13935
+ activeConversationId === null ? sanitizeComposerSettingsForTarget({
13936
+ settings: storedNodeDefaultSettings,
13937
+ target: selectedComposerTargetData,
13938
+ options: providerComposerOptions
13939
+ }) : storedNodeDefaultSettings
13940
+ );
13520
13941
  const homeComposerSettings = useStableComposerSettings(
13521
13942
  resolveEffectiveComposerSettings({
13522
- settings: storedNodeDefaultSettings
13943
+ settings: targetSafeNodeDefaultSettings
13523
13944
  })
13524
13945
  );
13946
+ useEffect4(() => {
13947
+ if (activeConversationId !== null || !selectedComposerTargetData.agentTargetId || !providerComposerOptions || sameComposerSettings(
13948
+ storedNodeDefaultSettings,
13949
+ targetSafeNodeDefaultSettings
13950
+ )) {
13951
+ return;
13952
+ }
13953
+ const targetDefaultDraftKey = nodeDefaultDraftKey(
13954
+ selectedComposerTargetData.provider,
13955
+ selectedComposerTargetData.agentTargetId
13956
+ );
13957
+ draftSettingsBySessionIdRef.current = {
13958
+ ...draftSettingsBySessionIdRef.current,
13959
+ [targetDefaultDraftKey]: targetSafeNodeDefaultSettings
13960
+ };
13961
+ setDraftSettingsBySessionId((current) => ({
13962
+ ...current,
13963
+ [targetDefaultDraftKey]: targetSafeNodeDefaultSettings
13964
+ }));
13965
+ onDataChangeRef.current(
13966
+ (current) => nodeDataFromComposerSettings(
13967
+ {
13968
+ ...current,
13969
+ provider: selectedComposerTargetData.provider,
13970
+ agentTargetId: selectedComposerTargetData.agentTargetId,
13971
+ providerTargetId: selectedComposerTargetData.providerTargetId,
13972
+ providerTargetRef: selectedComposerTargetData.providerTargetRef
13973
+ },
13974
+ targetSafeNodeDefaultSettings
13975
+ )
13976
+ );
13977
+ void onRememberComposerDefaultsRef.current?.({
13978
+ provider: selectedComposerTargetData.provider,
13979
+ defaults: composerDefaultsFromSettings(targetSafeNodeDefaultSettings)
13980
+ });
13981
+ }, [
13982
+ activeConversationId,
13983
+ providerComposerOptions,
13984
+ selectedComposerTargetData,
13985
+ storedNodeDefaultSettings,
13986
+ targetSafeNodeDefaultSettings
13987
+ ]);
13525
13988
  const activeConversationDraftSettings = activeConversationId ? draftSettingsBySessionId[activeConversationId] ?? null : null;
13526
13989
  const defaultConversationDraftSettings = useStableComposerSettings({
13527
13990
  ...activeConversationDraftSettings ?? homeComposerSettings,
@@ -13612,7 +14075,7 @@ function useAgentGUINodeController({
13612
14075
  hasProviderSessionNotFoundError,
13613
14076
  pendingApproval
13614
14077
  ]);
13615
- const canSubmit = activeLiveState !== "activating" && activeLiveState !== "failed" && !activeConversationResumeUnavailable && (activeConversationId !== null || selectedProviderTarget.disabled !== true) && (data.provider !== "openclaw" || openclawGateway?.status === "ready") && pendingApproval === null && pendingInteractivePrompt === null && sessionChrome.auth === null && !isCreatingConversation && !isSubmitting && !isInterrupting;
14078
+ 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;
13616
14079
  const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
13617
14080
  useEffect4(() => {
13618
14081
  const firstVersion = minFiniteMessageVersion(activeMessages);
@@ -13693,6 +14156,7 @@ function useAgentGUINodeController({
13693
14156
  isSubmitting,
13694
14157
  pendingApproval,
13695
14158
  pendingInteractivePrompt,
14159
+ providerTargetsLoading,
13696
14160
  workspaceId
13697
14161
  ]);
13698
14162
  const activeSessionReasoningSelection = useMemo4(
@@ -13725,7 +14189,9 @@ function useAgentGUINodeController({
13725
14189
  "models"
13726
14190
  );
13727
14191
  const optionsLoading = isSettingsLoading || isModelOptionsLoading;
13728
- const providerSupport = composerSupportForProvider(data.provider);
14192
+ const providerSupport = composerSupportForProvider(
14193
+ composerTargetData.provider
14194
+ );
13729
14195
  const selectedModelValue = draftModel;
13730
14196
  const selectedReasoningEffortValue = draftReasoningEffort;
13731
14197
  const selectedSpeedValue = draftSpeed;
@@ -13750,7 +14216,7 @@ function useAgentGUINodeController({
13750
14216
  supportsComputerUse: composerSupport.computer,
13751
14217
  supportsPermissionMode: supportsPermissionMode || optionsLoading && providerSupport.permission,
13752
14218
  supportsPlanMode: composerSupport.plan,
13753
- planExclusiveWithPermissionMode: data.provider === "claude-code",
14219
+ planExclusiveWithPermissionMode: composerTargetData.provider === "claude-code",
13754
14220
  isSettingsLoading,
13755
14221
  isModelOptionsLoading,
13756
14222
  modelUnavailable: activeConversationId !== null && sessionSettings === null && composerSupport.model && draftModel === null,
@@ -13767,7 +14233,7 @@ function useAgentGUINodeController({
13767
14233
  availableModels: composerSupport.model && hasOptionsSource && activeSessionModelSelection !== null ? activeSessionModelSelection.options : [],
13768
14234
  availableReasoningEfforts: composerSupport.reasoning && hasOptionsSource && activeSessionReasoningSelection !== null ? activeSessionReasoningSelection.options : [],
13769
14235
  availableSpeeds: composerSupport.speed && hasOptionsSource && activeSessionSpeedSelection !== null ? activeSessionSpeedSelection.options : [],
13770
- availablePermissionModes: supportsPermissionMode ? permissionModeOptions(data.provider, permissionConfig) : []
14236
+ availablePermissionModes: supportsPermissionMode ? permissionModeOptions(composerTargetData.provider, permissionConfig) : []
13771
14237
  };
13772
14238
  }, [
13773
14239
  activeConversationId,
@@ -13776,7 +14242,7 @@ function useAgentGUINodeController({
13776
14242
  activeSessionReasoningSelection,
13777
14243
  activeSessionSpeedSelection,
13778
14244
  activeSessionRuntimeContext,
13779
- data.provider,
14245
+ composerTargetData.provider,
13780
14246
  draftSettings.permissionModeId,
13781
14247
  draftSettings.planMode,
13782
14248
  providerComposerOptions,
@@ -13788,20 +14254,123 @@ function useAgentGUINodeController({
13788
14254
  draftSpeed
13789
14255
  ]);
13790
14256
  const stableComposerSettings = useStableComposerSettingsVM(composerSettings);
13791
- const prevSettingsLoadingRef = useRef4(null);
13792
- useEffect4(() => {
13793
- const nextLoading = stableComposerSettings.isSettingsLoading;
13794
- if (prevSettingsLoadingRef.current === nextLoading) {
13795
- return;
13796
- }
13797
- prevSettingsLoadingRef.current = nextLoading;
13798
- }, [
13799
- activeConversationId,
13800
- data.provider,
13801
- stableComposerSettings.availableModels.length,
13802
- stableComposerSettings.isSettingsLoading
13803
- ]);
14257
+ const updateConversationFilter = useCallback4(
14258
+ (filter) => {
14259
+ if (!canUseConversationTargetFilter) {
14260
+ setConversationFilter({ kind: "all" });
14261
+ return;
14262
+ }
14263
+ setConversationFilter(normalizeAgentGUIConversationFilter(filter));
14264
+ },
14265
+ [canUseConversationTargetFilter]
14266
+ );
14267
+ const selectProvider = useCallback4(
14268
+ (input) => {
14269
+ if (previewMode) {
14270
+ return;
14271
+ }
14272
+ const nextProvider = input.provider;
14273
+ const nextTarget = resolveAgentGUIProviderTarget({
14274
+ defaultProviderTargetId,
14275
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
14276
+ provider: nextProvider,
14277
+ providerTargetId: input.providerTargetId,
14278
+ providerTargets: normalizedProviderTargets
14279
+ });
14280
+ if (!nextTarget) {
14281
+ return;
14282
+ }
14283
+ if (nextTarget.disabled === true) {
14284
+ return;
14285
+ }
14286
+ const nextTargetIsExplicit = normalizedExplicitProviderTargets.some(
14287
+ (target) => target.provider === nextTarget.provider && target.targetId === nextTarget.targetId && agentGUIProviderTargetRefsEqual(target.ref, nextTarget.ref)
14288
+ );
14289
+ const nextTargetData = composerTargetDataFromProviderTarget({
14290
+ current: dataRef.current,
14291
+ isExplicit: nextTargetIsExplicit,
14292
+ target: nextTarget
14293
+ });
14294
+ setHomeComposerTargetOverride(nextTarget);
14295
+ const previous = activeConversationIdRef.current;
14296
+ if (previous) {
14297
+ void activation.unactivate(previous);
14298
+ }
14299
+ setIntent({ tag: "home" });
14300
+ isComposerHomeRef.current = true;
14301
+ setIsComposerHome(true);
14302
+ activeConversationIdRef.current = null;
14303
+ setActiveConversationId(null);
14304
+ setIsLoadingMessages(false);
14305
+ setDetailError(null);
14306
+ persistActiveConversation(null);
14307
+ onDataChangeRef.current((current) => {
14308
+ const currentNextTargetData = composerTargetDataFromProviderTarget({
14309
+ current,
14310
+ isExplicit: nextTargetIsExplicit,
14311
+ target: nextTarget
14312
+ });
14313
+ const nextAgentTargetId = currentNextTargetData.agentTargetId;
14314
+ const currentTargetId = current.agentTargetId ?? current.providerTargetId ?? null;
14315
+ const nextTargetId = nextAgentTargetId ?? nextTarget.targetId;
14316
+ const providerTargetChanged = current.provider !== nextProvider || (currentTargetId !== null || nextAgentTargetId !== null) && currentTargetId !== nextTargetId;
14317
+ const nextData = {
14318
+ ...current,
14319
+ provider: currentNextTargetData.provider,
14320
+ agentTargetId: currentNextTargetData.agentTargetId,
14321
+ lastActiveAgentSessionId: null,
14322
+ providerTargetId: currentNextTargetData.providerTargetId,
14323
+ providerTargetRef: currentNextTargetData.providerTargetRef,
14324
+ composerOverrides: providerTargetChanged ? null : current.composerOverrides
14325
+ };
14326
+ dataRef.current = nextData;
14327
+ return nextData;
14328
+ });
14329
+ loadComposerOptionsForTarget(nextTargetData, { force: true });
14330
+ },
14331
+ [
14332
+ activation,
14333
+ defaultProviderTargetId,
14334
+ loadComposerOptionsForTarget,
14335
+ normalizedExplicitProviderTargets,
14336
+ normalizedProviderTargets,
14337
+ persistActiveConversation,
14338
+ previewMode,
14339
+ shouldFallbackToLocalProviderTargets
14340
+ ]
14341
+ );
14342
+ const selectConversationFilterTarget = useCallback4(
14343
+ (input) => {
14344
+ if (!canUseConversationTargetFilter) {
14345
+ setConversationFilter({ kind: "all" });
14346
+ return;
14347
+ }
14348
+ const nextTarget = resolveAgentGUIProviderTarget({
14349
+ defaultProviderTargetId,
14350
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
14351
+ provider: input.provider,
14352
+ providerTargetId: input.providerTargetId,
14353
+ providerTargets: normalizedProviderTargets
14354
+ });
14355
+ if (!nextTarget || nextTarget.disabled === true) {
14356
+ return;
14357
+ }
14358
+ const agentTargetId = nextTarget.agentTargetId?.trim() ?? "";
14359
+ const nextFilter = agentTargetId ? { kind: "agentTarget", agentTargetId } : { kind: "all" };
14360
+ setConversationFilter(nextFilter);
14361
+ },
14362
+ [
14363
+ canUseConversationTargetFilter,
14364
+ defaultProviderTargetId,
14365
+ normalizedProviderTargets,
14366
+ shouldFallbackToLocalProviderTargets
14367
+ ]
14368
+ );
13804
14369
  const stableCreateConversation = useStableControllerEventCallback(createConversation);
14370
+ const stableSelectProvider = useStableControllerEventCallback(selectProvider);
14371
+ const stableSelectConversationFilterTarget = useStableControllerEventCallback(
14372
+ selectConversationFilterTarget
14373
+ );
13805
14374
  const stableSelectConversation = useStableControllerEventCallback(selectConversation);
13806
14375
  const stableSubmitPrompt = useStableControllerEventCallback(submitPrompt);
13807
14376
  const stableSubmitGuidancePrompt = useStableControllerEventCallback(submitGuidancePrompt);
@@ -13852,8 +14421,15 @@ function useAgentGUINodeController({
13852
14421
  const stableLoadOlderConversationMessages = useStableControllerEventCallback(
13853
14422
  loadOlderConversationMessages
13854
14423
  );
14424
+ const stableUpdateConversationFilter = useStableControllerEventCallback(
14425
+ updateConversationFilter
14426
+ );
14427
+ const viewData = activeConversationId === null ? selectedComposerTargetData.data : data;
13855
14428
  const controllerActions = useMemo4(
13856
14429
  () => ({
14430
+ updateConversationFilter: stableUpdateConversationFilter,
14431
+ selectConversationFilterTarget: stableSelectConversationFilterTarget,
14432
+ selectProvider: stableSelectProvider,
13857
14433
  createConversation: stableCreateConversation,
13858
14434
  selectConversation: stableSelectConversation,
13859
14435
  submitPrompt: stableSubmitPrompt,
@@ -13900,6 +14476,8 @@ function useAgentGUINodeController({
13900
14476
  stableRetryActivation,
13901
14477
  stableRetryOpenclawGateway,
13902
14478
  stableSelectConversation,
14479
+ stableSelectConversationFilterTarget,
14480
+ stableSelectProvider,
13903
14481
  stableSendQueuedPromptNext,
13904
14482
  stableSubmitGuidancePrompt,
13905
14483
  stableShowPromptImagesUnsupported,
@@ -13907,6 +14485,7 @@ function useAgentGUINodeController({
13907
14485
  stableSubmitInteractivePrompt,
13908
14486
  stableSubmitPrompt,
13909
14487
  stableToggleConversationPinned,
14488
+ stableUpdateConversationFilter,
13910
14489
  stableUpdateComposerSettings,
13911
14490
  stableUpdateDraftContent,
13912
14491
  stableUpdateSelectedProjectPath
@@ -13918,8 +14497,12 @@ function useAgentGUINodeController({
13918
14497
  workspaceId,
13919
14498
  workspacePath,
13920
14499
  currentUserId,
13921
- data,
13922
- selectedProviderTarget,
14500
+ data: viewData,
14501
+ selectedProviderTarget: effectiveSelectedProviderTarget,
14502
+ providerTargets: normalizedProviderTargets,
14503
+ providerTargetsLoading,
14504
+ conversationScope,
14505
+ conversationFilter,
13923
14506
  conversations: visibleConversations,
13924
14507
  userProjects,
13925
14508
  activeConversation,
@@ -13940,6 +14523,7 @@ function useAgentGUINodeController({
13940
14523
  promptImagesSupported,
13941
14524
  compactSupported,
13942
14525
  usage,
14526
+ backgroundAgentCount,
13943
14527
  listError,
13944
14528
  isDeletingConversation,
13945
14529
  isDeletingProjectConversations,
@@ -13981,10 +14565,14 @@ function useAgentGUINodeController({
13981
14565
  canSubmit,
13982
14566
  canQueueWhileBusy,
13983
14567
  conversation,
14568
+ conversationScope,
14569
+ conversationFilter,
13984
14570
  conversationDetail,
13985
14571
  controllerActions,
13986
14572
  data,
13987
- selectedProviderTarget,
14573
+ effectiveSelectedProviderTarget,
14574
+ normalizedProviderTargets,
14575
+ providerTargetsLoading,
13988
14576
  detailError,
13989
14577
  draftContent,
13990
14578
  draftPrompt,
@@ -13993,6 +14581,7 @@ function useAgentGUINodeController({
13993
14581
  promptImagesSupported,
13994
14582
  compactSupported,
13995
14583
  usage,
14584
+ backgroundAgentCount,
13996
14585
  isInterrupting,
13997
14586
  isCancelPending,
13998
14587
  isLoadingConversations,
@@ -14009,7 +14598,7 @@ function useAgentGUINodeController({
14009
14598
  pendingDeleteProjectConversations,
14010
14599
  pendingApproval,
14011
14600
  pendingInteractivePrompt,
14012
- selectedProviderTarget.disabled,
14601
+ effectiveSelectedProviderTarget.disabled,
14013
14602
  queuedPrompts,
14014
14603
  drainingQueuedPromptId,
14015
14604
  currentUserId,
@@ -14017,6 +14606,7 @@ function useAgentGUINodeController({
14017
14606
  workspacePath,
14018
14607
  stableComposerSettings,
14019
14608
  sessionChrome,
14609
+ viewData,
14020
14610
  userProjects,
14021
14611
  visibleConversations
14022
14612
  ]
@@ -14214,7 +14804,13 @@ import {
14214
14804
  } from "react";
14215
14805
  import { useSnapshot } from "valtio";
14216
14806
  import { proxy as proxy2 } from "valtio/vanilla";
14217
- import { ChevronRight as ChevronRight2, ExternalLink, Info as Info2, Wrench } from "lucide-react";
14807
+ import {
14808
+ ChevronRight as ChevronRight2,
14809
+ ExternalLink,
14810
+ Info as Info2,
14811
+ LayoutGrid,
14812
+ Wrench
14813
+ } from "lucide-react";
14218
14814
 
14219
14815
  // app/renderer/components/ui/popover.tsx
14220
14816
  import {
@@ -15015,13 +15611,11 @@ function AgentChromeNotice({
15015
15611
  }) {
15016
15612
  "use memo";
15017
15613
  const fullMessage = description ? `${title} ${description}` : title;
15614
+ const toneClassName = tone === "danger" ? AgentGUIChrome_styles_default.chromeCardDanger : tone === "muted" ? AgentGUIChrome_styles_default.chromeCardMuted : AgentGUIChrome_styles_default.chromeCardWarning;
15018
15615
  return /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.sessionChrome, children: /* @__PURE__ */ jsx19(
15019
15616
  "section",
15020
15617
  {
15021
- className: cn(
15022
- AgentGUIChrome_styles_default.chromeCard,
15023
- tone === "danger" ? AgentGUIChrome_styles_default.chromeCardDanger : AgentGUIChrome_styles_default.chromeCardWarning
15024
- ),
15618
+ className: cn(AgentGUIChrome_styles_default.chromeCard, toneClassName),
15025
15619
  role,
15026
15620
  "data-testid": testId,
15027
15621
  children: /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.chromeMetaRow, children: /* @__PURE__ */ jsxs7("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: [
@@ -15265,7 +15859,15 @@ import {
15265
15859
  useState as useState10
15266
15860
  } from "react";
15267
15861
  import { createPortal as createPortal3 } from "react-dom";
15268
- import { AddIcon, Button as Button3, Select as Select2, SelectTrigger as SelectTrigger2 } from "@tutti-os/ui-system";
15862
+ import {
15863
+ AddIcon,
15864
+ Button as Button3,
15865
+ Select as Select2,
15866
+ SelectContent as SelectContent2,
15867
+ SelectItem as SelectItem2,
15868
+ SelectTrigger as SelectTrigger2,
15869
+ SelectValue
15870
+ } from "@tutti-os/ui-system";
15269
15871
  import { ListChecks as ListChecks2, Target as Target3, X } from "lucide-react";
15270
15872
  import {
15271
15873
  createMentionPaletteStateAdapter,
@@ -15946,6 +16548,7 @@ var styles3 = {
15946
16548
  composerPromptTipText: "agent-gui-node__composer-prompt-tip-text",
15947
16549
  composerPromptTipTooltip: "agent-gui-node__composer-prompt-tip-tooltip",
15948
16550
  composerProjectRow: "agent-gui-node__composer-project-row",
16551
+ composerProviderSelect: "agent-gui-node__composer-provider-select",
15949
16552
  composerQueuedPromptCard: "agent-gui-node__composer-queued-prompt-card",
15950
16553
  composerQueuedPromptHeader: "agent-gui-node__composer-queued-prompt-header",
15951
16554
  composerQueuedPromptExpandCue: "agent-gui-node__composer-queued-prompt-expand-cue",
@@ -16023,6 +16626,12 @@ var styles3 = {
16023
16626
  projectRailAddProjectTrigger: "agent-gui-node__project-rail-add-project-trigger",
16024
16627
  projectRailHeader: "agent-gui-node__project-rail-header",
16025
16628
  projectRailTitle: "agent-gui-node__project-rail-title",
16629
+ providerRail: "agent-gui-node__provider-rail",
16630
+ providerRailAvatar: "agent-gui-node__provider-rail-avatar",
16631
+ providerRailAvatarIcon: "agent-gui-node__provider-rail-avatar-icon",
16632
+ providerRailAvatarImage: "agent-gui-node__provider-rail-avatar-image",
16633
+ providerRailTile: "agent-gui-node__provider-rail-tile",
16634
+ providerRailTileLabel: "agent-gui-node__provider-rail-tile-label",
16026
16635
  rail: "agent-gui-node__rail",
16027
16636
  railPanel: "agent-gui-node__rail-panel",
16028
16637
  railPanelCollapsed: "agent-gui-node__rail-panel--collapsed",
@@ -17878,6 +18487,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
17878
18487
  const removeMentionLabelRef = useRef8(removeMentionLabel);
17879
18488
  const availableSkillsRef = useRef8(availableSkills);
17880
18489
  const availableCapabilitiesRef = useRef8(availableCapabilities);
18490
+ const suppressPastedAtSuggestionRef = useRef8(false);
17881
18491
  const scrollFrameRef = useRef8(null);
17882
18492
  const [contextMenu, setContextMenu] = useState7(null);
17883
18493
  const closeContextMenu = useCallback6(() => {
@@ -17888,6 +18498,12 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
17888
18498
  if (!currentEditor || currentEditor.isDestroyed || !text) {
17889
18499
  return;
17890
18500
  }
18501
+ suppressPastedAtSuggestionRef.current = text.includes("@") && !text.endsWith("@");
18502
+ if (suppressPastedAtSuggestionRef.current) {
18503
+ window.setTimeout(() => {
18504
+ suppressPastedAtSuggestionRef.current = false;
18505
+ }, 0);
18506
+ }
17891
18507
  currentEditor.chain().focus().insertContent(
17892
18508
  plainTextToAgentRichTextInlineContent(text, {
17893
18509
  capabilities: availableCapabilitiesRef.current,
@@ -17961,7 +18577,8 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
17961
18577
  enableSuggestions: enableFileMentionSuggestions,
17962
18578
  onSuggestionChange: (state) => onFileMentionSuggestionChangeRef.current?.(state),
17963
18579
  onSuggestionKeyDown: (event) => onFileMentionSuggestionKeyDownRef.current?.(event) ?? false,
17964
- removeActionAriaLabel: removeMentionLabelRef.current
18580
+ removeActionAriaLabel: removeMentionLabelRef.current,
18581
+ shouldSuppressSuggestion: () => suppressPastedAtSuggestionRef.current
17965
18582
  },
17966
18583
  { skills: availableSkillsRef.current },
17967
18584
  { capabilities: availableCapabilitiesRef.current }
@@ -18149,6 +18766,12 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
18149
18766
  currentEditor.state.doc.content.size
18150
18767
  );
18151
18768
  }
18769
+ suppressPastedAtSuggestionRef.current = text.includes("@") && !text.endsWith("@");
18770
+ if (suppressPastedAtSuggestionRef.current) {
18771
+ window.setTimeout(() => {
18772
+ suppressPastedAtSuggestionRef.current = false;
18773
+ }, 0);
18774
+ }
18152
18775
  currentEditor.commands.insertContent(
18153
18776
  plainTextToAgentRichTextInlineContent(text, {
18154
18777
  capabilities: availableCapabilitiesRef.current,
@@ -18875,7 +19498,7 @@ function AgentReviewPickerPanel({
18875
19498
  {
18876
19499
  key: "uncommitted",
18877
19500
  label: labels.uncommitted,
18878
- onSelect: () => submit("/review")
19501
+ onSelect: () => submit("/review uncommitted")
18879
19502
  },
18880
19503
  {
18881
19504
  key: "base",
@@ -19495,7 +20118,7 @@ function AgentUsageChip({
19495
20118
  var composerStyles = {
19496
20119
  footerGroup: AgentGUINode_styles_default.composerFooterLeft,
19497
20120
  footerGroupRight: AgentGUINode_styles_default.composerFooterRight,
19498
- dropdownSurface: "nodrag isolate rounded-[12px] border border-hairline bg-background-fronted p-[4px] text-foreground shadow-[var(--tsh-shell-shadow)] [-webkit-app-region:no-drag]"
20121
+ dropdownSurface: "nodrag isolate rounded-[12px] border border-hairline bg-background-fronted p-[4px] text-foreground shadow-[var(--shadow-panel)] [-webkit-app-region:no-drag]"
19499
20122
  };
19500
20123
  var workspaceReferenceSelectValue = "__tutti_workspace_reference_idle__";
19501
20124
  var workspaceReferenceOptionValue = "__tutti_workspace_reference_add__";
@@ -19552,11 +20175,21 @@ function hasInlineOverflow(element) {
19552
20175
  }
19553
20176
  return element.scrollWidth > element.clientWidth + 1;
19554
20177
  }
20178
+ function resolveComposerProviderIconUrl(provider) {
20179
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
20180
+ return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20181
+ }
20182
+ function resolveComposerProviderTargetIconUrl(target) {
20183
+ return target.iconUrl?.trim() || resolveComposerProviderIconUrl(target.provider);
20184
+ }
19555
20185
  function AgentComposer({
19556
20186
  workspaceId,
19557
20187
  workspacePath,
19558
20188
  currentUserId,
19559
20189
  provider,
20190
+ selectedProviderTarget = null,
20191
+ providerTargets = [],
20192
+ providerSelectReadonly = false,
19560
20193
  slashStatus = null,
19561
20194
  usage = null,
19562
20195
  draftContent,
@@ -19575,6 +20208,7 @@ function AgentComposer({
19575
20208
  canQueueWhileBusy,
19576
20209
  showStopButton,
19577
20210
  activePrompt,
20211
+ backgroundAgentStatusText = null,
19578
20212
  activePromptKeyboardShortcutsEnabled = true,
19579
20213
  promptTips = EMPTY_PROMPT_TIPS,
19580
20214
  isInterrupting,
@@ -19592,6 +20226,7 @@ function AgentComposer({
19592
20226
  onProjectPathChange = () => {
19593
20227
  },
19594
20228
  onSettingsChange,
20229
+ onProviderSelect,
19595
20230
  capabilityMenuState,
19596
20231
  onSubmit,
19597
20232
  onSubmitGuidance,
@@ -20705,6 +21340,17 @@ function AgentComposer({
20705
21340
  }
20706
21341
  await applyReferencePickResult(await onRequestWorkspaceReferences());
20707
21342
  }, [applyReferencePickResult, onRequestWorkspaceReferences]);
21343
+ const providerSwitchTargets = useMemo9(
21344
+ () => providerTargets.filter((target) => target.disabled !== true),
21345
+ [providerTargets]
21346
+ );
21347
+ const showProviderSelect = providerSwitchTargets.length > 1;
21348
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
21349
+ const selectedProviderSwitchTarget = providerSwitchTargets.find(
21350
+ (target) => target.targetId === selectedProviderTargetId
21351
+ ) ?? selectedProviderTarget ?? providerSwitchTargets.find((target) => target.provider === provider) ?? null;
21352
+ const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? provider;
21353
+ const providerSelectDisabled = previewMode || providerSelectReadonly || !onProviderSelect;
20708
21354
  const applyDroppedFileReferences = useCallback9(
20709
21355
  async (files) => {
20710
21356
  if (!promptFilesSupported || !resolveDroppedFileReferences || files.length === 0) {
@@ -21355,6 +22001,16 @@ function AgentComposer({
21355
22001
  ),
21356
22002
  "data-edge-glow": showEdgeGlow ? "true" : void 0,
21357
22003
  children: [
22004
+ backgroundAgentStatusText ? /* @__PURE__ */ jsx28(
22005
+ AgentChromeNotice,
22006
+ {
22007
+ tone: "muted",
22008
+ role: "status",
22009
+ testId: "agent-gui-composer-background-agent-status",
22010
+ title: backgroundAgentStatusText,
22011
+ icon: /* @__PURE__ */ jsx28(Spinner, { className: "h-3.5 w-3.5" })
22012
+ }
22013
+ ) : null,
21358
22014
  isSelectedProjectMissing ? /* @__PURE__ */ jsx28(
21359
22015
  AgentChromeNotice,
21360
22016
  {
@@ -21691,8 +22347,70 @@ function AgentComposer({
21691
22347
  )
21692
22348
  }
21693
22349
  ),
21694
- composerSettings.supportsPlanMode && composerSettings.draftSettings.planMode ? /* @__PURE__ */ jsx28(
21695
- "button",
22350
+ showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
22351
+ Select2,
22352
+ {
22353
+ value: selectedProviderTargetId,
22354
+ disabled: providerSelectDisabled,
22355
+ onValueChange: (nextTargetId) => {
22356
+ const target = providerSwitchTargets.find(
22357
+ (candidate) => candidate.targetId === nextTargetId
22358
+ );
22359
+ if (!target) {
22360
+ return;
22361
+ }
22362
+ onProviderSelect?.({
22363
+ provider: target.provider,
22364
+ providerTargetId: target.targetId
22365
+ });
22366
+ },
22367
+ children: [
22368
+ /* @__PURE__ */ jsx28(
22369
+ SelectTrigger2,
22370
+ {
22371
+ size: "sm",
22372
+ "aria-label": labels.providerSwitchLabel,
22373
+ title: labels.providerSwitchLabel,
22374
+ className: cn(
22375
+ AgentGUINode_styles_default.composerMenuTrigger,
22376
+ AgentGUINode_styles_default.composerProviderSelect,
22377
+ "max-w-[160px] text-[var(--agent-gui-text-secondary)]"
22378
+ ),
22379
+ children: /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx28(SelectValue, { placeholder: selectedProviderLabel }) })
22380
+ }
22381
+ ),
22382
+ /* @__PURE__ */ jsx28(
22383
+ SelectContent2,
22384
+ {
22385
+ align: "start",
22386
+ className: cn(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
22387
+ children: providerSwitchTargets.map((target) => /* @__PURE__ */ jsx28(
22388
+ SelectItem2,
22389
+ {
22390
+ value: target.targetId,
22391
+ className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22392
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
22393
+ /* @__PURE__ */ jsx28(
22394
+ "img",
22395
+ {
22396
+ alt: "",
22397
+ "aria-hidden": "true",
22398
+ className: "size-4 shrink-0 rounded-[4px]",
22399
+ src: resolveComposerProviderTargetIconUrl(target)
22400
+ }
22401
+ ),
22402
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: target.label })
22403
+ ] })
22404
+ },
22405
+ `${target.provider}:${target.targetId}`
22406
+ ))
22407
+ }
22408
+ )
22409
+ ]
22410
+ }
22411
+ ) : null,
22412
+ composerSettings.supportsPlanMode && composerSettings.draftSettings.planMode ? /* @__PURE__ */ jsx28(
22413
+ "button",
21696
22414
  {
21697
22415
  type: "button",
21698
22416
  disabled: settingsControlsDisabled,
@@ -22298,7 +23016,7 @@ function groupConversations(conversations, labels, userProjects = [], options =
22298
23016
  }
22299
23017
  groups.push(
22300
23018
  ...[...projectGroups.values()].sort(
22301
- (left, right) => left.sectionOrder - right.sectionOrder || Number(right.items.length > 0) - Number(left.items.length > 0) || right.projectUpdatedAtUnixMs - left.projectUpdatedAtUnixMs || left.projectOrder - right.projectOrder || left.label.localeCompare(right.label) || left.id.localeCompare(right.id)
23019
+ (left, right) => left.sectionOrder - right.sectionOrder || right.projectUpdatedAtUnixMs - left.projectUpdatedAtUnixMs || left.projectOrder - right.projectOrder || left.label.localeCompare(right.label) || left.id.localeCompare(right.id)
22302
23020
  ).map(
22303
23021
  ({
22304
23022
  projectOrder: _projectOrder,
@@ -22508,7 +23226,7 @@ function resolveConversationDetailStatus(detail) {
22508
23226
  function objectRecord(value) {
22509
23227
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
22510
23228
  }
22511
- function numberValue(value) {
23229
+ function numberValue2(value) {
22512
23230
  if (typeof value === "number" && Number.isFinite(value)) {
22513
23231
  return value;
22514
23232
  }
@@ -22528,8 +23246,8 @@ function resolveSlashStatus({
22528
23246
  }) {
22529
23247
  const usage = objectRecord(rawState?.runtimeContext?.usage);
22530
23248
  const contextWindow = objectRecord(usage?.contextWindow) ?? objectRecord(usage?.context_window) ?? (usage && (usage.used !== void 0 || usage.size !== void 0 || usage.usedTokens !== void 0 || usage.totalTokens !== void 0) ? {
22531
- usedTokens: numberValue(usage.usedTokens) ?? numberValue(usage.used_tokens) ?? numberValue(usage.used),
22532
- totalTokens: numberValue(usage.totalTokens) ?? numberValue(usage.total_tokens) ?? numberValue(usage.size)
23249
+ usedTokens: numberValue2(usage.usedTokens) ?? numberValue2(usage.used_tokens) ?? numberValue2(usage.used),
23250
+ totalTokens: numberValue2(usage.totalTokens) ?? numberValue2(usage.total_tokens) ?? numberValue2(usage.size)
22533
23251
  } : null);
22534
23252
  const providerConfig = objectRecord(rawState?.runtimeContext?.providerConfig);
22535
23253
  return {
@@ -22538,8 +23256,8 @@ function resolveSlashStatus({
22538
23256
  limits,
22539
23257
  limitsLoading: limitsLoading || isAppServerStartupLoading2(rawState, "rateLimits"),
22540
23258
  contextWindow: contextWindow ? {
22541
- usedTokens: numberValue(contextWindow.usedTokens) ?? numberValue(contextWindow.used_tokens),
22542
- totalTokens: numberValue(contextWindow.totalTokens) ?? numberValue(contextWindow.total_tokens)
23259
+ usedTokens: numberValue2(contextWindow.usedTokens) ?? numberValue2(contextWindow.used_tokens),
23260
+ totalTokens: numberValue2(contextWindow.totalTokens) ?? numberValue2(contextWindow.total_tokens)
22543
23261
  } : null
22544
23262
  };
22545
23263
  }
@@ -22614,6 +23332,8 @@ function AgentGUINodeView({
22614
23332
  isAgentProviderReady,
22615
23333
  slashStatusLimits = [],
22616
23334
  slashStatusLimitsLoading = false,
23335
+ railConfigProvider,
23336
+ railSlashStatusLimits,
22617
23337
  previewMode = false,
22618
23338
  onAgentProviderLogin,
22619
23339
  actions,
@@ -22956,9 +23676,14 @@ function AgentGUINodeView({
22956
23676
  "--agent-gui-detail-min-width": `${detailMinWidthPx}px`,
22957
23677
  gridTemplateColumns: conversationRailCollapsed ? "0 minmax(var(--agent-gui-detail-min-width), 1fr)" : "var(--agent-gui-conversation-rail-width) minmax(var(--agent-gui-detail-min-width), 1fr)"
22958
23678
  };
23679
+ const effectiveRailConfigProvider = railConfigProvider === void 0 ? viewModel.data.provider : railConfigProvider;
23680
+ const effectiveRailSlashStatusLimits = railSlashStatusLimits ?? slashStatusLimits;
22959
23681
  const openAgentEnvSetup = useCallback10(() => {
22960
- openAgentEnvPanel({ provider: viewModel.data.provider, focus: null });
22961
- }, [viewModel.data.provider]);
23682
+ if (!effectiveRailConfigProvider) {
23683
+ return;
23684
+ }
23685
+ openAgentEnvPanel({ provider: effectiveRailConfigProvider, focus: null });
23686
+ }, [effectiveRailConfigProvider]);
22962
23687
  const conversationRailStoreState = useMemo10(
22963
23688
  () => ({
22964
23689
  activeConversationId: viewModel.activeConversationId,
@@ -22973,8 +23698,16 @@ function AgentGUINodeView({
22973
23698
  createConversationDisabled,
22974
23699
  openclawGateway,
22975
23700
  isCollapsed: conversationRailCollapsed,
22976
- slashStatusLimits,
23701
+ railConfigProvider: effectiveRailConfigProvider,
23702
+ slashStatusLimits: effectiveRailSlashStatusLimits,
23703
+ selectedProviderTarget: viewModel.selectedProviderTarget,
23704
+ providerTargets: viewModel.providerTargets,
23705
+ providerTargetsLoading: viewModel.providerTargetsLoading,
23706
+ conversationScope: viewModel.conversationScope,
23707
+ conversationFilter: viewModel.conversationFilter,
22977
23708
  onCreateConversation: requestCreateConversation,
23709
+ onUpdateConversationFilter: actions.updateConversationFilter,
23710
+ onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
22978
23711
  onOpenAgentEnvSetup: openAgentEnvSetup,
22979
23712
  onRetryOpenclawGateway: retryOpenclawGateway,
22980
23713
  onSelectConversation: selectConversation,
@@ -23001,6 +23734,7 @@ function AgentGUINodeView({
23001
23734
  openConversationWindow,
23002
23735
  openProjectFiles,
23003
23736
  openclawGateway,
23737
+ actions.updateConversationFilter,
23004
23738
  previewMode,
23005
23739
  removeProject,
23006
23740
  requestCreateConversation,
@@ -23008,9 +23742,15 @@ function AgentGUINodeView({
23008
23742
  retryOpenclawGateway,
23009
23743
  selectConversation,
23010
23744
  selectProjectDirectory,
23011
- slashStatusLimits,
23745
+ effectiveRailConfigProvider,
23746
+ effectiveRailSlashStatusLimits,
23747
+ viewModel.selectedProviderTarget,
23748
+ viewModel.providerTargets,
23749
+ viewModel.providerTargetsLoading,
23012
23750
  toggleConversationPinned,
23013
23751
  uiLanguage,
23752
+ viewModel.conversationScope,
23753
+ viewModel.conversationFilter,
23014
23754
  viewModel.activeConversationId,
23015
23755
  viewModel.isDeletingConversation,
23016
23756
  viewModel.isDeletingProjectConversations,
@@ -23032,7 +23772,21 @@ function AgentGUINodeView({
23032
23772
  conversationRailStore,
23033
23773
  conversationRailStoreState
23034
23774
  );
23035
- const content = /* @__PURE__ */ jsxs17(Fragment8, { children: [
23775
+ const agentTargetPresentations = useMemo10(
23776
+ () => viewModel.providerTargets.flatMap(
23777
+ (target) => target.agentTargetId ? [
23778
+ {
23779
+ agentTargetId: target.agentTargetId,
23780
+ iconUrl: target.iconUrl ?? null,
23781
+ name: target.label,
23782
+ provider: target.provider,
23783
+ workspaceId: viewModel.workspaceId
23784
+ }
23785
+ ] : []
23786
+ ),
23787
+ [viewModel.providerTargets, viewModel.workspaceId]
23788
+ );
23789
+ const content = /* @__PURE__ */ jsxs17(AgentTargetPresentationProvider, { agentTargets: agentTargetPresentations, children: [
23036
23790
  /* @__PURE__ */ jsxs17(
23037
23791
  "div",
23038
23792
  {
@@ -23054,11 +23808,9 @@ function AgentGUINodeView({
23054
23808
  AgentGUIConversationRailStorePane,
23055
23809
  {
23056
23810
  conversations: viewModel.conversations,
23057
- provider: viewModel.data.provider,
23058
23811
  store: conversationRailStore,
23059
23812
  storeState: conversationRailStoreState,
23060
- userProjects: viewModel.userProjects,
23061
- workspaceId: viewModel.workspaceId
23813
+ userProjects: viewModel.userProjects
23062
23814
  }
23063
23815
  )
23064
23816
  }
@@ -23560,6 +24312,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23560
24312
  removeMention: labels.removeMention,
23561
24313
  addReference: labels.addReference,
23562
24314
  referenceWorkspaceFiles: labels.referenceWorkspaceFiles,
24315
+ providerSwitchLabel: labels.providerSwitchLabel,
23563
24316
  projectLocked: labels.projectLocked,
23564
24317
  projectMissingDescription: labels.projectMissingDescription,
23565
24318
  promptTipsPrefix: labels.promptTipsPrefix,
@@ -23600,6 +24353,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23600
24353
  labels.queuedLabel,
23601
24354
  labels.queuedPromptMoreActions,
23602
24355
  labels.referenceWorkspaceFiles,
24356
+ labels.providerSwitchLabel,
23603
24357
  labels.removeMention,
23604
24358
  labels.reasoningDegreeLabel,
23605
24359
  labels.reasoningLabel,
@@ -23708,6 +24462,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23708
24462
  const submitPromptAndScrollToBottom = useCallback10(
23709
24463
  (content, displayPrompt) => {
23710
24464
  requestSubmittedPromptScrollToBottom();
24465
+ if (displayPrompt === void 0) {
24466
+ submitPrompt(content);
24467
+ return;
24468
+ }
23711
24469
  submitPrompt(content, displayPrompt);
23712
24470
  },
23713
24471
  [requestSubmittedPromptScrollToBottom, submitPrompt]
@@ -23715,6 +24473,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23715
24473
  const submitGuidancePromptAndScrollToBottom = useCallback10(
23716
24474
  (content, displayPrompt) => {
23717
24475
  requestSubmittedPromptScrollToBottom();
24476
+ if (displayPrompt === void 0) {
24477
+ submitGuidancePrompt(content);
24478
+ return;
24479
+ }
23718
24480
  submitGuidancePrompt(content, displayPrompt);
23719
24481
  },
23720
24482
  [requestSubmittedPromptScrollToBottom, submitGuidancePrompt]
@@ -23739,6 +24501,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23739
24501
  );
23740
24502
  const stableRequestGitBranches = useOptionalStableEventCallback(onRequestGitBranches);
23741
24503
  const authLogin = useOptionalStableEventCallback(onAgentProviderLogin);
24504
+ const backgroundAgentStatusText = viewModel.backgroundAgentCount > 0 ? labels.waitingForBackgroundAgent(viewModel.backgroundAgentCount) : null;
23742
24505
  const submitBottomDockInteractivePrompt = useCallback10(
23743
24506
  (input) => {
23744
24507
  submitInteractivePrompt(input);
@@ -23746,12 +24509,17 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23746
24509
  },
23747
24510
  [submitInteractivePrompt]
23748
24511
  );
24512
+ const canSwitchComposerProvider = viewModel.conversationScope === "multi-provider";
24513
+ const composerProviderTargets = canSwitchComposerProvider ? viewModel.providerTargets : [viewModel.selectedProviderTarget];
23749
24514
  const bottomDockComposerProps = useMemo10(
23750
24515
  () => ({
23751
24516
  workspaceId: viewModel.workspaceId,
23752
24517
  workspacePath: viewModel.workspacePath,
23753
24518
  currentUserId: viewModel.currentUserId,
23754
24519
  provider: viewModel.data.provider,
24520
+ selectedProviderTarget: viewModel.selectedProviderTarget,
24521
+ providerTargets: composerProviderTargets,
24522
+ providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
23755
24523
  slashStatus,
23756
24524
  usage: viewModel.usage,
23757
24525
  draftContent: viewModel.draftContent,
@@ -23773,6 +24541,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23773
24541
  // Plan decisions replace the composer via bottomDockReplacementPrompt;
23774
24542
  // approval / ask-user embed here (composerActivePrompt encodes that).
23775
24543
  activePrompt: composerActivePrompt,
24544
+ backgroundAgentStatusText,
23776
24545
  activePromptKeyboardShortcutsEnabled: isActive,
23777
24546
  promptTips: labels.promptTips,
23778
24547
  composerFocusRequestSequence,
@@ -23788,6 +24557,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23788
24557
  onDraftContentChange: updateDraftContent,
23789
24558
  onProjectPathChange: updateSelectedProjectPath,
23790
24559
  onSettingsChange: updateComposerSettings,
24560
+ onProviderSelect: canSwitchComposerProvider ? actions.selectProvider : void 0,
23791
24561
  onSubmit: submitPromptAndScrollToBottom,
23792
24562
  onSubmitGuidance: submitGuidancePromptAndScrollToBottom,
23793
24563
  onPromptImagesUnsupported: showPromptImagesUnsupported,
@@ -23806,7 +24576,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23806
24576
  }),
23807
24577
  [
23808
24578
  canQueueWhileBusy,
24579
+ backgroundAgentStatusText,
24580
+ canSwitchComposerProvider,
23809
24581
  capabilityMenuState,
24582
+ composerProviderTargets,
23810
24583
  composerDisabled,
23811
24584
  composerDisabledReason,
23812
24585
  composerFocusRequestSequence,
@@ -23838,6 +24611,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23838
24611
  stableSelectProjectDirectory,
23839
24612
  stableRequestWorkspaceReferences,
23840
24613
  updateComposerSettings,
24614
+ actions.selectProvider,
23841
24615
  updateDraftContent,
23842
24616
  updateSelectedProjectPath,
23843
24617
  viewModel.availableCommands,
@@ -23846,6 +24620,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23846
24620
  viewModel.composerSettings,
23847
24621
  viewModel.currentUserId,
23848
24622
  viewModel.data.provider,
24623
+ viewModel.selectedProviderTarget,
23849
24624
  viewModel.draftContent,
23850
24625
  viewModel.draftPrompt,
23851
24626
  viewModel.drainingQueuedPromptId,
@@ -23868,6 +24643,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23868
24643
  }),
23869
24644
  [bottomDockComposerProps]
23870
24645
  );
24646
+ const emptyHeroProvider = viewModel.selectedProviderTarget?.provider ?? viewModel.data.provider;
23871
24647
  const bottomDockStoreState = useMemo10(
23872
24648
  () => ({
23873
24649
  // The lifted prompt is rendered from props on the pane; the store still
@@ -23899,6 +24675,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23899
24675
  sessionChrome.auth?.message ?? "",
23900
24676
  sessionChrome.recovery?.kind ?? "",
23901
24677
  sessionChrome.recovery?.message ?? "",
24678
+ backgroundAgentStatusText ?? "",
23902
24679
  viewModel.queuedPrompts.map((prompt) => prompt.id).join(","),
23903
24680
  viewModel.drainingQueuedPromptId ?? "",
23904
24681
  viewModel.isRespondingApproval ? "1" : "0"
@@ -24151,7 +24928,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
24151
24928
  children: !hasActiveConversation ? /* @__PURE__ */ jsx31(
24152
24929
  AgentGUIEmptyHeroPane,
24153
24930
  {
24154
- provider: viewModel.data.provider,
24931
+ provider: emptyHeroProvider,
24155
24932
  emptyLabel: labels.empty,
24156
24933
  emptyProvider: labels.emptyProvider ?? "",
24157
24934
  inlineNoticeChrome,
@@ -24380,8 +25157,8 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
24380
25157
  const goal = objectRecord(sessionChrome.rawState?.runtimeContext?.goal);
24381
25158
  const goalObjective = goal ? stringValue2(goal.objective) : "";
24382
25159
  const goalStatus = goal ? stringValue2(goal.status) : "";
24383
- const goalTokenBudget = goal ? numberValue(goal.tokenBudget) : null;
24384
- const goalTokensUsed = goal ? numberValue(goal.tokensUsed) : null;
25160
+ const goalTokenBudget = goal ? numberValue2(goal.tokenBudget) : null;
25161
+ const goalTokensUsed = goal ? numberValue2(goal.tokensUsed) : null;
24385
25162
  const showGoalBanner = isGoalBannerVisible(goalObjective, goalStatus);
24386
25163
  return /* @__PURE__ */ jsxs17(
24387
25164
  "div",
@@ -24478,16 +25255,14 @@ function syncAgentGUIConversationRailStore(store, next) {
24478
25255
  Object.assign(store, next);
24479
25256
  }
24480
25257
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
24481
- 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.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
25258
+ return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.isLoadingConversations === next.isLoadingConversations && current.isDeletingConversation === next.isDeletingConversation && current.isDeletingProjectConversations === next.isDeletingProjectConversations && current.labels === next.labels && current.workspaceUserProjectI18n === next.workspaceUserProjectI18n && current.uiLanguage === next.uiLanguage && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && current.railConfigProvider === next.railConfigProvider && current.slashStatusLimits === next.slashStatusLimits && current.selectedProviderTarget === next.selectedProviderTarget && current.providerTargets === next.providerTargets && current.providerTargetsLoading === next.providerTargetsLoading && current.conversationScope === next.conversationScope && current.conversationFilter === next.conversationFilter && current.onUpdateConversationFilter === next.onUpdateConversationFilter && current.onSelectConversationFilterTarget === next.onSelectConversationFilterTarget && current.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
24482
25259
  }
24483
25260
  var AgentGUIConversationRailStorePane = memo(
24484
25261
  function AgentGUIConversationRailStorePane2({
24485
25262
  conversations,
24486
- provider,
24487
25263
  store,
24488
25264
  storeState: _storeState,
24489
- userProjects,
24490
- workspaceId
25265
+ userProjects
24491
25266
  }) {
24492
25267
  "use memo";
24493
25268
  const state = useSnapshot(store);
@@ -24496,9 +25271,7 @@ var AgentGUIConversationRailStorePane = memo(
24496
25271
  {
24497
25272
  ...state,
24498
25273
  conversations,
24499
- provider,
24500
- userProjects,
24501
- workspaceId
25274
+ userProjects
24502
25275
  }
24503
25276
  );
24504
25277
  }
@@ -24510,47 +25283,6 @@ function normalizeConversationRailProjectPath(path) {
24510
25283
  }
24511
25284
  return normalized.replace(/\/+$/, "") || "/";
24512
25285
  }
24513
- function buildRailSessionGroupProjects({
24514
- groups,
24515
- userProjects
24516
- }) {
24517
- const userProjectByPath = new Map(
24518
- userProjects.map((project) => [
24519
- normalizeConversationRailProjectPath(project.path),
24520
- project
24521
- ])
24522
- );
24523
- const groupProjectPaths = /* @__PURE__ */ new Set();
24524
- const groupProjects = [];
24525
- for (const group of groups) {
24526
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24527
- if (!normalizedPath || groupProjectPaths.has(normalizedPath)) {
24528
- continue;
24529
- }
24530
- groupProjectPaths.add(normalizedPath);
24531
- const existingProject = userProjectByPath.get(normalizedPath);
24532
- groupProjects.push({
24533
- ...existingProject ?? {
24534
- id: `agent-session-group:${normalizedPath}`,
24535
- label: labelFromProjectPath(normalizedPath),
24536
- path: group.cwd
24537
- },
24538
- lastUsedAtUnixMs: group.latestSessionUpdatedAtUnixMs,
24539
- updatedAtUnixMs: group.latestSessionUpdatedAtUnixMs
24540
- });
24541
- }
24542
- const emptyUserProjects = userProjects.filter(
24543
- (project) => !groupProjectPaths.has(normalizeConversationRailProjectPath(project.path))
24544
- );
24545
- return [...groupProjects, ...emptyUserProjects];
24546
- }
24547
- function labelFromProjectPath(path) {
24548
- const normalized = normalizeConversationRailProjectPath(path);
24549
- if (!normalized || normalized === "/") {
24550
- return path || "/";
24551
- }
24552
- return normalized.split("/").filter(Boolean).at(-1) ?? normalized;
24553
- }
24554
25286
  function stabilizeConversationSections(previous, next) {
24555
25287
  if (!previous) {
24556
25288
  return [...next];
@@ -24584,37 +25316,6 @@ function stabilizeConversationSections(previous, next) {
24584
25316
  });
24585
25317
  return changed ? stable : previous;
24586
25318
  }
24587
- function mergeRefreshedRailSessionGroups(current, refreshed) {
24588
- const currentByCwd = new Map(current.map((group) => [group.cwd, group]));
24589
- return refreshed.map((group) => {
24590
- const existing = currentByCwd.get(group.cwd);
24591
- if (!existing || existing.sessions.length <= group.sessions.length) {
24592
- return group;
24593
- }
24594
- const sessionIds = new Set(
24595
- group.sessions.map((session) => session.agentSessionId)
24596
- );
24597
- const sessions = [...group.sessions];
24598
- for (const session of existing.sessions) {
24599
- if (sessions.length >= group.sessionCount) {
24600
- break;
24601
- }
24602
- if (sessionIds.has(session.agentSessionId)) {
24603
- continue;
24604
- }
24605
- sessionIds.add(session.agentSessionId);
24606
- sessions.push(session);
24607
- }
24608
- const preservedLoadedPages = sessions.length > group.sessions.length;
24609
- const hasMore = preservedLoadedPages ? existing.hasMore && sessions.length < group.sessionCount : group.hasMore;
24610
- return {
24611
- ...group,
24612
- hasMore,
24613
- nextCursor: hasMore ? preservedLoadedPages ? existing.nextCursor : group.nextCursor : void 0,
24614
- sessions
24615
- };
24616
- });
24617
- }
24618
25319
  function stabilizeConversationSectionItems(previous, next) {
24619
25320
  if (previous.length !== next.length) {
24620
25321
  const previousById = /* @__PURE__ */ new Map();
@@ -24651,11 +25352,163 @@ function conversationSyncStatesRenderEqual(left, right) {
24651
25352
  function conversationProjectsRenderEqual2(left, right) {
24652
25353
  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);
24653
25354
  }
25355
+ var agentGUIProviderRailOrder = [
25356
+ "nexight",
25357
+ "claude-code",
25358
+ "codex",
25359
+ "openclaw",
25360
+ "hermes",
25361
+ "gemini"
25362
+ ];
25363
+ function agentGUIProviderRailOrderIndex(provider) {
25364
+ const index = agentGUIProviderRailOrder.indexOf(provider);
25365
+ return index < 0 ? agentGUIProviderRailOrder.length : index;
25366
+ }
25367
+ function agentGUIProviderRailLabel(provider, targetLabel, labels) {
25368
+ if (targetLabel.trim() && targetLabel !== provider) {
25369
+ return targetLabel;
25370
+ }
25371
+ if (provider === "codex") {
25372
+ return labels.conversationFilterCodex;
25373
+ }
25374
+ if (provider === "claude-code") {
25375
+ return labels.conversationFilterClaudeCode;
25376
+ }
25377
+ return targetLabel;
25378
+ }
25379
+ function agentGUIProviderTargetMatchesConversationFilter(target, filter) {
25380
+ return filter.kind === "agentTarget" && (target.agentTargetId?.trim() ?? "") === filter.agentTargetId;
25381
+ }
25382
+ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25383
+ conversationFilter,
25384
+ labels,
25385
+ previewMode,
25386
+ providerTargets,
25387
+ providerTargetsLoading,
25388
+ onSelectConversationFilterTarget,
25389
+ onUpdateConversationFilter
25390
+ }) {
25391
+ "use memo";
25392
+ const providerTiles = useMemo10(() => {
25393
+ const enabledTargets = providerTargets.filter(
25394
+ (target) => target.disabled !== true
25395
+ );
25396
+ const targets = [...enabledTargets];
25397
+ const originalIndexByTarget = /* @__PURE__ */ new Map();
25398
+ targets.forEach((target, index) => {
25399
+ originalIndexByTarget.set(
25400
+ `${target.provider}\0${target.targetId}`,
25401
+ index
25402
+ );
25403
+ });
25404
+ return targets.sort((left, right) => {
25405
+ const orderDelta = agentGUIProviderRailOrderIndex(left.provider) - agentGUIProviderRailOrderIndex(right.provider);
25406
+ if (orderDelta !== 0) {
25407
+ return orderDelta;
25408
+ }
25409
+ return (originalIndexByTarget.get(`${left.provider}\0${left.targetId}`) ?? 0) - (originalIndexByTarget.get(
25410
+ `${right.provider}\0${right.targetId}`
25411
+ ) ?? 0);
25412
+ });
25413
+ }, [providerTargets]);
25414
+ const allTileSelected = conversationFilter.kind === "all";
25415
+ const selectAllProviders = useCallback10(() => {
25416
+ onUpdateConversationFilter({ kind: "all" });
25417
+ }, [onUpdateConversationFilter]);
25418
+ const selectProviderTile = useCallback10(
25419
+ (target) => {
25420
+ onSelectConversationFilterTarget({
25421
+ provider: target.provider,
25422
+ providerTargetId: target.targetId
25423
+ });
25424
+ },
25425
+ [onSelectConversationFilterTarget]
25426
+ );
25427
+ return /* @__PURE__ */ jsxs17(
25428
+ "div",
25429
+ {
25430
+ className: AgentGUINode_styles_default.providerRail,
25431
+ role: "tablist",
25432
+ "aria-label": labels.providerSwitchLabel,
25433
+ "aria-busy": providerTargetsLoading,
25434
+ children: [
25435
+ /* @__PURE__ */ jsxs17(
25436
+ "button",
25437
+ {
25438
+ type: "button",
25439
+ role: "tab",
25440
+ "aria-selected": allTileSelected,
25441
+ className: AgentGUINode_styles_default.providerRailTile,
25442
+ "data-selected": allTileSelected ? "true" : "false",
25443
+ disabled: previewMode,
25444
+ onClick: selectAllProviders,
25445
+ children: [
25446
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(LayoutGrid, { "aria-hidden": true, className: AgentGUINode_styles_default.providerRailAvatarIcon }) }),
25447
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: labels.conversationFilterAll })
25448
+ ]
25449
+ }
25450
+ ),
25451
+ providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsxs17(
25452
+ "button",
25453
+ {
25454
+ type: "button",
25455
+ role: "tab",
25456
+ "aria-selected": "false",
25457
+ className: AgentGUINode_styles_default.providerRailTile,
25458
+ "data-loading": "true",
25459
+ "data-selected": "false",
25460
+ disabled: true,
25461
+ children: [
25462
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar }),
25463
+ /* @__PURE__ */ jsx31(
25464
+ "span",
25465
+ {
25466
+ "aria-hidden": "true",
25467
+ className: AgentGUINode_styles_default.providerRailTileLabel
25468
+ }
25469
+ )
25470
+ ]
25471
+ },
25472
+ `provider-target-loading-${index}`
25473
+ )) : null,
25474
+ providerTiles.map((target) => {
25475
+ const providerSelected = agentGUIProviderTargetMatchesConversationFilter(
25476
+ target,
25477
+ conversationFilter
25478
+ );
25479
+ return /* @__PURE__ */ jsxs17(
25480
+ "button",
25481
+ {
25482
+ type: "button",
25483
+ role: "tab",
25484
+ "aria-selected": providerSelected,
25485
+ className: AgentGUINode_styles_default.providerRailTile,
25486
+ "data-selected": providerSelected ? "true" : "false",
25487
+ disabled: previewMode,
25488
+ onClick: () => selectProviderTile(target),
25489
+ children: [
25490
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
25491
+ "img",
25492
+ {
25493
+ alt: "",
25494
+ "aria-hidden": "true",
25495
+ className: AgentGUINode_styles_default.providerRailAvatarImage,
25496
+ src: target.iconUrl || resolveAgentGUIHeroIconUrl(target.provider)
25497
+ }
25498
+ ) }),
25499
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: agentGUIProviderRailLabel(target.provider, target.label, labels) })
25500
+ ]
25501
+ },
25502
+ `${target.provider}:${target.targetId}`
25503
+ );
25504
+ })
25505
+ ]
25506
+ }
25507
+ );
25508
+ });
24654
25509
  var AgentGUIConversationRailPane = memo(
24655
25510
  function AgentGUIConversationRailPane2({
24656
25511
  conversations,
24657
- provider,
24658
- workspaceId,
24659
25512
  userProjects,
24660
25513
  activeConversationId,
24661
25514
  pendingDeleteConversationId,
@@ -24669,7 +25522,14 @@ var AgentGUIConversationRailPane = memo(
24669
25522
  createConversationDisabled,
24670
25523
  openclawGateway,
24671
25524
  isCollapsed,
25525
+ railConfigProvider,
24672
25526
  slashStatusLimits,
25527
+ providerTargets,
25528
+ providerTargetsLoading,
25529
+ conversationScope,
25530
+ conversationFilter,
25531
+ onUpdateConversationFilter,
25532
+ onSelectConversationFilterTarget,
24673
25533
  onCreateConversation,
24674
25534
  onOpenAgentEnvSetup,
24675
25535
  onRetryOpenclawGateway,
@@ -24686,21 +25546,14 @@ var AgentGUIConversationRailPane = memo(
24686
25546
  onConfirmDeleteConversation
24687
25547
  }) {
24688
25548
  "use memo";
24689
- const agentActivityRuntime = useAgentActivityRuntime();
25549
+ const showProviderRail = conversationScope === "multi-provider";
24690
25550
  const [conversationQuery, setConversationQuery] = useState11("");
24691
- const [searchConversations, setSearchConversations] = useState11([]);
24692
- const [searchConversationQuery, setSearchConversationQuery] = useState11("");
24693
- const [searchHasMore, setSearchHasMore] = useState11(false);
24694
- const [searchNextCursor, setSearchNextCursor] = useState11(
24695
- null
25551
+ const updateConversationFilter = useStableEventCallback2(
25552
+ onUpdateConversationFilter
25553
+ );
25554
+ const selectConversationFilterTarget = useStableEventCallback2(
25555
+ onSelectConversationFilterTarget
24696
25556
  );
24697
- const [
24698
- isLoadingMoreSearchConversations,
24699
- setIsLoadingMoreSearchConversations
24700
- ] = useState11(false);
24701
- const [railSessionGroups, setRailSessionGroups] = useState11([]);
24702
- const [activeConversationOverlay, setActiveConversationOverlay] = useState11(null);
24703
- const [loadingMoreSectionIds, setLoadingMoreSectionIds] = useState11(() => /* @__PURE__ */ new Set());
24704
25557
  const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState11(() => /* @__PURE__ */ new Set());
24705
25558
  const [currentTimeMs, setCurrentTimeMs] = useState11(() => Date.now());
24706
25559
  const [pendingProjectAction, setPendingProjectAction] = useState11(null);
@@ -24710,7 +25563,6 @@ var AgentGUIConversationRailPane = memo(
24710
25563
  /* @__PURE__ */ new Map()
24711
25564
  );
24712
25565
  const groupedConversationsRef = useRef12(null);
24713
- const wasDeletingConversationRef = useRef12(false);
24714
25566
  useEffect12(() => {
24715
25567
  const timer = window.setInterval(() => {
24716
25568
  setCurrentTimeMs(Date.now());
@@ -24719,217 +25571,25 @@ var AgentGUIConversationRailPane = memo(
24719
25571
  window.clearInterval(timer);
24720
25572
  };
24721
25573
  }, []);
24722
- const trimmedConversationQuery = conversationQuery.trim();
24723
- const hasConversationQuery = trimmedConversationQuery.length > 0;
24724
- const hasRuntimeGroupSource = !previewMode && Boolean(agentActivityRuntime.listSessionGroups);
24725
- const conversationIdentityKey = useMemo10(
24726
- () => conversations.map((conversation) => conversation.id).join("|"),
24727
- [conversations]
24728
- );
24729
- const railSessionGroupProjects = useMemo10(
24730
- () => buildRailSessionGroupProjects({
24731
- groups: railSessionGroups,
24732
- userProjects
24733
- }),
24734
- [railSessionGroups, userProjects]
24735
- );
24736
- const defaultRailGroupConversations = useMemo10(() => {
24737
- const freshConversationById = new Map(
24738
- conversations.map((conversation) => [conversation.id, conversation])
24739
- );
24740
- return buildAgentGUIConversationSummaries({
24741
- provider,
24742
- snapshot: {
24743
- composerOptionsByProvider: {},
24744
- presences: [],
24745
- sessionMessagesById: {},
24746
- sessions: railSessionGroups.flatMap((group) => group.sessions),
24747
- workspaceId
24748
- },
24749
- userProjects: railSessionGroupProjects
24750
- }).map(
24751
- (conversation) => freshConversationById.get(conversation.id) ?? conversation
24752
- );
24753
- }, [
24754
- conversations,
24755
- provider,
24756
- railSessionGroupProjects,
24757
- railSessionGroups,
24758
- workspaceId
24759
- ]);
24760
- const defaultRailSourceConversations = useMemo10(() => {
24761
- const source = hasRuntimeGroupSource ? defaultRailGroupConversations : conversations;
24762
- if (!activeConversationOverlay || source.some((item) => item.id === activeConversationOverlay.id)) {
24763
- return source;
24764
- }
24765
- return [...source, activeConversationOverlay];
24766
- }, [
24767
- activeConversationOverlay,
24768
- conversations,
24769
- defaultRailGroupConversations,
24770
- hasRuntimeGroupSource
24771
- ]);
24772
- const effectiveSearchConversations = searchConversationQuery === trimmedConversationQuery ? searchConversations : [];
24773
- const railSourceConversations = hasConversationQuery ? effectiveSearchConversations : defaultRailSourceConversations;
24774
- const runtimeSearchSessions = agentActivityRuntime.searchSessions;
24775
- useEffect12(() => {
24776
- if (!activeConversationOverlay || activeConversationOverlay.id !== activeConversationId) {
24777
- return;
24778
- }
24779
- if (defaultRailGroupConversations.some(
24780
- (item) => item.id === activeConversationOverlay.id
24781
- )) {
24782
- setActiveConversationOverlay(null);
24783
- }
24784
- }, [
24785
- activeConversationId,
24786
- activeConversationOverlay,
24787
- defaultRailGroupConversations
24788
- ]);
24789
- useEffect12(() => {
24790
- if (!hasConversationQuery) {
24791
- setSearchConversationQuery("");
24792
- setSearchConversations([]);
24793
- setSearchHasMore(false);
24794
- setSearchNextCursor(null);
24795
- return;
24796
- }
24797
- if (!runtimeSearchSessions) {
24798
- return;
24799
- }
24800
- let disposed = false;
24801
- const timer = window.setTimeout(() => {
24802
- void runtimeSearchSessions({
24803
- limit: 100,
24804
- query: trimmedConversationQuery,
24805
- workspaceId
24806
- }).then((result) => {
24807
- if (disposed) {
24808
- return;
24809
- }
24810
- setSearchConversationQuery(trimmedConversationQuery);
24811
- setSearchConversations(
24812
- buildAgentGUIConversationSummaries({
24813
- provider,
24814
- snapshot: {
24815
- composerOptionsByProvider: {},
24816
- presences: [],
24817
- sessionMessagesById: {},
24818
- sessions: result.sessions,
24819
- workspaceId: result.workspaceId
24820
- },
24821
- userProjects
24822
- })
24823
- );
24824
- setSearchHasMore(result.hasMore);
24825
- setSearchNextCursor(result.nextCursor ?? null);
24826
- }).catch(() => {
24827
- if (!disposed) {
24828
- setSearchConversationQuery(trimmedConversationQuery);
24829
- setSearchConversations([]);
24830
- setSearchHasMore(false);
24831
- setSearchNextCursor(null);
24832
- }
24833
- });
24834
- }, 150);
24835
- return () => {
24836
- disposed = true;
24837
- window.clearTimeout(timer);
24838
- };
24839
- }, [
24840
- hasConversationQuery,
24841
- provider,
24842
- runtimeSearchSessions,
24843
- trimmedConversationQuery,
24844
- userProjects,
24845
- workspaceId
24846
- ]);
24847
- useEffect12(() => {
24848
- if (!hasConversationQuery || runtimeSearchSessions) {
24849
- return;
24850
- }
24851
- setSearchConversationQuery(trimmedConversationQuery);
24852
- setSearchConversations(
24853
- conversations.filter(
24854
- (candidate) => conversationPlainTitle(candidate, labels, uiLanguage).toLowerCase().includes(trimmedConversationQuery.toLowerCase())
24855
- )
24856
- );
24857
- setSearchHasMore(false);
24858
- setSearchNextCursor(null);
24859
- }, [
24860
- conversations,
24861
- hasConversationQuery,
24862
- labels,
24863
- runtimeSearchSessions,
24864
- trimmedConversationQuery,
24865
- uiLanguage
24866
- ]);
24867
- useEffect12(() => {
24868
- if (!agentActivityRuntime.listSessionGroups || previewMode) {
24869
- setRailSessionGroups([]);
24870
- return;
24871
- }
24872
- let disposed = false;
24873
- const isDeletingNow = isDeletingConversation || isDeletingProjectConversations;
24874
- const resetLoadedGroups = wasDeletingConversationRef.current && !isDeletingNow;
24875
- wasDeletingConversationRef.current = isDeletingNow;
24876
- void agentActivityRuntime.listSessionGroups({
24877
- sessionLimit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
24878
- visibleOnly: true,
24879
- workspaceId
24880
- }).then((result) => {
24881
- if (!disposed) {
24882
- setRailSessionGroups(
24883
- (current) => resetLoadedGroups ? result.groups : mergeRefreshedRailSessionGroups(current, result.groups)
24884
- );
24885
- }
24886
- }).catch(() => {
24887
- if (!disposed) {
24888
- setRailSessionGroups([]);
24889
- }
24890
- });
24891
- return () => {
24892
- disposed = true;
24893
- };
24894
- }, [
24895
- agentActivityRuntime,
24896
- conversationIdentityKey,
24897
- isDeletingConversation,
24898
- isDeletingProjectConversations,
24899
- previewMode,
24900
- workspaceId
24901
- ]);
24902
- const groupingProjects = hasConversationQuery ? [] : hasRuntimeGroupSource ? railSessionGroupProjects : userProjects;
24903
- const showEmptyConversationSection = useMemo10(
24904
- () => !hasConversationQuery && (hasRuntimeGroupSource ? railSessionGroups.some((group) => !group.cwd.trim()) : !conversations.some(
24905
- (conversation) => conversation.project == null
24906
- )),
24907
- [
24908
- conversations,
24909
- hasConversationQuery,
24910
- hasRuntimeGroupSource,
24911
- railSessionGroups
24912
- ]
24913
- );
24914
25574
  const filteredConversationResult = useMemo10(() => {
24915
25575
  const startedAtMs = agentGuiPerfNowMs();
24916
- const query = trimmedConversationQuery.toLowerCase();
24917
- const items = !query ? railSourceConversations : railSourceConversations.filter(
25576
+ const query = conversationQuery.trim().toLowerCase();
25577
+ const items = !query ? conversations : conversations.filter(
24918
25578
  (candidate) => conversationPlainTitle(candidate, labels, uiLanguage).toLowerCase().includes(query)
24919
25579
  );
24920
25580
  return {
24921
25581
  items,
24922
25582
  filterMs: roundAgentGuiPerfMs(agentGuiPerfNowMs() - startedAtMs)
24923
25583
  };
24924
- }, [labels, railSourceConversations, trimmedConversationQuery, uiLanguage]);
25584
+ }, [conversationQuery, conversations, labels, uiLanguage]);
24925
25585
  const filteredConversations = filteredConversationResult.items;
24926
25586
  const groupedConversationResult = useMemo10(() => {
24927
25587
  const startedAtMs = agentGuiPerfNowMs();
24928
25588
  const rawGroups = groupConversations(
24929
25589
  filteredConversations,
24930
25590
  labels,
24931
- groupingProjects,
24932
- { includeEmptyConversations: showEmptyConversationSection }
25591
+ conversationQuery.trim() ? [] : userProjects,
25592
+ { includeEmptyConversations: !conversationQuery.trim() }
24933
25593
  );
24934
25594
  const groups = stabilizeConversationSections(
24935
25595
  groupedConversationsRef.current,
@@ -24940,12 +25600,7 @@ var AgentGUIConversationRailPane = memo(
24940
25600
  groups,
24941
25601
  groupMs: roundAgentGuiPerfMs(agentGuiPerfNowMs() - startedAtMs)
24942
25602
  };
24943
- }, [
24944
- filteredConversations,
24945
- groupingProjects,
24946
- labels,
24947
- showEmptyConversationSection
24948
- ]);
25603
+ }, [conversationQuery, filteredConversations, labels, userProjects]);
24949
25604
  const groupedConversations = groupedConversationResult.groups;
24950
25605
  const toggleProjectSectionCollapsed = useCallback10((sectionId) => {
24951
25606
  setCollapsedProjectSectionIds((current) => {
@@ -24966,140 +25621,17 @@ var AgentGUIConversationRailPane = memo(
24966
25621
  );
24967
25622
  const projectConversationCountsByPath = useMemo10(() => {
24968
25623
  const counts = /* @__PURE__ */ new Map();
24969
- const pathsFromGroups = /* @__PURE__ */ new Set();
24970
- for (const group of railSessionGroups) {
24971
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24972
- if (!normalizedPath) {
24973
- continue;
24974
- }
24975
- counts.set(normalizedPath, group.sessionCount);
24976
- pathsFromGroups.add(normalizedPath);
24977
- }
24978
25624
  for (const conversation of conversations) {
24979
25625
  const normalizedPath = normalizeConversationRailProjectPath(
24980
25626
  conversation.project?.path
24981
25627
  );
24982
- if (!normalizedPath || pathsFromGroups.has(normalizedPath)) {
25628
+ if (!normalizedPath) {
24983
25629
  continue;
24984
25630
  }
24985
25631
  counts.set(normalizedPath, (counts.get(normalizedPath) ?? 0) + 1);
24986
25632
  }
24987
25633
  return counts;
24988
- }, [conversations, railSessionGroups]);
24989
- const railSessionGroupBySectionId = useMemo10(() => {
24990
- const groupsBySectionId = /* @__PURE__ */ new Map();
24991
- for (const group of railSessionGroups) {
24992
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24993
- groupsBySectionId.set(
24994
- normalizedPath ? `project:${normalizedPath}` : "conversations",
24995
- group
24996
- );
24997
- }
24998
- return groupsBySectionId;
24999
- }, [railSessionGroups]);
25000
- const loadMoreSectionConversations = useCallback10(
25001
- (sectionId) => {
25002
- const group = railSessionGroupBySectionId.get(sectionId);
25003
- const listSessionsPage = agentActivityRuntime.listSessionsPage;
25004
- if (!group?.hasMore || !group.nextCursor || !listSessionsPage) {
25005
- return;
25006
- }
25007
- setLoadingMoreSectionIds((current) => {
25008
- if (current.has(sectionId)) {
25009
- return current;
25010
- }
25011
- const next = new Set(current);
25012
- next.add(sectionId);
25013
- return next;
25014
- });
25015
- void listSessionsPage({
25016
- cursor: group.nextCursor,
25017
- cwd: group.cwd,
25018
- limit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
25019
- visibleOnly: true,
25020
- workspaceId
25021
- }).then((page) => {
25022
- setRailSessionGroups(
25023
- (current) => current.map((candidate) => {
25024
- if (candidate.cwd !== group.cwd) {
25025
- return candidate;
25026
- }
25027
- const sessionIds = new Set(
25028
- candidate.sessions.map((session) => session.agentSessionId)
25029
- );
25030
- const nextSessions = [...candidate.sessions];
25031
- for (const session of page.sessions) {
25032
- if (!sessionIds.has(session.agentSessionId)) {
25033
- sessionIds.add(session.agentSessionId);
25034
- nextSessions.push(session);
25035
- }
25036
- }
25037
- return {
25038
- ...candidate,
25039
- hasMore: page.hasMore,
25040
- nextCursor: page.nextCursor,
25041
- sessions: nextSessions
25042
- };
25043
- })
25044
- );
25045
- }).finally(() => {
25046
- setLoadingMoreSectionIds((current) => {
25047
- if (!current.has(sectionId)) {
25048
- return current;
25049
- }
25050
- const next = new Set(current);
25051
- next.delete(sectionId);
25052
- return next;
25053
- });
25054
- });
25055
- },
25056
- [agentActivityRuntime, railSessionGroupBySectionId, workspaceId]
25057
- );
25058
- const loadMoreSearchConversations = useCallback10(() => {
25059
- const searchSessions = agentActivityRuntime.searchSessions;
25060
- if (!searchSessions || !searchHasMore || !searchNextCursor || isLoadingMoreSearchConversations) {
25061
- return;
25062
- }
25063
- setIsLoadingMoreSearchConversations(true);
25064
- void searchSessions({
25065
- cursor: searchNextCursor,
25066
- limit: 100,
25067
- query: trimmedConversationQuery,
25068
- workspaceId
25069
- }).then((result) => {
25070
- const nextConversations = buildAgentGUIConversationSummaries({
25071
- provider,
25072
- snapshot: {
25073
- composerOptionsByProvider: {},
25074
- presences: [],
25075
- sessionMessagesById: {},
25076
- sessions: result.sessions,
25077
- workspaceId: result.workspaceId
25078
- },
25079
- userProjects
25080
- });
25081
- setSearchConversations((current) => {
25082
- const currentIds = new Set(current.map((item) => item.id));
25083
- return [
25084
- ...current,
25085
- ...nextConversations.filter((item) => !currentIds.has(item.id))
25086
- ];
25087
- });
25088
- setSearchHasMore(result.hasMore);
25089
- setSearchNextCursor(result.nextCursor ?? null);
25090
- }).finally(() => {
25091
- setIsLoadingMoreSearchConversations(false);
25092
- });
25093
- }, [
25094
- agentActivityRuntime,
25095
- isLoadingMoreSearchConversations,
25096
- provider,
25097
- searchHasMore,
25098
- searchNextCursor,
25099
- trimmedConversationQuery,
25100
- userProjects,
25101
- workspaceId
25102
- ]);
25634
+ }, [conversations]);
25103
25635
  const registerConversationItemElement = useCallback10(
25104
25636
  (itemId, element) => {
25105
25637
  if (element) {
@@ -25110,46 +25642,6 @@ var AgentGUIConversationRailPane = memo(
25110
25642
  },
25111
25643
  []
25112
25644
  );
25113
- const handleSelectConversation = useCallback10(
25114
- (agentSessionId) => {
25115
- const normalizedAgentSessionId = agentSessionId.trim();
25116
- if (!normalizedAgentSessionId) {
25117
- return;
25118
- }
25119
- const isLoadedConversation = conversations.some(
25120
- (conversation) => conversation.id === normalizedAgentSessionId
25121
- );
25122
- if (!hasConversationQuery || isLoadedConversation) {
25123
- onSelectConversation(normalizedAgentSessionId);
25124
- return;
25125
- }
25126
- void agentActivityRuntime.getSession(workspaceId, normalizedAgentSessionId).then((session) => {
25127
- const [overlay] = buildAgentGUIConversationSummaries({
25128
- provider,
25129
- snapshot: {
25130
- composerOptionsByProvider: {},
25131
- presences: [],
25132
- sessionMessagesById: {},
25133
- sessions: [session],
25134
- workspaceId
25135
- },
25136
- userProjects: railSessionGroupProjects
25137
- });
25138
- setActiveConversationOverlay(overlay ?? null);
25139
- onSelectConversation(normalizedAgentSessionId);
25140
- }).catch(() => {
25141
- });
25142
- },
25143
- [
25144
- agentActivityRuntime,
25145
- conversations,
25146
- hasConversationQuery,
25147
- onSelectConversation,
25148
- provider,
25149
- railSessionGroupProjects,
25150
- workspaceId
25151
- ]
25152
- );
25153
25645
  useLayoutEffect4(() => {
25154
25646
  if (!activeConversationId) {
25155
25647
  return;
@@ -25189,6 +25681,18 @@ var AgentGUIConversationRailPane = memo(
25189
25681
  }
25190
25682
  )
25191
25683
  ] }),
25684
+ showProviderRail ? /* @__PURE__ */ jsx31(
25685
+ AgentGUIProviderRail,
25686
+ {
25687
+ conversationFilter,
25688
+ labels,
25689
+ previewMode,
25690
+ providerTargets,
25691
+ providerTargetsLoading,
25692
+ onSelectConversationFilterTarget: selectConversationFilterTarget,
25693
+ onUpdateConversationFilter: updateConversationFilter
25694
+ }
25695
+ ) : null,
25192
25696
  openclawGateway?.status === "starting" ? /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.gatewayStatus, "data-state": "starting", children: [
25193
25697
  /* @__PURE__ */ jsx31(
25194
25698
  StatusDot,
@@ -25232,9 +25736,6 @@ var AgentGUIConversationRailPane = memo(
25232
25736
  const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
25233
25737
  const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
25234
25738
  const projectConversationCount = normalizedProjectPath ? projectConversationCountsByPath.get(normalizedProjectPath) ?? 0 : 0;
25235
- const sectionSessionGroup = railSessionGroupBySectionId.get(
25236
- section.id
25237
- );
25238
25739
  return /* @__PURE__ */ jsxs17(Fragment7, { children: [
25239
25740
  showProjectRailHeader ? /* @__PURE__ */ jsx31(
25240
25741
  AgentGUIProjectRailHeader,
@@ -25251,13 +25752,11 @@ var AgentGUIConversationRailPane = memo(
25251
25752
  createConversationDisabled,
25252
25753
  currentTimeMs,
25253
25754
  isDeletingConversation,
25254
- isLoadingMoreConversations: hasConversationQuery ? isLoadingMoreSearchConversations : loadingMoreSectionIds.has(section.id),
25255
25755
  isSectionCollapsed,
25256
25756
  labels,
25257
25757
  pendingDeleteConversationId,
25258
25758
  previewMode,
25259
25759
  projectConversationCount,
25260
- sectionHasMore: hasConversationQuery ? searchHasMore : Boolean(sectionSessionGroup?.hasMore),
25261
25760
  projectLabel,
25262
25761
  projectPath,
25263
25762
  registerItemElement: registerConversationItemElement,
@@ -25267,12 +25766,11 @@ var AgentGUIConversationRailPane = memo(
25267
25766
  onConfirmDeleteConversation,
25268
25767
  onCreateConversation,
25269
25768
  onRequestDeleteConversation,
25270
- onSelectConversation: handleSelectConversation,
25769
+ onSelectConversation,
25271
25770
  setPendingProjectAction,
25272
25771
  onToggleConversationPinned,
25273
25772
  onOpenProjectFiles,
25274
25773
  onOpenConversationWindow,
25275
- onLoadMoreConversations: hasConversationQuery ? loadMoreSearchConversations : loadMoreSectionConversations,
25276
25774
  onToggleProjectSectionCollapsed: toggleProjectSectionCollapsed
25277
25775
  }
25278
25776
  )
@@ -25280,7 +25778,7 @@ var AgentGUIConversationRailPane = memo(
25280
25778
  })
25281
25779
  }
25282
25780
  ),
25283
- /* @__PURE__ */ jsx31("div", { className: "shrink-0 px-2 py-1.5", children: /* @__PURE__ */ jsxs17(Popover, { children: [
25781
+ railConfigProvider ? /* @__PURE__ */ jsx31("div", { className: "shrink-0 px-2 py-1.5", children: /* @__PURE__ */ jsxs17(Popover, { children: [
25284
25782
  /* @__PURE__ */ jsx31(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs17(
25285
25783
  Button,
25286
25784
  {
@@ -25342,7 +25840,7 @@ var AgentGUIConversationRailPane = memo(
25342
25840
  ] })
25343
25841
  }
25344
25842
  )
25345
- ] }) }),
25843
+ ] }) }) : null,
25346
25844
  /* @__PURE__ */ jsx31(
25347
25845
  ConfirmationDialog,
25348
25846
  {
@@ -25402,8 +25900,6 @@ var AgentGUIConversationRailSection = memo(
25402
25900
  pendingDeleteConversationId,
25403
25901
  previewMode,
25404
25902
  isDeletingConversation,
25405
- isLoadingMoreConversations,
25406
- sectionHasMore,
25407
25903
  createConversationDisabled,
25408
25904
  currentTimeMs,
25409
25905
  labels,
@@ -25412,7 +25908,6 @@ var AgentGUIConversationRailSection = memo(
25412
25908
  onCreateConversation,
25413
25909
  onToggleProjectSectionCollapsed,
25414
25910
  onSelectConversation,
25415
- onLoadMoreConversations,
25416
25911
  setPendingProjectAction,
25417
25912
  onToggleConversationPinned,
25418
25913
  onOpenProjectFiles,
@@ -25428,29 +25923,16 @@ var AgentGUIConversationRailSection = memo(
25428
25923
  );
25429
25924
  const visibleItemCount = isSectionCollapsed ? 0 : Math.min(visibleItemLimit, section.items.length);
25430
25925
  const visibleItems = isSectionCollapsed ? [] : section.items.slice(0, visibleItemCount);
25431
- const canShowMore = !isSectionCollapsed && (visibleItemCount < section.items.length || sectionHasMore);
25926
+ const canShowMore = !isSectionCollapsed && visibleItemCount < section.items.length;
25432
25927
  const canShowLess = !isSectionCollapsed && visibleItemCount > AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE;
25433
25928
  const showMoreConversations = useCallback10(() => {
25434
- if (visibleItemCount >= section.items.length && sectionHasMore) {
25435
- onLoadMoreConversations(section.id);
25436
- setVisibleItemLimit(
25437
- (current) => current + AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
25438
- );
25439
- return;
25440
- }
25441
25929
  setVisibleItemLimit(
25442
25930
  (current) => Math.min(
25443
25931
  section.items.length,
25444
25932
  current + AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
25445
25933
  )
25446
25934
  );
25447
- }, [
25448
- onLoadMoreConversations,
25449
- section.id,
25450
- section.items.length,
25451
- sectionHasMore,
25452
- visibleItemCount
25453
- ]);
25935
+ }, [section.items.length]);
25454
25936
  const showLessConversations = useCallback10(() => {
25455
25937
  setVisibleItemLimit(AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE);
25456
25938
  }, []);
@@ -25743,7 +26225,6 @@ var AgentGUIConversationRailSection = memo(
25743
26225
  {
25744
26226
  type: "button",
25745
26227
  className: AgentGUINode_styles_default.conversationSectionPaginationButton,
25746
- disabled: isLoadingMoreConversations,
25747
26228
  onClick: showMoreConversations,
25748
26229
  children: labels.showMoreConversations
25749
26230
  }
@@ -26196,6 +26677,10 @@ function formatQuotaPrimaryLine(row, t) {
26196
26677
  }
26197
26678
  function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
26198
26679
  if (probe.lastError?.code === "unsupported") {
26680
+ lines.push({
26681
+ label: t("agentHost.workspaceAgentProbeDetailQuota"),
26682
+ primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
26683
+ });
26199
26684
  return;
26200
26685
  }
26201
26686
  if (isLoadingUsage && !probe.usage) {
@@ -26204,6 +26689,12 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
26204
26689
  }
26205
26690
  const quotas = probe.usage?.quotas ?? [];
26206
26691
  if (quotas.length === 0) {
26692
+ if (probe.usage) {
26693
+ lines.push({
26694
+ label: t("agentHost.workspaceAgentProbeDetailQuota"),
26695
+ primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
26696
+ });
26697
+ }
26207
26698
  return;
26208
26699
  }
26209
26700
  const rows = buildCompactDisplayQuotas(quotas, t);
@@ -26644,11 +27135,11 @@ function slashStatusQuotasFromRuntimeUsage(value) {
26644
27135
  return null;
26645
27136
  }
26646
27137
  const normalized = { quotaType };
26647
- const percentRemaining = numberValue2(record.percentRemaining);
27138
+ const percentRemaining = numberValue3(record.percentRemaining);
26648
27139
  if (percentRemaining !== null) {
26649
27140
  normalized.percentRemaining = percentRemaining;
26650
27141
  }
26651
- const resetsAtUnixMs = numberValue2(record.resetsAtUnixMs);
27142
+ const resetsAtUnixMs = numberValue3(record.resetsAtUnixMs);
26652
27143
  if (resetsAtUnixMs !== null) {
26653
27144
  normalized.resetsAtUnixMs = resetsAtUnixMs;
26654
27145
  }
@@ -26656,7 +27147,7 @@ function slashStatusQuotasFromRuntimeUsage(value) {
26656
27147
  if (resetText) {
26657
27148
  normalized.resetText = resetText;
26658
27149
  }
26659
- const dollarRemaining = numberValue2(record.dollarRemaining);
27150
+ const dollarRemaining = numberValue3(record.dollarRemaining);
26660
27151
  if (dollarRemaining !== null) {
26661
27152
  normalized.dollarRemaining = dollarRemaining;
26662
27153
  }
@@ -26683,7 +27174,7 @@ function agentUsageQuotaTypeValue(value) {
26683
27174
  function objectRecord2(value) {
26684
27175
  return value && typeof value === "object" ? value : null;
26685
27176
  }
26686
- function numberValue2(value) {
27177
+ function numberValue3(value) {
26687
27178
  if (typeof value === "number" && Number.isFinite(value)) {
26688
27179
  return value;
26689
27180
  }
@@ -26710,13 +27201,29 @@ function filterSlashStatusQuotasForModel(quotas, selectedModel) {
26710
27201
  function normalizeSlashStatusModelName(value) {
26711
27202
  return value?.trim().toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") ?? "";
26712
27203
  }
27204
+ function resolveAgentGUIRailStatusProvider(input) {
27205
+ if (input.conversationScope !== "multi-provider") {
27206
+ return input.activeProvider;
27207
+ }
27208
+ const filter = input.conversationFilter;
27209
+ if (filter.kind !== "agentTarget") {
27210
+ return null;
27211
+ }
27212
+ const target = input.providerTargets.find(
27213
+ (candidate) => candidate.disabled !== true && (candidate.agentTargetId?.trim() ?? "") === filter.agentTargetId
27214
+ );
27215
+ return target ? target.provider : null;
27216
+ }
26713
27217
  function agentGuiStateEquals(left, right) {
26714
- return left === right || left.provider === right.provider && (left.providerTargetId ?? null) === (right.providerTargetId ?? null) && agentGUIProviderTargetRefsEqual(
27218
+ return left === right || left.provider === right.provider && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && (left.providerTargetId ?? null) === (right.providerTargetId ?? null) && agentGUIProviderTargetRefsEqual(
26715
27219
  left.providerTargetRef,
26716
27220
  right.providerTargetRef
26717
27221
  ) && left.lastActiveAgentSessionId === right.lastActiveAgentSessionId && left.conversationRailWidthPx === right.conversationRailWidthPx && left.conversationRailCollapsed === right.conversationRailCollapsed && (left.composerOverrides?.model ?? null) === (right.composerOverrides?.model ?? null) && (left.composerOverrides?.reasoningEffort ?? null) === (right.composerOverrides?.reasoningEffort ?? null) && (left.composerOverrides?.planMode ?? null) === (right.composerOverrides?.planMode ?? null) && (left.composerOverrides?.permissionModeId ?? null) === (right.composerOverrides?.permissionModeId ?? null) && composerOverridesByProviderEqual(
26718
27222
  left.composerOverridesByProvider,
26719
27223
  right.composerOverridesByProvider
27224
+ ) && composerOverridesByAgentTargetIdEqual(
27225
+ left.composerOverridesByAgentTargetId,
27226
+ right.composerOverridesByAgentTargetId
26720
27227
  );
26721
27228
  }
26722
27229
  function composerOverridesByProviderEqual(left, right) {
@@ -26734,12 +27241,26 @@ function composerOverridesByProviderEqual(left, right) {
26734
27241
  }
26735
27242
  return true;
26736
27243
  }
27244
+ function composerOverridesByAgentTargetIdEqual(left, right) {
27245
+ const keys = /* @__PURE__ */ new Set([
27246
+ ...Object.keys(left ?? {}),
27247
+ ...Object.keys(right ?? {})
27248
+ ]);
27249
+ for (const key of keys) {
27250
+ const leftSettings = left?.[key] ?? null;
27251
+ const rightSettings = right?.[key] ?? null;
27252
+ if ((leftSettings?.model ?? null) !== (rightSettings?.model ?? null) || (leftSettings?.reasoningEffort ?? null) !== (rightSettings?.reasoningEffort ?? null) || (leftSettings?.planMode ?? null) !== (rightSettings?.planMode ?? null) || (leftSettings?.permissionModeId ?? null) !== (rightSettings?.permissionModeId ?? null)) {
27253
+ return false;
27254
+ }
27255
+ }
27256
+ return true;
27257
+ }
26737
27258
  function areAgentGUINodePropsEqual(previous, next) {
26738
- return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.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 && workspaceAgentProbeRenderStateEqualsForProvider(
27259
+ return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.defaultProviderTargetId === next.defaultProviderTargetId && previous.conversationScope === next.conversationScope && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onRememberComposerDefaults === next.onRememberComposerDefaults && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && (previous.conversationScope === "multi-provider" || next.conversationScope === "multi-provider" ? previous.workspaceAgentProbes === next.workspaceAgentProbes : workspaceAgentProbeRenderStateEqualsForProvider(
26739
27260
  previous.workspaceAgentProbes,
26740
27261
  next.workspaceAgentProbes,
26741
27262
  previous.state.provider
26742
- ) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
27263
+ )) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
26743
27264
  }
26744
27265
  var AgentGUINode = memo2(function AgentGUINode2({
26745
27266
  nodeId,
@@ -26766,7 +27287,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
26766
27287
  onCapabilitySettingsRequest,
26767
27288
  onAgentProviderLogin,
26768
27289
  providerTargets,
27290
+ providerTargetsLoading = false,
26769
27291
  defaultProviderTargetId = null,
27292
+ conversationScope = "single-provider",
26770
27293
  onWorkspaceFileReferencesAdded,
26771
27294
  onOpenConversationWindow,
26772
27295
  onClose,
@@ -26923,9 +27446,11 @@ var AgentGUINode = memo2(function AgentGUINode2({
26923
27446
  workspacePath,
26924
27447
  avoidGroupingEdits: agentSettings.avoidGroupingEdits,
26925
27448
  data: state,
27449
+ conversationScope,
26926
27450
  openSessionRequest,
26927
27451
  prefillPromptRequest,
26928
27452
  providerTargets,
27453
+ providerTargetsLoading,
26929
27454
  defaultProviderTargetId,
26930
27455
  previewMode,
26931
27456
  onDataChange: handleDataChange,
@@ -26964,6 +27489,36 @@ var AgentGUINode = memo2(function AgentGUINode2({
26964
27489
  fallbackAgentLabel: fallbackAgentTitle,
26965
27490
  language: locale
26966
27491
  }) : null;
27492
+ useEffect14(() => {
27493
+ if (previewMode || !viewModel.activeConversation) {
27494
+ return;
27495
+ }
27496
+ const conversationTitle = activeConversationDockTitle?.trim() ?? "";
27497
+ if (!conversationTitle) {
27498
+ return;
27499
+ }
27500
+ const conversationId = viewModel.activeConversation.id;
27501
+ if (state.lastActiveAgentSessionId === conversationId && state.lastActiveConversationTitle === conversationTitle) {
27502
+ return;
27503
+ }
27504
+ onUpdateNode((current) => {
27505
+ if (current.lastActiveAgentSessionId === conversationId && current.lastActiveConversationTitle === conversationTitle) {
27506
+ return current;
27507
+ }
27508
+ return {
27509
+ ...current,
27510
+ lastActiveAgentSessionId: conversationId,
27511
+ lastActiveConversationTitle: conversationTitle
27512
+ };
27513
+ });
27514
+ }, [
27515
+ activeConversationDockTitle,
27516
+ onUpdateNode,
27517
+ previewMode,
27518
+ state.lastActiveAgentSessionId,
27519
+ state.lastActiveConversationTitle,
27520
+ viewModel.activeConversation
27521
+ ]);
26967
27522
  const labels = useMemo11(
26968
27523
  () => ({
26969
27524
  initialPlaceholder: t("agentHost.agentGui.initialPlaceholder", {
@@ -27094,6 +27649,12 @@ var AgentGUINode = memo2(function AgentGUINode2({
27094
27649
  emptyProjectConversations: t(
27095
27650
  "agentHost.agentGui.emptyProjectConversations"
27096
27651
  ),
27652
+ conversationFilterAll: t("agentHost.agentGui.conversationFilterAll"),
27653
+ conversationFilterCodex: t("agentHost.agentGui.conversationFilterCodex"),
27654
+ conversationFilterClaudeCode: t(
27655
+ "agentHost.agentGui.conversationFilterClaudeCode"
27656
+ ),
27657
+ providerSwitchLabel: t("agentHost.agentGui.providerSwitchLabel"),
27097
27658
  startConversation: t("agentHost.agentGui.startConversation"),
27098
27659
  selectConversation: t("agentHost.agentGui.selectConversation"),
27099
27660
  loadingConversations: t("agentHost.agentGui.loadingConversations"),
@@ -27208,6 +27769,10 @@ var AgentGUINode = memo2(function AgentGUINode2({
27208
27769
  submitAnswers: t("agentHost.agentGui.submitAnswers"),
27209
27770
  answerPlaceholder: t("agentHost.agentGui.answerPlaceholder"),
27210
27771
  waitingForAnswer: t("agentHost.agentGui.waitingForAnswer"),
27772
+ waitingForBackgroundAgent: (count) => {
27773
+ const pluralKey = count === 1 ? "agentHost.agentGui.waitingForBackgroundAgent_one" : "agentHost.agentGui.waitingForBackgroundAgent_other";
27774
+ return t(pluralKey, { count });
27775
+ },
27211
27776
  thinkingLabel: t("agentHost.workspaceAgentSessionDetailThinking"),
27212
27777
  toolCallsLabel: (count) => t("agentHost.workspaceAgentSessionDetailToolCalls", { count }),
27213
27778
  openConversationWindow: t("agentHost.agentGui.openConversationWindow"),
@@ -27418,42 +27983,24 @@ var AgentGUINode = memo2(function AgentGUINode2({
27418
27983
  }),
27419
27984
  [t]
27420
27985
  );
27421
- const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle ?? state.lastActiveConversationTitle ?? null : null;
27986
+ const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle : null;
27422
27987
  const windowTitle = collapsedWindowConversationTitle || (isConversationRailCollapsed ? activeConversationWindowTitle : null) || windowAgentTitle || title;
27423
27988
  const windowTitleIconUrl = agentGuiDockIconUrls[activeProvider] ?? null;
27424
- useEffect14(() => {
27425
- if (previewMode) {
27426
- return;
27427
- }
27428
- if (!viewModel.activeConversation) {
27429
- return;
27430
- }
27431
- const nextTitle = activeConversationDockTitle;
27432
- const previousTitle = state.lastActiveConversationTitle ?? null;
27433
- if (nextTitle === null && previousTitle !== null && viewModel.activeConversation.id === state.lastActiveAgentSessionId) {
27434
- return;
27435
- }
27436
- if ((state.lastActiveConversationTitle ?? null) === nextTitle) {
27437
- return;
27438
- }
27439
- onUpdateNode((current) => {
27440
- if ((current.lastActiveConversationTitle ?? null) === nextTitle) {
27441
- return current;
27442
- }
27443
- return {
27444
- ...current,
27445
- lastActiveConversationTitle: nextTitle
27446
- };
27447
- });
27448
- }, [
27449
- activeConversationDockTitle,
27450
- onUpdateNode,
27451
- previewMode,
27452
- state.lastActiveAgentSessionId,
27453
- state.lastActiveConversationTitle,
27454
- viewModel.activeConversation
27455
- ]);
27456
27989
  const activeProbeProvider = activeProvider;
27990
+ const railStatusProvider = useMemo11(
27991
+ () => resolveAgentGUIRailStatusProvider({
27992
+ activeProvider: activeProbeProvider,
27993
+ conversationFilter: viewModel.conversationFilter,
27994
+ conversationScope: viewModel.conversationScope,
27995
+ providerTargets: viewModel.providerTargets
27996
+ }),
27997
+ [
27998
+ activeProbeProvider,
27999
+ viewModel.conversationFilter,
28000
+ viewModel.conversationScope,
28001
+ viewModel.providerTargets
28002
+ ]
28003
+ );
27457
28004
  const activeAgentProbe = useMemo11(
27458
28005
  () => findWorkspaceAgentProbeForDockProvider(
27459
28006
  workspaceAgentProbes?.snapshot ?? null,
@@ -27461,6 +28008,13 @@ var AgentGUINode = memo2(function AgentGUINode2({
27461
28008
  ),
27462
28009
  [activeProbeProvider, workspaceAgentProbes?.snapshot]
27463
28010
  );
28011
+ const railAgentProbe = useMemo11(
28012
+ () => railStatusProvider ? findWorkspaceAgentProbeForDockProvider(
28013
+ workspaceAgentProbes?.snapshot ?? null,
28014
+ railStatusProvider
28015
+ ) : null,
28016
+ [railStatusProvider, workspaceAgentProbes?.snapshot]
28017
+ );
27464
28018
  const isActiveAgentProviderReady = useMemo11(() => {
27465
28019
  const managedAgent = getAgentHostManagedToolchainAgentByName(activeProbeProvider);
27466
28020
  if (!managedAgent) {
@@ -27494,6 +28048,11 @@ var AgentGUINode = memo2(function AgentGUINode2({
27494
28048
  viewModel.composerSettings.selectedModelValue
27495
28049
  ]
27496
28050
  );
28051
+ const railSlashStatusQuotaSource = railStatusProvider && railAgentProbe?.usage?.quotas && railAgentProbe.usage.quotas.length > 0 ? railAgentProbe.usage.quotas : [];
28052
+ const railSlashStatusLimits = useMemo11(
28053
+ () => slashStatusLimitsFromQuotas(railSlashStatusQuotaSource, null, t),
28054
+ [railSlashStatusQuotaSource, t]
28055
+ );
27497
28056
  const agentProbeLines = useMemo11(() => {
27498
28057
  return buildDockAgentProbeTooltipLines(
27499
28058
  activeAgentProbe,
@@ -27520,6 +28079,22 @@ var AgentGUINode = memo2(function AgentGUINode2({
27520
28079
  onAgentProbeDemandChange(null, probeSourceId);
27521
28080
  };
27522
28081
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
28082
+ useEffect14(() => {
28083
+ if (previewMode || !onAgentProbeDemandChange || !railStatusProvider || railStatusProvider === activeProbeProvider) {
28084
+ return;
28085
+ }
28086
+ const probeSourceId = `agent-gui:${nodeId}:rail`;
28087
+ onAgentProbeDemandChange(railStatusProvider, probeSourceId);
28088
+ return () => {
28089
+ onAgentProbeDemandChange(null, probeSourceId);
28090
+ };
28091
+ }, [
28092
+ activeProbeProvider,
28093
+ nodeId,
28094
+ onAgentProbeDemandChange,
28095
+ previewMode,
28096
+ railStatusProvider
28097
+ ]);
27523
28098
  const handleAgentProbeInfoOpen = useCallback12(() => {
27524
28099
  if (previewMode || !onAgentProbeRefreshRequest) {
27525
28100
  return;
@@ -27606,6 +28181,8 @@ var AgentGUINode = memo2(function AgentGUINode2({
27606
28181
  isAgentProviderReady: isActiveAgentProviderReady,
27607
28182
  slashStatusLimits,
27608
28183
  slashStatusLimitsLoading: workspaceAgentProbes?.isLoadingUsage ?? false,
28184
+ railConfigProvider: railStatusProvider,
28185
+ railSlashStatusLimits,
27609
28186
  previewMode,
27610
28187
  onLinkAction: handleLinkAction,
27611
28188
  capabilityMenuState,