@tutti-os/agent-gui 0.0.52 → 0.0.54

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 +33 -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 +136 -2
  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-7ZDLFTVL.js} +76 -7
  17. package/dist/chunk-7ZDLFTVL.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-EXZH66UE.js} +180 -88
  21. package/dist/chunk-EXZH66UE.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-JRA44NYI.js} +78 -4
  26. package/dist/chunk-JRA44NYI.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-ARCM7YB2.js → chunk-PBHTLI3E.js} +13 -3
  30. package/dist/{chunk-ARCM7YB2.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 +23 -53
  45. package/dist/index.js +945 -665
  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-EXZH66UE.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-7ZDLFTVL.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-ARCM7YB2.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-JRA44NYI.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 } : {},
@@ -4100,7 +4145,7 @@ function setAgentSessionViewDetailMessages(ref, nextMessages, options = {}) {
4100
4145
  return;
4101
4146
  }
4102
4147
  updateAgentSessionView(normalized, (current) => {
4103
- const detailMessages = mergeMessages([], nextMessages);
4148
+ const detailMessages = mergeMessages([], durableOnlyMessages(nextMessages));
4104
4149
  const oldestLoadedVersion = oldestMessageVersion(detailMessages);
4105
4150
  if (sameMessages(current.detailMessages, detailMessages) && current.oldestLoadedVersion === oldestLoadedVersion && current.hasOlderMessages === (options.hasOlderMessages ?? current.hasOlderMessages) && current.isLoadingOlderMessages === (options.isLoadingOlderMessages ?? current.isLoadingOlderMessages)) {
4106
4151
  return current;
@@ -4120,7 +4165,10 @@ function mergeAgentSessionViewDetailMessages(ref, nextMessages, options = {}) {
4120
4165
  return;
4121
4166
  }
4122
4167
  updateAgentSessionView(normalized, (current) => {
4123
- const detailMessages = mergeMessages(current.detailMessages, nextMessages);
4168
+ const detailMessages = mergeMessages(
4169
+ current.detailMessages,
4170
+ durableOnlyMessages(nextMessages)
4171
+ );
4124
4172
  const oldestLoadedVersion = oldestMessageVersion(detailMessages);
4125
4173
  if (sameMessages(current.detailMessages, detailMessages) && current.oldestLoadedVersion === oldestLoadedVersion && current.hasOlderMessages === (options.hasOlderMessages ?? current.hasOlderMessages) && current.isLoadingOlderMessages === (options.isLoadingOlderMessages ?? current.isLoadingOlderMessages)) {
4126
4174
  return current;
@@ -4581,8 +4629,13 @@ function sameMessages(left, right) {
4581
4629
  (item, index) => equivalentMessageValue(item, right[index])
4582
4630
  );
4583
4631
  }
4632
+ function durableOnlyMessages(messages) {
4633
+ return messages.filter(
4634
+ (message) => !isWorkspaceAgentActivityOptimisticMessage(message)
4635
+ );
4636
+ }
4584
4637
  function oldestMessageVersion(messages) {
4585
- const versions = messages.map((message) => message.version).filter((version) => Number.isFinite(version));
4638
+ const versions = messages.filter((message) => !isWorkspaceAgentActivityOptimisticMessage(message)).map((message) => message.version).filter((version) => Number.isFinite(version));
4586
4639
  return versions.length === 0 ? null : Math.min(...versions);
4587
4640
  }
4588
4641
  function equivalentMessageValue(left, right) {
@@ -4822,20 +4875,43 @@ function normalizeQuery(input) {
4822
4875
  return null;
4823
4876
  }
4824
4877
  return {
4878
+ conversationFilter: normalizeAgentGUIConversationListFilter(input),
4825
4879
  workspaceId,
4826
4880
  userId,
4827
4881
  provider,
4828
4882
  sessionOrigin
4829
4883
  };
4830
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
+ }
4831
4901
  function createAgentGUIConversationListQueryKey(input) {
4832
4902
  const normalized = normalizeQuery(input);
4833
- return normalized ? [
4903
+ if (!normalized) {
4904
+ return null;
4905
+ }
4906
+ const providerScope = normalized.conversationFilter ? "conversation-filter" : normalized.provider;
4907
+ const queryKey = [
4834
4908
  normalized.workspaceId,
4835
4909
  normalized.userId,
4836
- normalized.provider,
4910
+ providerScope,
4911
+ conversationFilterKey(normalized.conversationFilter, normalized.provider),
4837
4912
  normalized.sessionOrigin
4838
- ].join("::") : null;
4913
+ ].join("::");
4914
+ return queryKey;
4839
4915
  }
4840
4916
  function createEmptyQueryState(query) {
4841
4917
  const normalized = normalizeQuery(query);
@@ -5523,6 +5599,9 @@ function getWorkspaceAgentSnapshotForConversations(input) {
5523
5599
  const snapshot3 = getAgentActivityRuntime().getSnapshot(input.workspaceId);
5524
5600
  return workspaceAgentSnapshotForConversations(snapshot3);
5525
5601
  }
5602
+ function shouldUseCurrentWorkspaceAgentSnapshotForRefresh(reason) {
5603
+ return reason === "workspace-agent-update" || reason === "session-overlay-update";
5604
+ }
5526
5605
  async function refreshAgentGUIConversationListQuery(query, reason, options = {}) {
5527
5606
  const state = ensureQueryState(query);
5528
5607
  if (!state) {
@@ -5550,7 +5629,9 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5550
5629
  sessionOrigin: state.query.sessionOrigin,
5551
5630
  userId: state.query.userId
5552
5631
  };
5553
- 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(
5554
5635
  workspaceAgentsInput
5555
5636
  );
5556
5637
  if (requestId !== requestIdByQueryKey.get(queryKey)) {
@@ -5605,6 +5686,7 @@ async function refreshAgentGUIConversationListQuery(query, reason, options = {})
5605
5686
  return agentSessionId && dirtySessionIds.has(agentSessionId) || syncSessionId && dirtySessionIds.has(syncSessionId);
5606
5687
  }) : workspaceAgentSnapshot.sessions;
5607
5688
  const baseConversations = buildAgentGUIConversationSummaries({
5689
+ ...state.query.conversationFilter ? { conversationFilter: state.query.conversationFilter } : {},
5608
5690
  snapshot: canApplyDirtySessionProjection ? {
5609
5691
  ...workspaceAgentSnapshot,
5610
5692
  sessions: projectionSessions
@@ -6096,6 +6178,42 @@ function useAgentGuiConversationList(query) {
6096
6178
  );
6097
6179
  }
6098
6180
 
6181
+ // agent-gui/agentGuiNode/controller/agentGuiController.promptHelpers.ts
6182
+ function createOptimisticPromptMessage(input) {
6183
+ const clientSubmitMessageId = input.clientSubmitId ? createWorkspaceAgentActivityUserMessageIdFromClientSubmitId(
6184
+ input.clientSubmitId
6185
+ ) : null;
6186
+ return {
6187
+ id: 0,
6188
+ workspaceId: input.workspaceId,
6189
+ agentSessionId: input.agentSessionId,
6190
+ messageId: clientSubmitMessageId ?? `optimistic:user:${input.turnId}`,
6191
+ version: 0,
6192
+ turnId: input.turnId,
6193
+ role: "user",
6194
+ kind: "text",
6195
+ payload: {
6196
+ __agentGuiOptimisticPrompt: true,
6197
+ actorId: input.userId,
6198
+ ...input.clientSubmitId ? { clientSubmitId: input.clientSubmitId } : {},
6199
+ content: input.content,
6200
+ text: input.prompt
6201
+ },
6202
+ occurredAtUnixMs: input.occurredAtUnixMs,
6203
+ startedAtUnixMs: input.occurredAtUnixMs
6204
+ };
6205
+ }
6206
+ function normalizeOptionalText(value) {
6207
+ if (typeof value !== "string") {
6208
+ return null;
6209
+ }
6210
+ const trimmed = value.trim();
6211
+ return trimmed ? trimmed : null;
6212
+ }
6213
+ function recordValue(value) {
6214
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
6215
+ }
6216
+
6099
6217
  // agent-gui/agentGuiNode/controller/useAgentGUIActivation.ts
6100
6218
  import { useCallback as useCallback3, useMemo as useMemo3, useState as useState3 } from "react";
6101
6219
  function useAgentGUIActivation({
@@ -6127,6 +6245,7 @@ function useAgentGUIActivation({
6127
6245
  mode: input.mode,
6128
6246
  workspaceId,
6129
6247
  agentSessionId,
6248
+ agentTargetId: input.agentTargetId,
6130
6249
  provider: input.provider,
6131
6250
  cwd: input.cwd,
6132
6251
  initialContent: input.initialContent,
@@ -6305,18 +6424,6 @@ function composerSettingsSupportFromOptions(composerOptions, sessionRuntimeConte
6305
6424
  };
6306
6425
  }
6307
6426
 
6308
- // agent-gui/agentGuiNode/controller/agentGuiController.promptHelpers.ts
6309
- function normalizeOptionalText(value) {
6310
- if (typeof value !== "string") {
6311
- return null;
6312
- }
6313
- const trimmed = value.trim();
6314
- return trimmed ? trimmed : null;
6315
- }
6316
- function recordValue(value) {
6317
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
6318
- }
6319
-
6320
6427
  // agent-gui/agentGuiNode/controller/agentGuiController.composerHelpers.ts
6321
6428
  function normalizeConfigOptionValue(value) {
6322
6429
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -6449,7 +6556,8 @@ function buildNodeDefaultComposerSettings(data, options) {
6449
6556
  };
6450
6557
  }
6451
6558
  function nodeComposerOverridesForProvider(data) {
6452
- return data.composerOverridesByProvider?.[data.provider] ?? data.composerOverrides ?? null;
6559
+ const agentTargetId = normalizeOptionalText(data.agentTargetId);
6560
+ return (agentTargetId ? data.composerOverridesByAgentTargetId?.[agentTargetId] : null) ?? data.composerOverridesByProvider?.[data.provider] ?? data.composerOverrides ?? null;
6453
6561
  }
6454
6562
  function composerSupportForProvider(provider) {
6455
6563
  if (provider === "claude-code" || provider === "codex" || provider === "gemini") {
@@ -6481,6 +6589,16 @@ function nodeDataFromComposerSettings(current, settings) {
6481
6589
  computerUse: settings.computerUse,
6482
6590
  permissionModeId: normalizePermissionModeId(settings.permissionModeId)
6483
6591
  };
6592
+ const agentTargetId = normalizeOptionalText(current.agentTargetId);
6593
+ if (agentTargetId) {
6594
+ return {
6595
+ ...current,
6596
+ composerOverridesByAgentTargetId: {
6597
+ ...current.composerOverridesByAgentTargetId ?? {},
6598
+ [agentTargetId]: composerOverrides
6599
+ }
6600
+ };
6601
+ }
6484
6602
  return {
6485
6603
  ...current,
6486
6604
  composerOverrides,
@@ -7410,17 +7528,46 @@ function messageActivityTimeUnixMs(message) {
7410
7528
  function minFiniteMessageVersion(messages) {
7411
7529
  let result = null;
7412
7530
  for (const message of messages) {
7413
- if (!Number.isFinite(message.version)) {
7531
+ if (!Number.isFinite(message.version) || isWorkspaceAgentActivityOptimisticMessage(message)) {
7414
7532
  continue;
7415
7533
  }
7416
7534
  result = result === null ? message.version : Math.min(result, message.version);
7417
7535
  }
7418
7536
  return result;
7419
7537
  }
7420
- function hasUserTextMessage(messages) {
7421
- return messages.some(
7422
- (message) => message.kind.trim().toLowerCase() === "text" && message.role.trim().toLowerCase() === "user" && workspaceAgentActivityMessageText(message).trim() !== ""
7423
- );
7538
+ function isUserTextMessage(message) {
7539
+ return message.kind.trim().toLowerCase() === "text" && message.role.trim().toLowerCase() === "user" && workspaceAgentActivityMessageText(message).trim() !== "";
7540
+ }
7541
+ function windowHasTurnMissingUserPrompt(messages, newestPagedVersion) {
7542
+ if (newestPagedVersion === null) {
7543
+ return messages.length > 0 && !messages.some(isUserTextMessage);
7544
+ }
7545
+ const turnIdsWithUserPrompt = /* @__PURE__ */ new Set();
7546
+ const pagedTurnIds = /* @__PURE__ */ new Set();
7547
+ for (const message of messages) {
7548
+ if (isWorkspaceAgentActivityOptimisticMessage(message)) {
7549
+ continue;
7550
+ }
7551
+ const turnId = message.turnId?.trim() ?? "";
7552
+ if (!turnId) {
7553
+ continue;
7554
+ }
7555
+ if (Number.isFinite(message.version) && message.version <= newestPagedVersion) {
7556
+ pagedTurnIds.add(turnId);
7557
+ }
7558
+ if (isUserTextMessage(message)) {
7559
+ turnIdsWithUserPrompt.add(turnId);
7560
+ }
7561
+ }
7562
+ if (pagedTurnIds.size === 0) {
7563
+ return false;
7564
+ }
7565
+ for (const turnId of pagedTurnIds) {
7566
+ if (!turnIdsWithUserPrompt.has(turnId)) {
7567
+ return true;
7568
+ }
7569
+ }
7570
+ return false;
7424
7571
  }
7425
7572
  function workspaceAgentActivityMessageText(message) {
7426
7573
  const payload = message.payload;
@@ -7450,7 +7597,7 @@ function workspaceAgentActivityMessageText(message) {
7450
7597
  function maxFiniteMessageVersion(messages) {
7451
7598
  let result = null;
7452
7599
  for (const message of messages) {
7453
- if (!Number.isFinite(message.version)) {
7600
+ if (!Number.isFinite(message.version) || isWorkspaceAgentActivityOptimisticMessage(message)) {
7454
7601
  continue;
7455
7602
  }
7456
7603
  result = result === null ? message.version : Math.max(result, message.version);
@@ -7627,30 +7774,6 @@ function createAgentGUIConversationId() {
7627
7774
  const fallbackHex = Math.random().toString(16).slice(2).padEnd(12, "0");
7628
7775
  return `00000000-0000-4000-8000-${fallbackHex.slice(0, 12)}`;
7629
7776
  }
7630
- function createOptimisticPromptMessage(input) {
7631
- const clientSubmitMessageId = input.clientSubmitId ? createWorkspaceAgentActivityUserMessageIdFromClientSubmitId(
7632
- input.clientSubmitId
7633
- ) : null;
7634
- return {
7635
- id: Math.max(1, Math.floor(input.occurredAtUnixMs)),
7636
- workspaceId: input.workspaceId,
7637
- agentSessionId: input.agentSessionId,
7638
- messageId: clientSubmitMessageId ?? `optimistic:user:${input.turnId}`,
7639
- version: Math.max(1, Math.floor(input.occurredAtUnixMs)),
7640
- turnId: input.turnId,
7641
- role: "user",
7642
- kind: "text",
7643
- payload: {
7644
- __agentGuiOptimisticPrompt: true,
7645
- actorId: input.userId,
7646
- ...input.clientSubmitId ? { clientSubmitId: input.clientSubmitId } : {},
7647
- content: input.content,
7648
- text: input.prompt
7649
- },
7650
- occurredAtUnixMs: input.occurredAtUnixMs,
7651
- startedAtUnixMs: input.occurredAtUnixMs
7652
- };
7653
- }
7654
7777
  function createPendingOptimisticTurnId(clientSubmitId) {
7655
7778
  return `pending:${clientSubmitId}`;
7656
7779
  }
@@ -7697,6 +7820,41 @@ function normalizeAgentGUIOpenSessionRequest(request) {
7697
7820
  function recordValue2(value) {
7698
7821
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
7699
7822
  }
7823
+ function numberValue(value) {
7824
+ if (typeof value === "number" && Number.isFinite(value)) {
7825
+ return value;
7826
+ }
7827
+ if (typeof value === "string" && value.trim() !== "") {
7828
+ const parsed = Number(value);
7829
+ return Number.isFinite(parsed) ? parsed : null;
7830
+ }
7831
+ return null;
7832
+ }
7833
+ function activeBackgroundAgentCount(runtimeContext) {
7834
+ const backgroundAgents = recordValue2(runtimeContext?.backgroundAgents);
7835
+ if (!backgroundAgents) {
7836
+ return 0;
7837
+ }
7838
+ const items = Array.isArray(backgroundAgents.items) ? backgroundAgents.items : [];
7839
+ if (items.length === 0) {
7840
+ const count = numberValue(backgroundAgents.count);
7841
+ return count === null ? 0 : Math.max(0, Math.floor(count));
7842
+ }
7843
+ return items.filter((item) => {
7844
+ const record = recordValue2(item);
7845
+ if (!record) {
7846
+ return false;
7847
+ }
7848
+ const status = String(record.status ?? "").trim().toLowerCase();
7849
+ return ![
7850
+ "completed",
7851
+ "failed",
7852
+ "cancelled",
7853
+ "canceled",
7854
+ "stopped"
7855
+ ].includes(status);
7856
+ }).length;
7857
+ }
7700
7858
  function appServerStartupMetadata(runtimeContext) {
7701
7859
  return recordValue2(runtimeContext?.appServerStartup);
7702
7860
  }
@@ -8115,21 +8273,25 @@ function areAgentComposerDraftsEqual(left, right) {
8115
8273
  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;
8116
8274
  });
8117
8275
  }
8118
- function nodeDefaultDraftKey(agentProvider) {
8276
+ function nodeDefaultDraftKey(agentProvider, agentTargetId) {
8277
+ const normalizedAgentTargetId = normalizeOptionalText2(agentTargetId);
8278
+ if (normalizedAgentTargetId) {
8279
+ return `${NODE_DEFAULT_DRAFT_KEY}:target:${normalizedAgentTargetId}`;
8280
+ }
8119
8281
  return `${NODE_DEFAULT_DRAFT_KEY}:${agentProvider}`;
8120
8282
  }
8121
- function nodeDefaultDraftContentKey(agentProvider) {
8122
- return nodeDefaultDraftKey(agentProvider);
8283
+ function nodeDefaultDraftContentKey(agentProvider, agentTargetId) {
8284
+ return nodeDefaultDraftKey(agentProvider, agentTargetId);
8123
8285
  }
8124
8286
  function normalizeProjectDraftPath(value) {
8125
8287
  const normalized = value?.trim().replaceAll("\\", "/").replace(/\/+$/, "");
8126
8288
  return normalized ? normalized : null;
8127
8289
  }
8128
8290
  function readNodeDefaultDraftContent(input) {
8129
- return input.drafts[nodeDefaultDraftContentKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? EMPTY_AGENT_COMPOSER_DRAFT;
8291
+ 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;
8130
8292
  }
8131
8293
  function readNodeDefaultDraftSettings(input) {
8132
- return input.drafts[nodeDefaultDraftKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? buildNodeDefaultComposerSettings(input.data, {
8294
+ return input.drafts[nodeDefaultDraftKey(input.data.provider, input.data.agentTargetId)] ?? input.drafts[nodeDefaultDraftKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? buildNodeDefaultComposerSettings(input.data, {
8133
8295
  defaultReasoningEffort: input.defaultReasoningEffort
8134
8296
  });
8135
8297
  }
@@ -8212,7 +8374,7 @@ function isCompletedOutcomeToken(value) {
8212
8374
  return value?.trim().toLowerCase() === "completed";
8213
8375
  }
8214
8376
  function hasSessionControlStatePatch(patch) {
8215
- 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;
8377
+ 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;
8216
8378
  }
8217
8379
  function mergeSessionControlStatePatch(current, patch) {
8218
8380
  if (!current || !hasSessionControlStatePatch(patch)) {
@@ -8276,6 +8438,10 @@ function mergeSessionControlStatePatch(current, patch) {
8276
8438
  next.submitAvailability = submitAvailability;
8277
8439
  changed = true;
8278
8440
  }
8441
+ if (patch.pendingInteractive !== void 0 && !sameJSONValue(current.pendingInteractive ?? null, patch.pendingInteractive)) {
8442
+ next.pendingInteractive = patch.pendingInteractive;
8443
+ changed = true;
8444
+ }
8279
8445
  if (patch.turn?.phase) {
8280
8446
  next.turnLifecycle = {
8281
8447
  activeTurnId: patch.turn.activeTurnId !== void 0 ? patch.turn.activeTurnId : patch.turn.phase === "settled" ? null : patch.turn.turnId,
@@ -8292,6 +8458,9 @@ function mergeSessionControlStatePatch(current, patch) {
8292
8458
  }
8293
8459
  return changed ? next : current;
8294
8460
  }
8461
+ function sameJSONValue(left, right) {
8462
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
8463
+ }
8295
8464
  function conversationStatusFromSessionState(state) {
8296
8465
  if (state.turnLifecycle?.phase) {
8297
8466
  return conversationStatusFromStatePatch({
@@ -8401,7 +8570,9 @@ function useAgentGUINodeController({
8401
8570
  workspacePath,
8402
8571
  avoidGroupingEdits,
8403
8572
  data,
8573
+ conversationScope = "single-provider",
8404
8574
  providerTargets,
8575
+ providerTargetsLoading = false,
8405
8576
  defaultProviderTargetId = null,
8406
8577
  openSessionRequest = null,
8407
8578
  prefillPromptRequest = null,
@@ -8421,23 +8592,37 @@ function useAgentGUINodeController({
8421
8592
  [providerTargets]
8422
8593
  );
8423
8594
  const normalizedProviderTargets = useMemo4(
8424
- () => normalizedExplicitProviderTargets.length > 0 ? normalizedExplicitProviderTargets : normalizeAgentGUIProviderTargets(null),
8425
- [normalizedExplicitProviderTargets]
8595
+ () => providerTargetsLoading ? [] : providerTargets === void 0 ? normalizeAgentGUIProviderTargets(null) : normalizedExplicitProviderTargets,
8596
+ [normalizedExplicitProviderTargets, providerTargets, providerTargetsLoading]
8426
8597
  );
8427
- const selectedProviderTarget = useMemo4(
8428
- () => resolveAgentGUIProviderTarget({
8598
+ const shouldFallbackToLocalProviderTargets = providerTargets === void 0 && !providerTargetsLoading;
8599
+ const selectedProviderTarget = useMemo4(() => {
8600
+ const resolved = resolveAgentGUIProviderTarget({
8601
+ agentTargetId: data.agentTargetId,
8429
8602
  defaultProviderTargetId,
8603
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
8430
8604
  provider: data.provider,
8431
8605
  providerTargetId: data.providerTargetId,
8432
8606
  providerTargets: normalizedProviderTargets
8433
- }),
8434
- [
8435
- data.provider,
8436
- data.providerTargetId,
8437
- defaultProviderTargetId,
8438
- normalizedProviderTargets
8439
- ]
8440
- );
8607
+ });
8608
+ return resolved ?? {
8609
+ targetId: data.agentTargetId ?? "__loading__",
8610
+ provider: data.provider,
8611
+ ref: {
8612
+ kind: "loading",
8613
+ provider: data.provider
8614
+ },
8615
+ label: data.provider,
8616
+ disabled: true
8617
+ };
8618
+ }, [
8619
+ data.agentTargetId,
8620
+ data.provider,
8621
+ data.providerTargetId,
8622
+ defaultProviderTargetId,
8623
+ normalizedProviderTargets,
8624
+ shouldFallbackToLocalProviderTargets
8625
+ ]);
8441
8626
  const selectedProviderTargetIsExplicit = useMemo4(
8442
8627
  () => normalizedExplicitProviderTargets.some(
8443
8628
  (target) => target.provider === selectedProviderTarget.provider && target.targetId === selectedProviderTarget.targetId && agentGUIProviderTargetRefsEqual(
@@ -8458,6 +8643,17 @@ function useAgentGUINodeController({
8458
8643
  return stable;
8459
8644
  }, [agentActivitySnapshot]);
8460
8645
  const generatedControllerOwnerKey = useId();
8646
+ const [conversationFilter, setConversationFilter] = useState4(
8647
+ () => createAgentGUIConversationFilterState().filter
8648
+ );
8649
+ const canUseConversationTargetFilter = conversationScope === "multi-provider";
8650
+ const queryConversationFilter = canUseConversationTargetFilter ? conversationFilter : null;
8651
+ useEffect4(() => {
8652
+ if (canUseConversationTargetFilter || conversationFilter.kind === "all") {
8653
+ return;
8654
+ }
8655
+ setConversationFilter({ kind: "all" });
8656
+ }, [canUseConversationTargetFilter, conversationFilter]);
8461
8657
  const conversationListQuery = useMemo4(() => {
8462
8658
  const userId = currentUserId?.trim() ?? "";
8463
8659
  const provider = data.provider?.trim() ?? "";
@@ -8465,12 +8661,13 @@ function useAgentGUINodeController({
8465
8661
  return null;
8466
8662
  }
8467
8663
  return {
8664
+ ...queryConversationFilter ? { conversationFilter: queryConversationFilter } : {},
8468
8665
  workspaceId,
8469
8666
  userId,
8470
8667
  provider: data.provider,
8471
8668
  sessionOrigin: AGENT_GUI_RUNTIME_SESSION_ORIGIN
8472
8669
  };
8473
- }, [currentUserId, data.provider, workspaceId]);
8670
+ }, [currentUserId, data.provider, queryConversationFilter, workspaceId]);
8474
8671
  const conversationListState = useAgentGuiConversationList(
8475
8672
  conversationListQuery
8476
8673
  );
@@ -8564,7 +8761,7 @@ function useAgentGUINodeController({
8564
8761
  sessionViewRef(activeConversationId)
8565
8762
  );
8566
8763
  const activeSessionState = activeSessionView?.controlState ?? null;
8567
- const providerComposerOptions = agentActivitySnapshot.composerOptionsByProvider?.[data.provider] ?? null;
8764
+ const providerComposerOptions = (data.agentTargetId ? agentActivitySnapshot.composerOptionsByAgentTargetId?.[data.agentTargetId] : null) ?? agentActivitySnapshot.composerOptionsByProvider?.[data.provider] ?? null;
8568
8765
  const resolvedPromptImagesSupported = resolveAgentActivityCapability2(
8569
8766
  "imageInput",
8570
8767
  {
@@ -8578,6 +8775,10 @@ function useAgentGUINodeController({
8578
8775
  sessionRuntimeContext: activeSessionState?.runtimeContext
8579
8776
  });
8580
8777
  const activeSessionRuntimeContext = activeSessionState?.runtimeContext;
8778
+ const backgroundAgentCount = useMemo4(
8779
+ () => activeBackgroundAgentCount(activeSessionRuntimeContext),
8780
+ [activeSessionRuntimeContext]
8781
+ );
8581
8782
  const composerSupport = useMemo4(
8582
8783
  () => composerSettingsSupportFromOptions(
8583
8784
  providerComposerOptions,
@@ -9136,7 +9337,17 @@ function useAgentGUINodeController({
9136
9337
  const previousQuery = previousSnapshot.query;
9137
9338
  const previousQueryKey = previousQuery ? createAgentGUIConversationListQueryKey(previousQuery) : null;
9138
9339
  const nextQueryKey = conversationListQuery ? createAgentGUIConversationListQueryKey(conversationListQuery) : null;
9139
- if (previousQuery && conversationListQuery && previousQueryKey !== nextQueryKey && previousQuery.workspaceId === conversationListQuery.workspaceId && previousQuery.provider === conversationListQuery.provider && previousQuery.sessionOrigin === conversationListQuery.sessionOrigin && previousSnapshot.conversations.length > 0) {
9340
+ const previousHasExplicitFilter = previousQuery?.conversationFilter != null;
9341
+ const nextHasExplicitFilter = conversationListQuery?.conversationFilter != null;
9342
+ const previousFilterKey = previousQuery ? JSON.stringify(
9343
+ normalizeAgentGUIConversationFilter(previousQuery.conversationFilter)
9344
+ ) : "";
9345
+ const nextFilterKey = conversationListQuery ? JSON.stringify(
9346
+ normalizeAgentGUIConversationFilter(
9347
+ conversationListQuery.conversationFilter
9348
+ )
9349
+ ) : "";
9350
+ 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) {
9140
9351
  ensureAgentGUIConversationListQuery(conversationListQuery);
9141
9352
  seedAgentGUIConversationListConversationsIfEmpty({
9142
9353
  query: conversationListQuery,
@@ -9987,7 +10198,10 @@ function useAgentGUINodeController({
9987
10198
  );
9988
10199
  let hasOlderMessages = page.hasMore && page.messages.length > 0;
9989
10200
  let oldestLoadedVersion = minFiniteMessageVersion(detailMessages);
9990
- for (let backfillPageIndex = 0; hasOlderMessages && !hasUserTextMessage(detailMessages) && oldestLoadedVersion !== null && backfillPageIndex < AGENT_GUI_DETAIL_MISSING_USER_BACKFILL_PAGE_LIMIT; backfillPageIndex += 1) {
10201
+ for (let backfillPageIndex = 0; hasOlderMessages && windowHasTurnMissingUserPrompt(
10202
+ detailMessages,
10203
+ maxFiniteMessageVersion(page.messages)
10204
+ ) && oldestLoadedVersion !== null && backfillPageIndex < AGENT_GUI_DETAIL_MISSING_USER_BACKFILL_PAGE_LIMIT; backfillPageIndex += 1) {
9991
10205
  reportAgentGUIMessagePageDiagnostic({
9992
10206
  agentSessionId: normalizedAgentSessionId,
9993
10207
  details: {
@@ -10300,6 +10514,7 @@ function useAgentGUINodeController({
10300
10514
  const loadDraftComposerOptions = useCallback4(
10301
10515
  (options) => {
10302
10516
  const provider = dataRef.current.provider;
10517
+ const agentTargetId = dataRef.current.agentTargetId ?? null;
10303
10518
  if (isCreatingConversationRef.current) {
10304
10519
  return;
10305
10520
  }
@@ -10315,6 +10530,7 @@ function useAgentGUINodeController({
10315
10530
  cwd: composerOptionsCwd,
10316
10531
  force: options?.force,
10317
10532
  provider,
10533
+ agentTargetId,
10318
10534
  settings
10319
10535
  })
10320
10536
  ).catch(() => void 0);
@@ -10328,7 +10544,7 @@ function useAgentGUINodeController({
10328
10544
  if (!supports.model && !supports.reasoning && !supports.permission) {
10329
10545
  return;
10330
10546
  }
10331
- const projectKey = `${data.provider}\0${selectedProjectPath ?? ""}`;
10547
+ const projectKey = `${data.agentTargetId ?? data.provider}\0${selectedProjectPath ?? ""}`;
10332
10548
  const previousProjectKey = composerOptionsProjectKeyRef.current;
10333
10549
  composerOptionsProjectKeyRef.current = projectKey;
10334
10550
  if (previousProjectKey === null || previousProjectKey === projectKey) {
@@ -10336,6 +10552,7 @@ function useAgentGUINodeController({
10336
10552
  }
10337
10553
  loadDraftComposerOptions({ force: true });
10338
10554
  }, [
10555
+ data.agentTargetId,
10339
10556
  data.provider,
10340
10557
  loadDraftComposerOptions,
10341
10558
  previewMode,
@@ -10395,6 +10612,7 @@ function useAgentGUINodeController({
10395
10612
  );
10396
10613
  }, [
10397
10614
  activeConversationId,
10615
+ data.agentTargetId,
10398
10616
  data.provider,
10399
10617
  isComposerHome,
10400
10618
  loadDraftComposerOptions,
@@ -10991,6 +11209,11 @@ function useAgentGUINodeController({
10991
11209
  if (isCreatingConversation || target.disabled === true || data.provider === "openclaw" && openclawGateway?.status !== "ready") {
10992
11210
  return;
10993
11211
  }
11212
+ const agentTargetId = target.agentTargetId?.trim() ?? "";
11213
+ if (!agentTargetId && selectedProviderTargetIsExplicitRef.current) {
11214
+ setDetailError(translate("agentHost.agentGui.agentTargetRequired"));
11215
+ return;
11216
+ }
10994
11217
  const normalizedInitialContent = Array.isArray(initialContentInput) ? normalizeAgentPromptContentBlocks(
10995
11218
  initialContentInput
10996
11219
  ) : textPromptContent(normalizeOptionalPrompt(initialContentInput));
@@ -11007,14 +11230,16 @@ function useAgentGUINodeController({
11007
11230
  void (async () => {
11008
11231
  const target2 = selectedProviderTargetRef.current;
11009
11232
  const provider = target2.provider;
11010
- const shouldUseProviderTargetRef = selectedProviderTargetIsExplicitRef.current;
11233
+ const agentTargetId2 = target2.agentTargetId?.trim() ?? "";
11234
+ const shouldUseProviderTargetRef = !agentTargetId2 && selectedProviderTargetIsExplicitRef.current;
11011
11235
  onDataChangeRef.current(
11012
- (current) => current.provider === provider && (current.providerTargetId ?? null) === (shouldUseProviderTargetRef ? target2.targetId : null) && agentGUIProviderTargetRefsEqual(
11236
+ (current) => current.provider === provider && (current.agentTargetId ?? null) === (agentTargetId2 || null) && (current.providerTargetId ?? null) === (shouldUseProviderTargetRef ? target2.targetId : null) && agentGUIProviderTargetRefsEqual(
11013
11237
  current.providerTargetRef,
11014
11238
  shouldUseProviderTargetRef ? target2.ref : null
11015
11239
  ) ? current : {
11016
11240
  ...current,
11017
11241
  provider,
11242
+ agentTargetId: agentTargetId2 || null,
11018
11243
  providerTargetId: shouldUseProviderTargetRef ? target2.targetId : null,
11019
11244
  providerTargetRef: shouldUseProviderTargetRef ? target2.ref : null
11020
11245
  }
@@ -11046,7 +11271,7 @@ function useAgentGUINodeController({
11046
11271
  lastActiveModelByProviderRef.current[provider]
11047
11272
  ) : null;
11048
11273
  const effectiveInitialSettings = inheritedModel === null ? initialSettings : { ...initialSettings, model: inheritedModel };
11049
- const snapshotComposerOptions = agentActivityRuntime.getSnapshot(workspaceId).composerOptionsByProvider?.[provider] ?? null;
11274
+ const snapshotComposerOptions = (agentTargetId2 ? agentActivityRuntime.getSnapshot(workspaceId).composerOptionsByAgentTargetId?.[agentTargetId2] : null) ?? agentActivityRuntime.getSnapshot(workspaceId).composerOptionsByProvider?.[provider] ?? null;
11050
11275
  const snapshotDraftAgentSessionId = normalizedInitialContent.length > 0 && provider === "claude-code" ? draftAgentSessionIdFromComposerOptions(snapshotComposerOptions) : null;
11051
11276
  const draftAgentSessionId = snapshotDraftAgentSessionId && !activatedConversationIdsRef.current.has(
11052
11277
  snapshotDraftAgentSessionId
@@ -11145,6 +11370,7 @@ function useAgentGUINodeController({
11145
11370
  return activation.activate({
11146
11371
  mode: "new",
11147
11372
  agentSessionId,
11373
+ agentTargetId: agentTargetId2 || null,
11148
11374
  provider,
11149
11375
  providerTargetRef: shouldUseProviderTargetRef ? target2.ref : null,
11150
11376
  cwd: selectedProjectPath2 ?? "",
@@ -12432,7 +12658,10 @@ function useAgentGUINodeController({
12432
12658
  };
12433
12659
  const agentSessionId = activeConversationIdRef.current;
12434
12660
  if (!agentSessionId) {
12435
- const defaultDraftKey = nodeDefaultDraftKey(dataRef.current.provider);
12661
+ const defaultDraftKey = nodeDefaultDraftKey(
12662
+ dataRef.current.provider,
12663
+ dataRef.current.agentTargetId
12664
+ );
12436
12665
  const storedDefaults = readNodeDefaultDraftSettings({
12437
12666
  data: dataRef.current,
12438
12667
  defaultReasoningEffort,
@@ -13282,7 +13511,8 @@ function useAgentGUINodeController({
13282
13511
  return null;
13283
13512
  }
13284
13513
  const previous = projectionConversationRef.current;
13285
- 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) {
13514
+ const turnLifecycle = activeSessionState?.agentSessionId === activeConversation.id ? activeSessionState.turnLifecycle ?? null : null;
13515
+ 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)) {
13286
13516
  return previous;
13287
13517
  }
13288
13518
  const next = activeConversation ? {
@@ -13294,7 +13524,8 @@ function useAgentGUINodeController({
13294
13524
  status: activeConversation.status,
13295
13525
  cwd: activeConversation.cwd,
13296
13526
  updatedAtUnixMs: activeConversation.updatedAtUnixMs,
13297
- syncState: activeConversation.syncState
13527
+ syncState: activeConversation.syncState,
13528
+ turnLifecycle
13298
13529
  } : null;
13299
13530
  projectionConversationRef.current = next;
13300
13531
  return next;
@@ -13307,7 +13538,11 @@ function useAgentGUINodeController({
13307
13538
  activeConversation?.status,
13308
13539
  activeConversation?.title,
13309
13540
  activeConversation?.titleFallback,
13310
- activeConversation?.userId
13541
+ activeConversation?.userId,
13542
+ activeSessionState?.agentSessionId,
13543
+ activeSessionState?.turnLifecycle?.activeTurnId,
13544
+ activeSessionState?.turnLifecycle?.phase,
13545
+ activeSessionState?.turnLifecycle?.settling
13311
13546
  ]);
13312
13547
  const draftContent = activeConversationId ? draftBySessionId[activeConversationId] ?? EMPTY_AGENT_COMPOSER_DRAFT : readNodeDefaultDraftContent({
13313
13548
  data,
@@ -13572,7 +13807,7 @@ function useAgentGUINodeController({
13572
13807
  hasProviderSessionNotFoundError,
13573
13808
  pendingApproval
13574
13809
  ]);
13575
- 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;
13810
+ const canSubmit = !providerTargetsLoading && 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;
13576
13811
  const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
13577
13812
  useEffect4(() => {
13578
13813
  const firstVersion = minFiniteMessageVersion(activeMessages);
@@ -13653,6 +13888,7 @@ function useAgentGUINodeController({
13653
13888
  isSubmitting,
13654
13889
  pendingApproval,
13655
13890
  pendingInteractivePrompt,
13891
+ providerTargetsLoading,
13656
13892
  workspaceId
13657
13893
  ]);
13658
13894
  const activeSessionReasoningSelection = useMemo4(
@@ -13761,7 +13997,115 @@ function useAgentGUINodeController({
13761
13997
  stableComposerSettings.availableModels.length,
13762
13998
  stableComposerSettings.isSettingsLoading
13763
13999
  ]);
14000
+ const updateConversationFilter = useCallback4(
14001
+ (filter) => {
14002
+ if (!canUseConversationTargetFilter) {
14003
+ setConversationFilter({ kind: "all" });
14004
+ return;
14005
+ }
14006
+ setConversationFilter(normalizeAgentGUIConversationFilter(filter));
14007
+ },
14008
+ [canUseConversationTargetFilter]
14009
+ );
14010
+ const selectProvider = useCallback4(
14011
+ (input) => {
14012
+ if (previewMode) {
14013
+ return;
14014
+ }
14015
+ const nextProvider = input.provider;
14016
+ const nextTarget = resolveAgentGUIProviderTarget({
14017
+ defaultProviderTargetId,
14018
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
14019
+ provider: nextProvider,
14020
+ providerTargetId: input.providerTargetId,
14021
+ providerTargets: normalizedProviderTargets
14022
+ });
14023
+ if (!nextTarget) {
14024
+ return;
14025
+ }
14026
+ if (nextTarget.disabled === true) {
14027
+ return;
14028
+ }
14029
+ const shouldUseProviderTargetRef = normalizedExplicitProviderTargets.some(
14030
+ (target) => target.provider === nextTarget.provider && target.targetId === nextTarget.targetId && agentGUIProviderTargetRefsEqual(target.ref, nextTarget.ref)
14031
+ );
14032
+ const previous = activeConversationIdRef.current;
14033
+ if (previous) {
14034
+ void activation.unactivate(previous);
14035
+ }
14036
+ setIntent({ tag: "home" });
14037
+ isComposerHomeRef.current = true;
14038
+ setIsComposerHome(true);
14039
+ activeConversationIdRef.current = null;
14040
+ setActiveConversationId(null);
14041
+ setIsLoadingMessages(false);
14042
+ setDetailError(null);
14043
+ persistActiveConversation(null);
14044
+ onDataChangeRef.current((current) => {
14045
+ const nextAgentTargetId = shouldUseProviderTargetRef ? nextTarget.agentTargetId ?? null : null;
14046
+ const nextData = {
14047
+ ...current,
14048
+ provider: nextProvider,
14049
+ agentTargetId: nextAgentTargetId,
14050
+ lastActiveAgentSessionId: null,
14051
+ providerTargetId: null,
14052
+ providerTargetRef: null
14053
+ };
14054
+ dataRef.current = nextData;
14055
+ return nextData;
14056
+ });
14057
+ window.setTimeout(() => {
14058
+ loadDraftComposerOptions({ force: true });
14059
+ }, 0);
14060
+ },
14061
+ [
14062
+ activation,
14063
+ defaultProviderTargetId,
14064
+ loadDraftComposerOptions,
14065
+ normalizedExplicitProviderTargets,
14066
+ normalizedProviderTargets,
14067
+ persistActiveConversation,
14068
+ previewMode,
14069
+ shouldFallbackToLocalProviderTargets
14070
+ ]
14071
+ );
14072
+ const selectConversationFilterTarget = useCallback4(
14073
+ (input) => {
14074
+ if (!canUseConversationTargetFilter) {
14075
+ setConversationFilter({ kind: "all" });
14076
+ return;
14077
+ }
14078
+ const nextTarget = resolveAgentGUIProviderTarget({
14079
+ defaultProviderTargetId,
14080
+ fallbackToLocal: shouldFallbackToLocalProviderTargets,
14081
+ provider: input.provider,
14082
+ providerTargetId: input.providerTargetId,
14083
+ providerTargets: normalizedProviderTargets
14084
+ });
14085
+ if (!nextTarget || nextTarget.disabled === true) {
14086
+ return;
14087
+ }
14088
+ const agentTargetId = nextTarget.agentTargetId?.trim() ?? "";
14089
+ const nextFilter = agentTargetId ? { kind: "agentTarget", agentTargetId } : { kind: "all" };
14090
+ setConversationFilter(nextFilter);
14091
+ selectProvider({
14092
+ provider: nextTarget.provider,
14093
+ providerTargetId: nextTarget.targetId
14094
+ });
14095
+ },
14096
+ [
14097
+ canUseConversationTargetFilter,
14098
+ defaultProviderTargetId,
14099
+ normalizedProviderTargets,
14100
+ selectProvider,
14101
+ shouldFallbackToLocalProviderTargets
14102
+ ]
14103
+ );
13764
14104
  const stableCreateConversation = useStableControllerEventCallback(createConversation);
14105
+ const stableSelectProvider = useStableControllerEventCallback(selectProvider);
14106
+ const stableSelectConversationFilterTarget = useStableControllerEventCallback(
14107
+ selectConversationFilterTarget
14108
+ );
13765
14109
  const stableSelectConversation = useStableControllerEventCallback(selectConversation);
13766
14110
  const stableSubmitPrompt = useStableControllerEventCallback(submitPrompt);
13767
14111
  const stableSubmitGuidancePrompt = useStableControllerEventCallback(submitGuidancePrompt);
@@ -13812,8 +14156,14 @@ function useAgentGUINodeController({
13812
14156
  const stableLoadOlderConversationMessages = useStableControllerEventCallback(
13813
14157
  loadOlderConversationMessages
13814
14158
  );
14159
+ const stableUpdateConversationFilter = useStableControllerEventCallback(
14160
+ updateConversationFilter
14161
+ );
13815
14162
  const controllerActions = useMemo4(
13816
14163
  () => ({
14164
+ updateConversationFilter: stableUpdateConversationFilter,
14165
+ selectConversationFilterTarget: stableSelectConversationFilterTarget,
14166
+ selectProvider: stableSelectProvider,
13817
14167
  createConversation: stableCreateConversation,
13818
14168
  selectConversation: stableSelectConversation,
13819
14169
  submitPrompt: stableSubmitPrompt,
@@ -13860,6 +14210,8 @@ function useAgentGUINodeController({
13860
14210
  stableRetryActivation,
13861
14211
  stableRetryOpenclawGateway,
13862
14212
  stableSelectConversation,
14213
+ stableSelectConversationFilterTarget,
14214
+ stableSelectProvider,
13863
14215
  stableSendQueuedPromptNext,
13864
14216
  stableSubmitGuidancePrompt,
13865
14217
  stableShowPromptImagesUnsupported,
@@ -13867,6 +14219,7 @@ function useAgentGUINodeController({
13867
14219
  stableSubmitInteractivePrompt,
13868
14220
  stableSubmitPrompt,
13869
14221
  stableToggleConversationPinned,
14222
+ stableUpdateConversationFilter,
13870
14223
  stableUpdateComposerSettings,
13871
14224
  stableUpdateDraftContent,
13872
14225
  stableUpdateSelectedProjectPath
@@ -13880,6 +14233,10 @@ function useAgentGUINodeController({
13880
14233
  currentUserId,
13881
14234
  data,
13882
14235
  selectedProviderTarget,
14236
+ providerTargets: normalizedProviderTargets,
14237
+ providerTargetsLoading,
14238
+ conversationScope,
14239
+ conversationFilter,
13883
14240
  conversations: visibleConversations,
13884
14241
  userProjects,
13885
14242
  activeConversation,
@@ -13900,6 +14257,7 @@ function useAgentGUINodeController({
13900
14257
  promptImagesSupported,
13901
14258
  compactSupported,
13902
14259
  usage,
14260
+ backgroundAgentCount,
13903
14261
  listError,
13904
14262
  isDeletingConversation,
13905
14263
  isDeletingProjectConversations,
@@ -13941,10 +14299,14 @@ function useAgentGUINodeController({
13941
14299
  canSubmit,
13942
14300
  canQueueWhileBusy,
13943
14301
  conversation,
14302
+ conversationScope,
14303
+ conversationFilter,
13944
14304
  conversationDetail,
13945
14305
  controllerActions,
13946
14306
  data,
13947
14307
  selectedProviderTarget,
14308
+ normalizedProviderTargets,
14309
+ providerTargetsLoading,
13948
14310
  detailError,
13949
14311
  draftContent,
13950
14312
  draftPrompt,
@@ -13953,6 +14315,7 @@ function useAgentGUINodeController({
13953
14315
  promptImagesSupported,
13954
14316
  compactSupported,
13955
14317
  usage,
14318
+ backgroundAgentCount,
13956
14319
  isInterrupting,
13957
14320
  isCancelPending,
13958
14321
  isLoadingConversations,
@@ -14174,7 +14537,13 @@ import {
14174
14537
  } from "react";
14175
14538
  import { useSnapshot } from "valtio";
14176
14539
  import { proxy as proxy2 } from "valtio/vanilla";
14177
- import { ChevronRight as ChevronRight2, ExternalLink, Info as Info2, Wrench } from "lucide-react";
14540
+ import {
14541
+ ChevronRight as ChevronRight2,
14542
+ ExternalLink,
14543
+ Info as Info2,
14544
+ LayoutGrid,
14545
+ Wrench
14546
+ } from "lucide-react";
14178
14547
 
14179
14548
  // app/renderer/components/ui/popover.tsx
14180
14549
  import {
@@ -14975,13 +15344,11 @@ function AgentChromeNotice({
14975
15344
  }) {
14976
15345
  "use memo";
14977
15346
  const fullMessage = description ? `${title} ${description}` : title;
15347
+ const toneClassName = tone === "danger" ? AgentGUIChrome_styles_default.chromeCardDanger : tone === "muted" ? AgentGUIChrome_styles_default.chromeCardMuted : AgentGUIChrome_styles_default.chromeCardWarning;
14978
15348
  return /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.sessionChrome, children: /* @__PURE__ */ jsx19(
14979
15349
  "section",
14980
15350
  {
14981
- className: cn(
14982
- AgentGUIChrome_styles_default.chromeCard,
14983
- tone === "danger" ? AgentGUIChrome_styles_default.chromeCardDanger : AgentGUIChrome_styles_default.chromeCardWarning
14984
- ),
15351
+ className: cn(AgentGUIChrome_styles_default.chromeCard, toneClassName),
14985
15352
  role,
14986
15353
  "data-testid": testId,
14987
15354
  children: /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.chromeMetaRow, children: /* @__PURE__ */ jsxs7("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: [
@@ -15225,7 +15592,15 @@ import {
15225
15592
  useState as useState10
15226
15593
  } from "react";
15227
15594
  import { createPortal as createPortal3 } from "react-dom";
15228
- import { AddIcon, Button as Button3, Select as Select2, SelectTrigger as SelectTrigger2 } from "@tutti-os/ui-system";
15595
+ import {
15596
+ AddIcon,
15597
+ Button as Button3,
15598
+ Select as Select2,
15599
+ SelectContent as SelectContent2,
15600
+ SelectItem as SelectItem2,
15601
+ SelectTrigger as SelectTrigger2,
15602
+ SelectValue
15603
+ } from "@tutti-os/ui-system";
15229
15604
  import { ListChecks as ListChecks2, Target as Target3, X } from "lucide-react";
15230
15605
  import {
15231
15606
  createMentionPaletteStateAdapter,
@@ -15906,6 +16281,7 @@ var styles3 = {
15906
16281
  composerPromptTipText: "agent-gui-node__composer-prompt-tip-text",
15907
16282
  composerPromptTipTooltip: "agent-gui-node__composer-prompt-tip-tooltip",
15908
16283
  composerProjectRow: "agent-gui-node__composer-project-row",
16284
+ composerProviderSelect: "agent-gui-node__composer-provider-select",
15909
16285
  composerQueuedPromptCard: "agent-gui-node__composer-queued-prompt-card",
15910
16286
  composerQueuedPromptHeader: "agent-gui-node__composer-queued-prompt-header",
15911
16287
  composerQueuedPromptExpandCue: "agent-gui-node__composer-queued-prompt-expand-cue",
@@ -15983,6 +16359,12 @@ var styles3 = {
15983
16359
  projectRailAddProjectTrigger: "agent-gui-node__project-rail-add-project-trigger",
15984
16360
  projectRailHeader: "agent-gui-node__project-rail-header",
15985
16361
  projectRailTitle: "agent-gui-node__project-rail-title",
16362
+ providerRail: "agent-gui-node__provider-rail",
16363
+ providerRailAvatar: "agent-gui-node__provider-rail-avatar",
16364
+ providerRailAvatarIcon: "agent-gui-node__provider-rail-avatar-icon",
16365
+ providerRailAvatarImage: "agent-gui-node__provider-rail-avatar-image",
16366
+ providerRailTile: "agent-gui-node__provider-rail-tile",
16367
+ providerRailTileLabel: "agent-gui-node__provider-rail-tile-label",
15986
16368
  rail: "agent-gui-node__rail",
15987
16369
  railPanel: "agent-gui-node__rail-panel",
15988
16370
  railPanelCollapsed: "agent-gui-node__rail-panel--collapsed",
@@ -18835,7 +19217,7 @@ function AgentReviewPickerPanel({
18835
19217
  {
18836
19218
  key: "uncommitted",
18837
19219
  label: labels.uncommitted,
18838
- onSelect: () => submit("/review")
19220
+ onSelect: () => submit("/review uncommitted")
18839
19221
  },
18840
19222
  {
18841
19223
  key: "base",
@@ -19512,11 +19894,21 @@ function hasInlineOverflow(element) {
19512
19894
  }
19513
19895
  return element.scrollWidth > element.clientWidth + 1;
19514
19896
  }
19897
+ function resolveComposerProviderIconUrl(provider) {
19898
+ const normalizedProvider = normalizeManagedAgentProvider(provider);
19899
+ return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
19900
+ }
19901
+ function resolveComposerProviderTargetIconUrl(target) {
19902
+ return target.iconUrl?.trim() || resolveComposerProviderIconUrl(target.provider);
19903
+ }
19515
19904
  function AgentComposer({
19516
19905
  workspaceId,
19517
19906
  workspacePath,
19518
19907
  currentUserId,
19519
19908
  provider,
19909
+ selectedProviderTarget = null,
19910
+ providerTargets = [],
19911
+ providerSelectReadonly = false,
19520
19912
  slashStatus = null,
19521
19913
  usage = null,
19522
19914
  draftContent,
@@ -19535,6 +19927,7 @@ function AgentComposer({
19535
19927
  canQueueWhileBusy,
19536
19928
  showStopButton,
19537
19929
  activePrompt,
19930
+ backgroundAgentStatusText = null,
19538
19931
  activePromptKeyboardShortcutsEnabled = true,
19539
19932
  promptTips = EMPTY_PROMPT_TIPS,
19540
19933
  isInterrupting,
@@ -19552,6 +19945,7 @@ function AgentComposer({
19552
19945
  onProjectPathChange = () => {
19553
19946
  },
19554
19947
  onSettingsChange,
19948
+ onProviderSelect,
19555
19949
  capabilityMenuState,
19556
19950
  onSubmit,
19557
19951
  onSubmitGuidance,
@@ -20665,6 +21059,17 @@ function AgentComposer({
20665
21059
  }
20666
21060
  await applyReferencePickResult(await onRequestWorkspaceReferences());
20667
21061
  }, [applyReferencePickResult, onRequestWorkspaceReferences]);
21062
+ const providerSwitchTargets = useMemo9(
21063
+ () => providerTargets.filter((target) => target.disabled !== true),
21064
+ [providerTargets]
21065
+ );
21066
+ const showProviderSelect = providerSwitchTargets.length > 1;
21067
+ const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${provider}`;
21068
+ const selectedProviderSwitchTarget = providerSwitchTargets.find(
21069
+ (target) => target.targetId === selectedProviderTargetId
21070
+ ) ?? selectedProviderTarget ?? providerSwitchTargets.find((target) => target.provider === provider) ?? null;
21071
+ const selectedProviderLabel = selectedProviderSwitchTarget?.label ?? provider;
21072
+ const providerSelectDisabled = previewMode || providerSelectReadonly || !onProviderSelect;
20668
21073
  const applyDroppedFileReferences = useCallback9(
20669
21074
  async (files) => {
20670
21075
  if (!promptFilesSupported || !resolveDroppedFileReferences || files.length === 0) {
@@ -21315,6 +21720,16 @@ function AgentComposer({
21315
21720
  ),
21316
21721
  "data-edge-glow": showEdgeGlow ? "true" : void 0,
21317
21722
  children: [
21723
+ backgroundAgentStatusText ? /* @__PURE__ */ jsx28(
21724
+ AgentChromeNotice,
21725
+ {
21726
+ tone: "muted",
21727
+ role: "status",
21728
+ testId: "agent-gui-composer-background-agent-status",
21729
+ title: backgroundAgentStatusText,
21730
+ icon: /* @__PURE__ */ jsx28(Spinner, { className: "h-3.5 w-3.5" })
21731
+ }
21732
+ ) : null,
21318
21733
  isSelectedProjectMissing ? /* @__PURE__ */ jsx28(
21319
21734
  AgentChromeNotice,
21320
21735
  {
@@ -21651,13 +22066,75 @@ function AgentComposer({
21651
22066
  )
21652
22067
  }
21653
22068
  ),
21654
- composerSettings.supportsPlanMode && composerSettings.draftSettings.planMode ? /* @__PURE__ */ jsx28(
21655
- "button",
22069
+ showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs15(
22070
+ Select2,
21656
22071
  {
21657
- type: "button",
21658
- disabled: settingsControlsDisabled,
21659
- "aria-label": labels.planModeLabel,
21660
- title: labels.planModeLabel,
22072
+ value: selectedProviderTargetId,
22073
+ disabled: providerSelectDisabled,
22074
+ onValueChange: (nextTargetId) => {
22075
+ const target = providerSwitchTargets.find(
22076
+ (candidate) => candidate.targetId === nextTargetId
22077
+ );
22078
+ if (!target) {
22079
+ return;
22080
+ }
22081
+ onProviderSelect?.({
22082
+ provider: target.provider,
22083
+ providerTargetId: target.targetId
22084
+ });
22085
+ },
22086
+ children: [
22087
+ /* @__PURE__ */ jsx28(
22088
+ SelectTrigger2,
22089
+ {
22090
+ size: "sm",
22091
+ "aria-label": labels.providerSwitchLabel,
22092
+ title: labels.providerSwitchLabel,
22093
+ className: cn(
22094
+ AgentGUINode_styles_default.composerMenuTrigger,
22095
+ AgentGUINode_styles_default.composerProviderSelect,
22096
+ "max-w-[160px] text-[var(--agent-gui-text-secondary)]"
22097
+ ),
22098
+ children: /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx28(SelectValue, { placeholder: selectedProviderLabel }) })
22099
+ }
22100
+ ),
22101
+ /* @__PURE__ */ jsx28(
22102
+ SelectContent2,
22103
+ {
22104
+ align: "start",
22105
+ className: cn(AgentGUINode_styles_default.composerMenuContent, "min-w-[190px]"),
22106
+ children: providerSwitchTargets.map((target) => /* @__PURE__ */ jsx28(
22107
+ SelectItem2,
22108
+ {
22109
+ value: target.targetId,
22110
+ className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22111
+ children: /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
22112
+ /* @__PURE__ */ jsx28(
22113
+ "img",
22114
+ {
22115
+ alt: "",
22116
+ "aria-hidden": "true",
22117
+ className: "size-4 shrink-0 rounded-[4px]",
22118
+ src: resolveComposerProviderTargetIconUrl(target)
22119
+ }
22120
+ ),
22121
+ /* @__PURE__ */ jsx28("span", { className: "min-w-0 truncate", children: target.label })
22122
+ ] })
22123
+ },
22124
+ `${target.provider}:${target.targetId}`
22125
+ ))
22126
+ }
22127
+ )
22128
+ ]
22129
+ }
22130
+ ) : null,
22131
+ composerSettings.supportsPlanMode && composerSettings.draftSettings.planMode ? /* @__PURE__ */ jsx28(
22132
+ "button",
22133
+ {
22134
+ type: "button",
22135
+ disabled: settingsControlsDisabled,
22136
+ "aria-label": labels.planModeLabel,
22137
+ title: labels.planModeLabel,
21661
22138
  "data-agent-plan-mode-badge": "true",
21662
22139
  className: cn(
21663
22140
  AgentGUINode_styles_default.composerMenuTrigger,
@@ -22258,7 +22735,7 @@ function groupConversations(conversations, labels, userProjects = [], options =
22258
22735
  }
22259
22736
  groups.push(
22260
22737
  ...[...projectGroups.values()].sort(
22261
- (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)
22738
+ (left, right) => left.sectionOrder - right.sectionOrder || right.projectUpdatedAtUnixMs - left.projectUpdatedAtUnixMs || left.projectOrder - right.projectOrder || left.label.localeCompare(right.label) || left.id.localeCompare(right.id)
22262
22739
  ).map(
22263
22740
  ({
22264
22741
  projectOrder: _projectOrder,
@@ -22468,7 +22945,7 @@ function resolveConversationDetailStatus(detail) {
22468
22945
  function objectRecord(value) {
22469
22946
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
22470
22947
  }
22471
- function numberValue(value) {
22948
+ function numberValue2(value) {
22472
22949
  if (typeof value === "number" && Number.isFinite(value)) {
22473
22950
  return value;
22474
22951
  }
@@ -22488,8 +22965,8 @@ function resolveSlashStatus({
22488
22965
  }) {
22489
22966
  const usage = objectRecord(rawState?.runtimeContext?.usage);
22490
22967
  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) ? {
22491
- usedTokens: numberValue(usage.usedTokens) ?? numberValue(usage.used_tokens) ?? numberValue(usage.used),
22492
- totalTokens: numberValue(usage.totalTokens) ?? numberValue(usage.total_tokens) ?? numberValue(usage.size)
22968
+ usedTokens: numberValue2(usage.usedTokens) ?? numberValue2(usage.used_tokens) ?? numberValue2(usage.used),
22969
+ totalTokens: numberValue2(usage.totalTokens) ?? numberValue2(usage.total_tokens) ?? numberValue2(usage.size)
22493
22970
  } : null);
22494
22971
  const providerConfig = objectRecord(rawState?.runtimeContext?.providerConfig);
22495
22972
  return {
@@ -22498,8 +22975,8 @@ function resolveSlashStatus({
22498
22975
  limits,
22499
22976
  limitsLoading: limitsLoading || isAppServerStartupLoading2(rawState, "rateLimits"),
22500
22977
  contextWindow: contextWindow ? {
22501
- usedTokens: numberValue(contextWindow.usedTokens) ?? numberValue(contextWindow.used_tokens),
22502
- totalTokens: numberValue(contextWindow.totalTokens) ?? numberValue(contextWindow.total_tokens)
22978
+ usedTokens: numberValue2(contextWindow.usedTokens) ?? numberValue2(contextWindow.used_tokens),
22979
+ totalTokens: numberValue2(contextWindow.totalTokens) ?? numberValue2(contextWindow.total_tokens)
22503
22980
  } : null
22504
22981
  };
22505
22982
  }
@@ -22934,7 +23411,14 @@ function AgentGUINodeView({
22934
23411
  openclawGateway,
22935
23412
  isCollapsed: conversationRailCollapsed,
22936
23413
  slashStatusLimits,
23414
+ selectedProviderTarget: viewModel.selectedProviderTarget,
23415
+ providerTargets: viewModel.providerTargets,
23416
+ providerTargetsLoading: viewModel.providerTargetsLoading,
23417
+ conversationScope: viewModel.conversationScope,
23418
+ conversationFilter: viewModel.conversationFilter,
22937
23419
  onCreateConversation: requestCreateConversation,
23420
+ onUpdateConversationFilter: actions.updateConversationFilter,
23421
+ onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
22938
23422
  onOpenAgentEnvSetup: openAgentEnvSetup,
22939
23423
  onRetryOpenclawGateway: retryOpenclawGateway,
22940
23424
  onSelectConversation: selectConversation,
@@ -22961,6 +23445,7 @@ function AgentGUINodeView({
22961
23445
  openConversationWindow,
22962
23446
  openProjectFiles,
22963
23447
  openclawGateway,
23448
+ actions.updateConversationFilter,
22964
23449
  previewMode,
22965
23450
  removeProject,
22966
23451
  requestCreateConversation,
@@ -22969,8 +23454,13 @@ function AgentGUINodeView({
22969
23454
  selectConversation,
22970
23455
  selectProjectDirectory,
22971
23456
  slashStatusLimits,
23457
+ viewModel.selectedProviderTarget,
23458
+ viewModel.providerTargets,
23459
+ viewModel.providerTargetsLoading,
22972
23460
  toggleConversationPinned,
22973
23461
  uiLanguage,
23462
+ viewModel.conversationScope,
23463
+ viewModel.conversationFilter,
22974
23464
  viewModel.activeConversationId,
22975
23465
  viewModel.isDeletingConversation,
22976
23466
  viewModel.isDeletingProjectConversations,
@@ -22992,7 +23482,21 @@ function AgentGUINodeView({
22992
23482
  conversationRailStore,
22993
23483
  conversationRailStoreState
22994
23484
  );
22995
- const content = /* @__PURE__ */ jsxs17(Fragment8, { children: [
23485
+ const agentTargetPresentations = useMemo10(
23486
+ () => viewModel.providerTargets.flatMap(
23487
+ (target) => target.agentTargetId ? [
23488
+ {
23489
+ agentTargetId: target.agentTargetId,
23490
+ iconUrl: target.iconUrl ?? null,
23491
+ name: target.label,
23492
+ provider: target.provider,
23493
+ workspaceId: viewModel.workspaceId
23494
+ }
23495
+ ] : []
23496
+ ),
23497
+ [viewModel.providerTargets, viewModel.workspaceId]
23498
+ );
23499
+ const content = /* @__PURE__ */ jsxs17(AgentTargetPresentationProvider, { agentTargets: agentTargetPresentations, children: [
22996
23500
  /* @__PURE__ */ jsxs17(
22997
23501
  "div",
22998
23502
  {
@@ -23014,11 +23518,9 @@ function AgentGUINodeView({
23014
23518
  AgentGUIConversationRailStorePane,
23015
23519
  {
23016
23520
  conversations: viewModel.conversations,
23017
- provider: viewModel.data.provider,
23018
23521
  store: conversationRailStore,
23019
23522
  storeState: conversationRailStoreState,
23020
- userProjects: viewModel.userProjects,
23021
- workspaceId: viewModel.workspaceId
23523
+ userProjects: viewModel.userProjects
23022
23524
  }
23023
23525
  )
23024
23526
  }
@@ -23520,6 +24022,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23520
24022
  removeMention: labels.removeMention,
23521
24023
  addReference: labels.addReference,
23522
24024
  referenceWorkspaceFiles: labels.referenceWorkspaceFiles,
24025
+ providerSwitchLabel: labels.providerSwitchLabel,
23523
24026
  projectLocked: labels.projectLocked,
23524
24027
  projectMissingDescription: labels.projectMissingDescription,
23525
24028
  promptTipsPrefix: labels.promptTipsPrefix,
@@ -23560,6 +24063,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23560
24063
  labels.queuedLabel,
23561
24064
  labels.queuedPromptMoreActions,
23562
24065
  labels.referenceWorkspaceFiles,
24066
+ labels.providerSwitchLabel,
23563
24067
  labels.removeMention,
23564
24068
  labels.reasoningDegreeLabel,
23565
24069
  labels.reasoningLabel,
@@ -23668,6 +24172,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23668
24172
  const submitPromptAndScrollToBottom = useCallback10(
23669
24173
  (content, displayPrompt) => {
23670
24174
  requestSubmittedPromptScrollToBottom();
24175
+ if (displayPrompt === void 0) {
24176
+ submitPrompt(content);
24177
+ return;
24178
+ }
23671
24179
  submitPrompt(content, displayPrompt);
23672
24180
  },
23673
24181
  [requestSubmittedPromptScrollToBottom, submitPrompt]
@@ -23675,6 +24183,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23675
24183
  const submitGuidancePromptAndScrollToBottom = useCallback10(
23676
24184
  (content, displayPrompt) => {
23677
24185
  requestSubmittedPromptScrollToBottom();
24186
+ if (displayPrompt === void 0) {
24187
+ submitGuidancePrompt(content);
24188
+ return;
24189
+ }
23678
24190
  submitGuidancePrompt(content, displayPrompt);
23679
24191
  },
23680
24192
  [requestSubmittedPromptScrollToBottom, submitGuidancePrompt]
@@ -23699,6 +24211,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23699
24211
  );
23700
24212
  const stableRequestGitBranches = useOptionalStableEventCallback(onRequestGitBranches);
23701
24213
  const authLogin = useOptionalStableEventCallback(onAgentProviderLogin);
24214
+ const backgroundAgentStatusText = viewModel.backgroundAgentCount > 0 ? labels.waitingForBackgroundAgent(viewModel.backgroundAgentCount) : null;
23702
24215
  const submitBottomDockInteractivePrompt = useCallback10(
23703
24216
  (input) => {
23704
24217
  submitInteractivePrompt(input);
@@ -23706,12 +24219,17 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23706
24219
  },
23707
24220
  [submitInteractivePrompt]
23708
24221
  );
24222
+ const canSwitchComposerProvider = viewModel.conversationScope === "multi-provider";
24223
+ const composerProviderTargets = canSwitchComposerProvider ? viewModel.providerTargets : [viewModel.selectedProviderTarget];
23709
24224
  const bottomDockComposerProps = useMemo10(
23710
24225
  () => ({
23711
24226
  workspaceId: viewModel.workspaceId,
23712
24227
  workspacePath: viewModel.workspacePath,
23713
24228
  currentUserId: viewModel.currentUserId,
23714
24229
  provider: viewModel.data.provider,
24230
+ selectedProviderTarget: viewModel.selectedProviderTarget,
24231
+ providerTargets: composerProviderTargets,
24232
+ providerSelectReadonly: !canSwitchComposerProvider || viewModel.activeConversationId !== null,
23715
24233
  slashStatus,
23716
24234
  usage: viewModel.usage,
23717
24235
  draftContent: viewModel.draftContent,
@@ -23733,6 +24251,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23733
24251
  // Plan decisions replace the composer via bottomDockReplacementPrompt;
23734
24252
  // approval / ask-user embed here (composerActivePrompt encodes that).
23735
24253
  activePrompt: composerActivePrompt,
24254
+ backgroundAgentStatusText,
23736
24255
  activePromptKeyboardShortcutsEnabled: isActive,
23737
24256
  promptTips: labels.promptTips,
23738
24257
  composerFocusRequestSequence,
@@ -23748,6 +24267,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23748
24267
  onDraftContentChange: updateDraftContent,
23749
24268
  onProjectPathChange: updateSelectedProjectPath,
23750
24269
  onSettingsChange: updateComposerSettings,
24270
+ onProviderSelect: canSwitchComposerProvider ? actions.selectProvider : void 0,
23751
24271
  onSubmit: submitPromptAndScrollToBottom,
23752
24272
  onSubmitGuidance: submitGuidancePromptAndScrollToBottom,
23753
24273
  onPromptImagesUnsupported: showPromptImagesUnsupported,
@@ -23766,7 +24286,10 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23766
24286
  }),
23767
24287
  [
23768
24288
  canQueueWhileBusy,
24289
+ backgroundAgentStatusText,
24290
+ canSwitchComposerProvider,
23769
24291
  capabilityMenuState,
24292
+ composerProviderTargets,
23770
24293
  composerDisabled,
23771
24294
  composerDisabledReason,
23772
24295
  composerFocusRequestSequence,
@@ -23798,6 +24321,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23798
24321
  stableSelectProjectDirectory,
23799
24322
  stableRequestWorkspaceReferences,
23800
24323
  updateComposerSettings,
24324
+ actions.selectProvider,
23801
24325
  updateDraftContent,
23802
24326
  updateSelectedProjectPath,
23803
24327
  viewModel.availableCommands,
@@ -23806,6 +24330,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23806
24330
  viewModel.composerSettings,
23807
24331
  viewModel.currentUserId,
23808
24332
  viewModel.data.provider,
24333
+ viewModel.selectedProviderTarget,
23809
24334
  viewModel.draftContent,
23810
24335
  viewModel.draftPrompt,
23811
24336
  viewModel.drainingQueuedPromptId,
@@ -23859,6 +24384,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
23859
24384
  sessionChrome.auth?.message ?? "",
23860
24385
  sessionChrome.recovery?.kind ?? "",
23861
24386
  sessionChrome.recovery?.message ?? "",
24387
+ backgroundAgentStatusText ?? "",
23862
24388
  viewModel.queuedPrompts.map((prompt) => prompt.id).join(","),
23863
24389
  viewModel.drainingQueuedPromptId ?? "",
23864
24390
  viewModel.isRespondingApproval ? "1" : "0"
@@ -24340,8 +24866,8 @@ var AgentGUIBottomDockPane = memo(function AgentGUIBottomDockPane2({
24340
24866
  const goal = objectRecord(sessionChrome.rawState?.runtimeContext?.goal);
24341
24867
  const goalObjective = goal ? stringValue2(goal.objective) : "";
24342
24868
  const goalStatus = goal ? stringValue2(goal.status) : "";
24343
- const goalTokenBudget = goal ? numberValue(goal.tokenBudget) : null;
24344
- const goalTokensUsed = goal ? numberValue(goal.tokensUsed) : null;
24869
+ const goalTokenBudget = goal ? numberValue2(goal.tokenBudget) : null;
24870
+ const goalTokensUsed = goal ? numberValue2(goal.tokensUsed) : null;
24345
24871
  const showGoalBanner = isGoalBannerVisible(goalObjective, goalStatus);
24346
24872
  return /* @__PURE__ */ jsxs17(
24347
24873
  "div",
@@ -24438,16 +24964,14 @@ function syncAgentGUIConversationRailStore(store, next) {
24438
24964
  Object.assign(store, next);
24439
24965
  }
24440
24966
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
24441
- 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;
24967
+ 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.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;
24442
24968
  }
24443
24969
  var AgentGUIConversationRailStorePane = memo(
24444
24970
  function AgentGUIConversationRailStorePane2({
24445
24971
  conversations,
24446
- provider,
24447
24972
  store,
24448
24973
  storeState: _storeState,
24449
- userProjects,
24450
- workspaceId
24974
+ userProjects
24451
24975
  }) {
24452
24976
  "use memo";
24453
24977
  const state = useSnapshot(store);
@@ -24456,9 +24980,7 @@ var AgentGUIConversationRailStorePane = memo(
24456
24980
  {
24457
24981
  ...state,
24458
24982
  conversations,
24459
- provider,
24460
- userProjects,
24461
- workspaceId
24983
+ userProjects
24462
24984
  }
24463
24985
  );
24464
24986
  }
@@ -24470,47 +24992,6 @@ function normalizeConversationRailProjectPath(path) {
24470
24992
  }
24471
24993
  return normalized.replace(/\/+$/, "") || "/";
24472
24994
  }
24473
- function buildRailSessionGroupProjects({
24474
- groups,
24475
- userProjects
24476
- }) {
24477
- const userProjectByPath = new Map(
24478
- userProjects.map((project) => [
24479
- normalizeConversationRailProjectPath(project.path),
24480
- project
24481
- ])
24482
- );
24483
- const groupProjectPaths = /* @__PURE__ */ new Set();
24484
- const groupProjects = [];
24485
- for (const group of groups) {
24486
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24487
- if (!normalizedPath || groupProjectPaths.has(normalizedPath)) {
24488
- continue;
24489
- }
24490
- groupProjectPaths.add(normalizedPath);
24491
- const existingProject = userProjectByPath.get(normalizedPath);
24492
- groupProjects.push({
24493
- ...existingProject ?? {
24494
- id: `agent-session-group:${normalizedPath}`,
24495
- label: labelFromProjectPath(normalizedPath),
24496
- path: group.cwd
24497
- },
24498
- lastUsedAtUnixMs: group.latestSessionUpdatedAtUnixMs,
24499
- updatedAtUnixMs: group.latestSessionUpdatedAtUnixMs
24500
- });
24501
- }
24502
- const emptyUserProjects = userProjects.filter(
24503
- (project) => !groupProjectPaths.has(normalizeConversationRailProjectPath(project.path))
24504
- );
24505
- return [...groupProjects, ...emptyUserProjects];
24506
- }
24507
- function labelFromProjectPath(path) {
24508
- const normalized = normalizeConversationRailProjectPath(path);
24509
- if (!normalized || normalized === "/") {
24510
- return path || "/";
24511
- }
24512
- return normalized.split("/").filter(Boolean).at(-1) ?? normalized;
24513
- }
24514
24995
  function stabilizeConversationSections(previous, next) {
24515
24996
  if (!previous) {
24516
24997
  return [...next];
@@ -24544,37 +25025,6 @@ function stabilizeConversationSections(previous, next) {
24544
25025
  });
24545
25026
  return changed ? stable : previous;
24546
25027
  }
24547
- function mergeRefreshedRailSessionGroups(current, refreshed) {
24548
- const currentByCwd = new Map(current.map((group) => [group.cwd, group]));
24549
- return refreshed.map((group) => {
24550
- const existing = currentByCwd.get(group.cwd);
24551
- if (!existing || existing.sessions.length <= group.sessions.length) {
24552
- return group;
24553
- }
24554
- const sessionIds = new Set(
24555
- group.sessions.map((session) => session.agentSessionId)
24556
- );
24557
- const sessions = [...group.sessions];
24558
- for (const session of existing.sessions) {
24559
- if (sessions.length >= group.sessionCount) {
24560
- break;
24561
- }
24562
- if (sessionIds.has(session.agentSessionId)) {
24563
- continue;
24564
- }
24565
- sessionIds.add(session.agentSessionId);
24566
- sessions.push(session);
24567
- }
24568
- const preservedLoadedPages = sessions.length > group.sessions.length;
24569
- const hasMore = preservedLoadedPages ? existing.hasMore && sessions.length < group.sessionCount : group.hasMore;
24570
- return {
24571
- ...group,
24572
- hasMore,
24573
- nextCursor: hasMore ? preservedLoadedPages ? existing.nextCursor : group.nextCursor : void 0,
24574
- sessions
24575
- };
24576
- });
24577
- }
24578
25028
  function stabilizeConversationSectionItems(previous, next) {
24579
25029
  if (previous.length !== next.length) {
24580
25030
  const previousById = /* @__PURE__ */ new Map();
@@ -24611,11 +25061,163 @@ function conversationSyncStatesRenderEqual(left, right) {
24611
25061
  function conversationProjectsRenderEqual2(left, right) {
24612
25062
  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);
24613
25063
  }
25064
+ var agentGUIProviderRailOrder = [
25065
+ "nexight",
25066
+ "claude-code",
25067
+ "codex",
25068
+ "openclaw",
25069
+ "hermes",
25070
+ "gemini"
25071
+ ];
25072
+ function agentGUIProviderRailOrderIndex(provider) {
25073
+ const index = agentGUIProviderRailOrder.indexOf(provider);
25074
+ return index < 0 ? agentGUIProviderRailOrder.length : index;
25075
+ }
25076
+ function agentGUIProviderRailLabel(provider, targetLabel, labels) {
25077
+ if (targetLabel.trim() && targetLabel !== provider) {
25078
+ return targetLabel;
25079
+ }
25080
+ if (provider === "codex") {
25081
+ return labels.conversationFilterCodex;
25082
+ }
25083
+ if (provider === "claude-code") {
25084
+ return labels.conversationFilterClaudeCode;
25085
+ }
25086
+ return targetLabel;
25087
+ }
25088
+ function agentGUIProviderTargetMatchesConversationFilter(target, filter) {
25089
+ return filter.kind === "agentTarget" && (target.agentTargetId?.trim() ?? "") === filter.agentTargetId;
25090
+ }
25091
+ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
25092
+ conversationFilter,
25093
+ labels,
25094
+ previewMode,
25095
+ providerTargets,
25096
+ providerTargetsLoading,
25097
+ onSelectConversationFilterTarget,
25098
+ onUpdateConversationFilter
25099
+ }) {
25100
+ "use memo";
25101
+ const providerTiles = useMemo10(() => {
25102
+ const enabledTargets = providerTargets.filter(
25103
+ (target) => target.disabled !== true
25104
+ );
25105
+ const targets = [...enabledTargets];
25106
+ const originalIndexByTarget = /* @__PURE__ */ new Map();
25107
+ targets.forEach((target, index) => {
25108
+ originalIndexByTarget.set(
25109
+ `${target.provider}\0${target.targetId}`,
25110
+ index
25111
+ );
25112
+ });
25113
+ return targets.sort((left, right) => {
25114
+ const orderDelta = agentGUIProviderRailOrderIndex(left.provider) - agentGUIProviderRailOrderIndex(right.provider);
25115
+ if (orderDelta !== 0) {
25116
+ return orderDelta;
25117
+ }
25118
+ return (originalIndexByTarget.get(`${left.provider}\0${left.targetId}`) ?? 0) - (originalIndexByTarget.get(
25119
+ `${right.provider}\0${right.targetId}`
25120
+ ) ?? 0);
25121
+ });
25122
+ }, [providerTargets]);
25123
+ const allTileSelected = conversationFilter.kind === "all";
25124
+ const selectAllProviders = useCallback10(() => {
25125
+ onUpdateConversationFilter({ kind: "all" });
25126
+ }, [onUpdateConversationFilter]);
25127
+ const selectProviderTile = useCallback10(
25128
+ (target) => {
25129
+ onSelectConversationFilterTarget({
25130
+ provider: target.provider,
25131
+ providerTargetId: target.targetId
25132
+ });
25133
+ },
25134
+ [onSelectConversationFilterTarget]
25135
+ );
25136
+ return /* @__PURE__ */ jsxs17(
25137
+ "div",
25138
+ {
25139
+ className: AgentGUINode_styles_default.providerRail,
25140
+ role: "tablist",
25141
+ "aria-label": labels.providerSwitchLabel,
25142
+ "aria-busy": providerTargetsLoading,
25143
+ children: [
25144
+ /* @__PURE__ */ jsxs17(
25145
+ "button",
25146
+ {
25147
+ type: "button",
25148
+ role: "tab",
25149
+ "aria-selected": allTileSelected,
25150
+ className: AgentGUINode_styles_default.providerRailTile,
25151
+ "data-selected": allTileSelected ? "true" : "false",
25152
+ disabled: previewMode,
25153
+ onClick: selectAllProviders,
25154
+ children: [
25155
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(LayoutGrid, { "aria-hidden": true, className: AgentGUINode_styles_default.providerRailAvatarIcon }) }),
25156
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: labels.conversationFilterAll })
25157
+ ]
25158
+ }
25159
+ ),
25160
+ providerTargetsLoading ? [0, 1, 2].map((index) => /* @__PURE__ */ jsxs17(
25161
+ "button",
25162
+ {
25163
+ type: "button",
25164
+ role: "tab",
25165
+ "aria-selected": "false",
25166
+ className: AgentGUINode_styles_default.providerRailTile,
25167
+ "data-loading": "true",
25168
+ "data-selected": "false",
25169
+ disabled: true,
25170
+ children: [
25171
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar }),
25172
+ /* @__PURE__ */ jsx31(
25173
+ "span",
25174
+ {
25175
+ "aria-hidden": "true",
25176
+ className: AgentGUINode_styles_default.providerRailTileLabel
25177
+ }
25178
+ )
25179
+ ]
25180
+ },
25181
+ `provider-target-loading-${index}`
25182
+ )) : null,
25183
+ providerTiles.map((target) => {
25184
+ const providerSelected = agentGUIProviderTargetMatchesConversationFilter(
25185
+ target,
25186
+ conversationFilter
25187
+ );
25188
+ return /* @__PURE__ */ jsxs17(
25189
+ "button",
25190
+ {
25191
+ type: "button",
25192
+ role: "tab",
25193
+ "aria-selected": providerSelected,
25194
+ className: AgentGUINode_styles_default.providerRailTile,
25195
+ "data-selected": providerSelected ? "true" : "false",
25196
+ disabled: previewMode,
25197
+ onClick: () => selectProviderTile(target),
25198
+ children: [
25199
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
25200
+ "img",
25201
+ {
25202
+ alt: "",
25203
+ "aria-hidden": "true",
25204
+ className: AgentGUINode_styles_default.providerRailAvatarImage,
25205
+ src: target.iconUrl || resolveAgentGUIHeroIconUrl(target.provider)
25206
+ }
25207
+ ) }),
25208
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: agentGUIProviderRailLabel(target.provider, target.label, labels) })
25209
+ ]
25210
+ },
25211
+ `${target.provider}:${target.targetId}`
25212
+ );
25213
+ })
25214
+ ]
25215
+ }
25216
+ );
25217
+ });
24614
25218
  var AgentGUIConversationRailPane = memo(
24615
25219
  function AgentGUIConversationRailPane2({
24616
25220
  conversations,
24617
- provider,
24618
- workspaceId,
24619
25221
  userProjects,
24620
25222
  activeConversationId,
24621
25223
  pendingDeleteConversationId,
@@ -24630,6 +25232,12 @@ var AgentGUIConversationRailPane = memo(
24630
25232
  openclawGateway,
24631
25233
  isCollapsed,
24632
25234
  slashStatusLimits,
25235
+ providerTargets,
25236
+ providerTargetsLoading,
25237
+ conversationScope,
25238
+ conversationFilter,
25239
+ onUpdateConversationFilter,
25240
+ onSelectConversationFilterTarget,
24633
25241
  onCreateConversation,
24634
25242
  onOpenAgentEnvSetup,
24635
25243
  onRetryOpenclawGateway,
@@ -24646,21 +25254,14 @@ var AgentGUIConversationRailPane = memo(
24646
25254
  onConfirmDeleteConversation
24647
25255
  }) {
24648
25256
  "use memo";
24649
- const agentActivityRuntime = useAgentActivityRuntime();
25257
+ const showProviderRail = conversationScope === "multi-provider";
24650
25258
  const [conversationQuery, setConversationQuery] = useState11("");
24651
- const [searchConversations, setSearchConversations] = useState11([]);
24652
- const [searchConversationQuery, setSearchConversationQuery] = useState11("");
24653
- const [searchHasMore, setSearchHasMore] = useState11(false);
24654
- const [searchNextCursor, setSearchNextCursor] = useState11(
24655
- null
25259
+ const updateConversationFilter = useStableEventCallback2(
25260
+ onUpdateConversationFilter
25261
+ );
25262
+ const selectConversationFilterTarget = useStableEventCallback2(
25263
+ onSelectConversationFilterTarget
24656
25264
  );
24657
- const [
24658
- isLoadingMoreSearchConversations,
24659
- setIsLoadingMoreSearchConversations
24660
- ] = useState11(false);
24661
- const [railSessionGroups, setRailSessionGroups] = useState11([]);
24662
- const [activeConversationOverlay, setActiveConversationOverlay] = useState11(null);
24663
- const [loadingMoreSectionIds, setLoadingMoreSectionIds] = useState11(() => /* @__PURE__ */ new Set());
24664
25265
  const [collapsedProjectSectionIds, setCollapsedProjectSectionIds] = useState11(() => /* @__PURE__ */ new Set());
24665
25266
  const [currentTimeMs, setCurrentTimeMs] = useState11(() => Date.now());
24666
25267
  const [pendingProjectAction, setPendingProjectAction] = useState11(null);
@@ -24670,7 +25271,6 @@ var AgentGUIConversationRailPane = memo(
24670
25271
  /* @__PURE__ */ new Map()
24671
25272
  );
24672
25273
  const groupedConversationsRef = useRef12(null);
24673
- const wasDeletingConversationRef = useRef12(false);
24674
25274
  useEffect12(() => {
24675
25275
  const timer = window.setInterval(() => {
24676
25276
  setCurrentTimeMs(Date.now());
@@ -24679,217 +25279,25 @@ var AgentGUIConversationRailPane = memo(
24679
25279
  window.clearInterval(timer);
24680
25280
  };
24681
25281
  }, []);
24682
- const trimmedConversationQuery = conversationQuery.trim();
24683
- const hasConversationQuery = trimmedConversationQuery.length > 0;
24684
- const hasRuntimeGroupSource = !previewMode && Boolean(agentActivityRuntime.listSessionGroups);
24685
- const conversationIdentityKey = useMemo10(
24686
- () => conversations.map((conversation) => conversation.id).join("|"),
24687
- [conversations]
24688
- );
24689
- const railSessionGroupProjects = useMemo10(
24690
- () => buildRailSessionGroupProjects({
24691
- groups: railSessionGroups,
24692
- userProjects
24693
- }),
24694
- [railSessionGroups, userProjects]
24695
- );
24696
- const defaultRailGroupConversations = useMemo10(() => {
24697
- const freshConversationById = new Map(
24698
- conversations.map((conversation) => [conversation.id, conversation])
24699
- );
24700
- return buildAgentGUIConversationSummaries({
24701
- provider,
24702
- snapshot: {
24703
- composerOptionsByProvider: {},
24704
- presences: [],
24705
- sessionMessagesById: {},
24706
- sessions: railSessionGroups.flatMap((group) => group.sessions),
24707
- workspaceId
24708
- },
24709
- userProjects: railSessionGroupProjects
24710
- }).map(
24711
- (conversation) => freshConversationById.get(conversation.id) ?? conversation
24712
- );
24713
- }, [
24714
- conversations,
24715
- provider,
24716
- railSessionGroupProjects,
24717
- railSessionGroups,
24718
- workspaceId
24719
- ]);
24720
- const defaultRailSourceConversations = useMemo10(() => {
24721
- const source = hasRuntimeGroupSource ? defaultRailGroupConversations : conversations;
24722
- if (!activeConversationOverlay || source.some((item) => item.id === activeConversationOverlay.id)) {
24723
- return source;
24724
- }
24725
- return [...source, activeConversationOverlay];
24726
- }, [
24727
- activeConversationOverlay,
24728
- conversations,
24729
- defaultRailGroupConversations,
24730
- hasRuntimeGroupSource
24731
- ]);
24732
- const effectiveSearchConversations = searchConversationQuery === trimmedConversationQuery ? searchConversations : [];
24733
- const railSourceConversations = hasConversationQuery ? effectiveSearchConversations : defaultRailSourceConversations;
24734
- const runtimeSearchSessions = agentActivityRuntime.searchSessions;
24735
- useEffect12(() => {
24736
- if (!activeConversationOverlay || activeConversationOverlay.id !== activeConversationId) {
24737
- return;
24738
- }
24739
- if (defaultRailGroupConversations.some(
24740
- (item) => item.id === activeConversationOverlay.id
24741
- )) {
24742
- setActiveConversationOverlay(null);
24743
- }
24744
- }, [
24745
- activeConversationId,
24746
- activeConversationOverlay,
24747
- defaultRailGroupConversations
24748
- ]);
24749
- useEffect12(() => {
24750
- if (!hasConversationQuery) {
24751
- setSearchConversationQuery("");
24752
- setSearchConversations([]);
24753
- setSearchHasMore(false);
24754
- setSearchNextCursor(null);
24755
- return;
24756
- }
24757
- if (!runtimeSearchSessions) {
24758
- return;
24759
- }
24760
- let disposed = false;
24761
- const timer = window.setTimeout(() => {
24762
- void runtimeSearchSessions({
24763
- limit: 100,
24764
- query: trimmedConversationQuery,
24765
- workspaceId
24766
- }).then((result) => {
24767
- if (disposed) {
24768
- return;
24769
- }
24770
- setSearchConversationQuery(trimmedConversationQuery);
24771
- setSearchConversations(
24772
- buildAgentGUIConversationSummaries({
24773
- provider,
24774
- snapshot: {
24775
- composerOptionsByProvider: {},
24776
- presences: [],
24777
- sessionMessagesById: {},
24778
- sessions: result.sessions,
24779
- workspaceId: result.workspaceId
24780
- },
24781
- userProjects
24782
- })
24783
- );
24784
- setSearchHasMore(result.hasMore);
24785
- setSearchNextCursor(result.nextCursor ?? null);
24786
- }).catch(() => {
24787
- if (!disposed) {
24788
- setSearchConversationQuery(trimmedConversationQuery);
24789
- setSearchConversations([]);
24790
- setSearchHasMore(false);
24791
- setSearchNextCursor(null);
24792
- }
24793
- });
24794
- }, 150);
24795
- return () => {
24796
- disposed = true;
24797
- window.clearTimeout(timer);
24798
- };
24799
- }, [
24800
- hasConversationQuery,
24801
- provider,
24802
- runtimeSearchSessions,
24803
- trimmedConversationQuery,
24804
- userProjects,
24805
- workspaceId
24806
- ]);
24807
- useEffect12(() => {
24808
- if (!hasConversationQuery || runtimeSearchSessions) {
24809
- return;
24810
- }
24811
- setSearchConversationQuery(trimmedConversationQuery);
24812
- setSearchConversations(
24813
- conversations.filter(
24814
- (candidate) => conversationPlainTitle(candidate, labels, uiLanguage).toLowerCase().includes(trimmedConversationQuery.toLowerCase())
24815
- )
24816
- );
24817
- setSearchHasMore(false);
24818
- setSearchNextCursor(null);
24819
- }, [
24820
- conversations,
24821
- hasConversationQuery,
24822
- labels,
24823
- runtimeSearchSessions,
24824
- trimmedConversationQuery,
24825
- uiLanguage
24826
- ]);
24827
- useEffect12(() => {
24828
- if (!agentActivityRuntime.listSessionGroups || previewMode) {
24829
- setRailSessionGroups([]);
24830
- return;
24831
- }
24832
- let disposed = false;
24833
- const isDeletingNow = isDeletingConversation || isDeletingProjectConversations;
24834
- const resetLoadedGroups = wasDeletingConversationRef.current && !isDeletingNow;
24835
- wasDeletingConversationRef.current = isDeletingNow;
24836
- void agentActivityRuntime.listSessionGroups({
24837
- sessionLimit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
24838
- visibleOnly: true,
24839
- workspaceId
24840
- }).then((result) => {
24841
- if (!disposed) {
24842
- setRailSessionGroups(
24843
- (current) => resetLoadedGroups ? result.groups : mergeRefreshedRailSessionGroups(current, result.groups)
24844
- );
24845
- }
24846
- }).catch(() => {
24847
- if (!disposed) {
24848
- setRailSessionGroups([]);
24849
- }
24850
- });
24851
- return () => {
24852
- disposed = true;
24853
- };
24854
- }, [
24855
- agentActivityRuntime,
24856
- conversationIdentityKey,
24857
- isDeletingConversation,
24858
- isDeletingProjectConversations,
24859
- previewMode,
24860
- workspaceId
24861
- ]);
24862
- const groupingProjects = hasConversationQuery ? [] : hasRuntimeGroupSource ? railSessionGroupProjects : userProjects;
24863
- const showEmptyConversationSection = useMemo10(
24864
- () => !hasConversationQuery && (hasRuntimeGroupSource ? railSessionGroups.some((group) => !group.cwd.trim()) : !conversations.some(
24865
- (conversation) => conversation.project == null
24866
- )),
24867
- [
24868
- conversations,
24869
- hasConversationQuery,
24870
- hasRuntimeGroupSource,
24871
- railSessionGroups
24872
- ]
24873
- );
24874
25282
  const filteredConversationResult = useMemo10(() => {
24875
25283
  const startedAtMs = agentGuiPerfNowMs();
24876
- const query = trimmedConversationQuery.toLowerCase();
24877
- const items = !query ? railSourceConversations : railSourceConversations.filter(
25284
+ const query = conversationQuery.trim().toLowerCase();
25285
+ const items = !query ? conversations : conversations.filter(
24878
25286
  (candidate) => conversationPlainTitle(candidate, labels, uiLanguage).toLowerCase().includes(query)
24879
25287
  );
24880
25288
  return {
24881
25289
  items,
24882
25290
  filterMs: roundAgentGuiPerfMs(agentGuiPerfNowMs() - startedAtMs)
24883
25291
  };
24884
- }, [labels, railSourceConversations, trimmedConversationQuery, uiLanguage]);
25292
+ }, [conversationQuery, conversations, labels, uiLanguage]);
24885
25293
  const filteredConversations = filteredConversationResult.items;
24886
25294
  const groupedConversationResult = useMemo10(() => {
24887
25295
  const startedAtMs = agentGuiPerfNowMs();
24888
25296
  const rawGroups = groupConversations(
24889
25297
  filteredConversations,
24890
25298
  labels,
24891
- groupingProjects,
24892
- { includeEmptyConversations: showEmptyConversationSection }
25299
+ conversationQuery.trim() ? [] : userProjects,
25300
+ { includeEmptyConversations: !conversationQuery.trim() }
24893
25301
  );
24894
25302
  const groups = stabilizeConversationSections(
24895
25303
  groupedConversationsRef.current,
@@ -24900,12 +25308,7 @@ var AgentGUIConversationRailPane = memo(
24900
25308
  groups,
24901
25309
  groupMs: roundAgentGuiPerfMs(agentGuiPerfNowMs() - startedAtMs)
24902
25310
  };
24903
- }, [
24904
- filteredConversations,
24905
- groupingProjects,
24906
- labels,
24907
- showEmptyConversationSection
24908
- ]);
25311
+ }, [conversationQuery, filteredConversations, labels, userProjects]);
24909
25312
  const groupedConversations = groupedConversationResult.groups;
24910
25313
  const toggleProjectSectionCollapsed = useCallback10((sectionId) => {
24911
25314
  setCollapsedProjectSectionIds((current) => {
@@ -24926,140 +25329,17 @@ var AgentGUIConversationRailPane = memo(
24926
25329
  );
24927
25330
  const projectConversationCountsByPath = useMemo10(() => {
24928
25331
  const counts = /* @__PURE__ */ new Map();
24929
- const pathsFromGroups = /* @__PURE__ */ new Set();
24930
- for (const group of railSessionGroups) {
24931
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24932
- if (!normalizedPath) {
24933
- continue;
24934
- }
24935
- counts.set(normalizedPath, group.sessionCount);
24936
- pathsFromGroups.add(normalizedPath);
24937
- }
24938
25332
  for (const conversation of conversations) {
24939
25333
  const normalizedPath = normalizeConversationRailProjectPath(
24940
25334
  conversation.project?.path
24941
25335
  );
24942
- if (!normalizedPath || pathsFromGroups.has(normalizedPath)) {
25336
+ if (!normalizedPath) {
24943
25337
  continue;
24944
25338
  }
24945
25339
  counts.set(normalizedPath, (counts.get(normalizedPath) ?? 0) + 1);
24946
25340
  }
24947
25341
  return counts;
24948
- }, [conversations, railSessionGroups]);
24949
- const railSessionGroupBySectionId = useMemo10(() => {
24950
- const groupsBySectionId = /* @__PURE__ */ new Map();
24951
- for (const group of railSessionGroups) {
24952
- const normalizedPath = normalizeConversationRailProjectPath(group.cwd);
24953
- groupsBySectionId.set(
24954
- normalizedPath ? `project:${normalizedPath}` : "conversations",
24955
- group
24956
- );
24957
- }
24958
- return groupsBySectionId;
24959
- }, [railSessionGroups]);
24960
- const loadMoreSectionConversations = useCallback10(
24961
- (sectionId) => {
24962
- const group = railSessionGroupBySectionId.get(sectionId);
24963
- const listSessionsPage = agentActivityRuntime.listSessionsPage;
24964
- if (!group?.hasMore || !group.nextCursor || !listSessionsPage) {
24965
- return;
24966
- }
24967
- setLoadingMoreSectionIds((current) => {
24968
- if (current.has(sectionId)) {
24969
- return current;
24970
- }
24971
- const next = new Set(current);
24972
- next.add(sectionId);
24973
- return next;
24974
- });
24975
- void listSessionsPage({
24976
- cursor: group.nextCursor,
24977
- cwd: group.cwd,
24978
- limit: AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
24979
- visibleOnly: true,
24980
- workspaceId
24981
- }).then((page) => {
24982
- setRailSessionGroups(
24983
- (current) => current.map((candidate) => {
24984
- if (candidate.cwd !== group.cwd) {
24985
- return candidate;
24986
- }
24987
- const sessionIds = new Set(
24988
- candidate.sessions.map((session) => session.agentSessionId)
24989
- );
24990
- const nextSessions = [...candidate.sessions];
24991
- for (const session of page.sessions) {
24992
- if (!sessionIds.has(session.agentSessionId)) {
24993
- sessionIds.add(session.agentSessionId);
24994
- nextSessions.push(session);
24995
- }
24996
- }
24997
- return {
24998
- ...candidate,
24999
- hasMore: page.hasMore,
25000
- nextCursor: page.nextCursor,
25001
- sessions: nextSessions
25002
- };
25003
- })
25004
- );
25005
- }).finally(() => {
25006
- setLoadingMoreSectionIds((current) => {
25007
- if (!current.has(sectionId)) {
25008
- return current;
25009
- }
25010
- const next = new Set(current);
25011
- next.delete(sectionId);
25012
- return next;
25013
- });
25014
- });
25015
- },
25016
- [agentActivityRuntime, railSessionGroupBySectionId, workspaceId]
25017
- );
25018
- const loadMoreSearchConversations = useCallback10(() => {
25019
- const searchSessions = agentActivityRuntime.searchSessions;
25020
- if (!searchSessions || !searchHasMore || !searchNextCursor || isLoadingMoreSearchConversations) {
25021
- return;
25022
- }
25023
- setIsLoadingMoreSearchConversations(true);
25024
- void searchSessions({
25025
- cursor: searchNextCursor,
25026
- limit: 100,
25027
- query: trimmedConversationQuery,
25028
- workspaceId
25029
- }).then((result) => {
25030
- const nextConversations = buildAgentGUIConversationSummaries({
25031
- provider,
25032
- snapshot: {
25033
- composerOptionsByProvider: {},
25034
- presences: [],
25035
- sessionMessagesById: {},
25036
- sessions: result.sessions,
25037
- workspaceId: result.workspaceId
25038
- },
25039
- userProjects
25040
- });
25041
- setSearchConversations((current) => {
25042
- const currentIds = new Set(current.map((item) => item.id));
25043
- return [
25044
- ...current,
25045
- ...nextConversations.filter((item) => !currentIds.has(item.id))
25046
- ];
25047
- });
25048
- setSearchHasMore(result.hasMore);
25049
- setSearchNextCursor(result.nextCursor ?? null);
25050
- }).finally(() => {
25051
- setIsLoadingMoreSearchConversations(false);
25052
- });
25053
- }, [
25054
- agentActivityRuntime,
25055
- isLoadingMoreSearchConversations,
25056
- provider,
25057
- searchHasMore,
25058
- searchNextCursor,
25059
- trimmedConversationQuery,
25060
- userProjects,
25061
- workspaceId
25062
- ]);
25342
+ }, [conversations]);
25063
25343
  const registerConversationItemElement = useCallback10(
25064
25344
  (itemId, element) => {
25065
25345
  if (element) {
@@ -25070,46 +25350,6 @@ var AgentGUIConversationRailPane = memo(
25070
25350
  },
25071
25351
  []
25072
25352
  );
25073
- const handleSelectConversation = useCallback10(
25074
- (agentSessionId) => {
25075
- const normalizedAgentSessionId = agentSessionId.trim();
25076
- if (!normalizedAgentSessionId) {
25077
- return;
25078
- }
25079
- const isLoadedConversation = conversations.some(
25080
- (conversation) => conversation.id === normalizedAgentSessionId
25081
- );
25082
- if (!hasConversationQuery || isLoadedConversation) {
25083
- onSelectConversation(normalizedAgentSessionId);
25084
- return;
25085
- }
25086
- void agentActivityRuntime.getSession(workspaceId, normalizedAgentSessionId).then((session) => {
25087
- const [overlay] = buildAgentGUIConversationSummaries({
25088
- provider,
25089
- snapshot: {
25090
- composerOptionsByProvider: {},
25091
- presences: [],
25092
- sessionMessagesById: {},
25093
- sessions: [session],
25094
- workspaceId
25095
- },
25096
- userProjects: railSessionGroupProjects
25097
- });
25098
- setActiveConversationOverlay(overlay ?? null);
25099
- onSelectConversation(normalizedAgentSessionId);
25100
- }).catch(() => {
25101
- });
25102
- },
25103
- [
25104
- agentActivityRuntime,
25105
- conversations,
25106
- hasConversationQuery,
25107
- onSelectConversation,
25108
- provider,
25109
- railSessionGroupProjects,
25110
- workspaceId
25111
- ]
25112
- );
25113
25353
  useLayoutEffect4(() => {
25114
25354
  if (!activeConversationId) {
25115
25355
  return;
@@ -25149,6 +25389,18 @@ var AgentGUIConversationRailPane = memo(
25149
25389
  }
25150
25390
  )
25151
25391
  ] }),
25392
+ showProviderRail ? /* @__PURE__ */ jsx31(
25393
+ AgentGUIProviderRail,
25394
+ {
25395
+ conversationFilter,
25396
+ labels,
25397
+ previewMode,
25398
+ providerTargets,
25399
+ providerTargetsLoading,
25400
+ onSelectConversationFilterTarget: selectConversationFilterTarget,
25401
+ onUpdateConversationFilter: updateConversationFilter
25402
+ }
25403
+ ) : null,
25152
25404
  openclawGateway?.status === "starting" ? /* @__PURE__ */ jsxs17("div", { className: AgentGUINode_styles_default.gatewayStatus, "data-state": "starting", children: [
25153
25405
  /* @__PURE__ */ jsx31(
25154
25406
  StatusDot,
@@ -25192,9 +25444,6 @@ var AgentGUIConversationRailPane = memo(
25192
25444
  const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
25193
25445
  const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
25194
25446
  const projectConversationCount = normalizedProjectPath ? projectConversationCountsByPath.get(normalizedProjectPath) ?? 0 : 0;
25195
- const sectionSessionGroup = railSessionGroupBySectionId.get(
25196
- section.id
25197
- );
25198
25447
  return /* @__PURE__ */ jsxs17(Fragment7, { children: [
25199
25448
  showProjectRailHeader ? /* @__PURE__ */ jsx31(
25200
25449
  AgentGUIProjectRailHeader,
@@ -25211,13 +25460,11 @@ var AgentGUIConversationRailPane = memo(
25211
25460
  createConversationDisabled,
25212
25461
  currentTimeMs,
25213
25462
  isDeletingConversation,
25214
- isLoadingMoreConversations: hasConversationQuery ? isLoadingMoreSearchConversations : loadingMoreSectionIds.has(section.id),
25215
25463
  isSectionCollapsed,
25216
25464
  labels,
25217
25465
  pendingDeleteConversationId,
25218
25466
  previewMode,
25219
25467
  projectConversationCount,
25220
- sectionHasMore: hasConversationQuery ? searchHasMore : Boolean(sectionSessionGroup?.hasMore),
25221
25468
  projectLabel,
25222
25469
  projectPath,
25223
25470
  registerItemElement: registerConversationItemElement,
@@ -25227,12 +25474,11 @@ var AgentGUIConversationRailPane = memo(
25227
25474
  onConfirmDeleteConversation,
25228
25475
  onCreateConversation,
25229
25476
  onRequestDeleteConversation,
25230
- onSelectConversation: handleSelectConversation,
25477
+ onSelectConversation,
25231
25478
  setPendingProjectAction,
25232
25479
  onToggleConversationPinned,
25233
25480
  onOpenProjectFiles,
25234
25481
  onOpenConversationWindow,
25235
- onLoadMoreConversations: hasConversationQuery ? loadMoreSearchConversations : loadMoreSectionConversations,
25236
25482
  onToggleProjectSectionCollapsed: toggleProjectSectionCollapsed
25237
25483
  }
25238
25484
  )
@@ -25362,8 +25608,6 @@ var AgentGUIConversationRailSection = memo(
25362
25608
  pendingDeleteConversationId,
25363
25609
  previewMode,
25364
25610
  isDeletingConversation,
25365
- isLoadingMoreConversations,
25366
- sectionHasMore,
25367
25611
  createConversationDisabled,
25368
25612
  currentTimeMs,
25369
25613
  labels,
@@ -25372,7 +25616,6 @@ var AgentGUIConversationRailSection = memo(
25372
25616
  onCreateConversation,
25373
25617
  onToggleProjectSectionCollapsed,
25374
25618
  onSelectConversation,
25375
- onLoadMoreConversations,
25376
25619
  setPendingProjectAction,
25377
25620
  onToggleConversationPinned,
25378
25621
  onOpenProjectFiles,
@@ -25388,29 +25631,16 @@ var AgentGUIConversationRailSection = memo(
25388
25631
  );
25389
25632
  const visibleItemCount = isSectionCollapsed ? 0 : Math.min(visibleItemLimit, section.items.length);
25390
25633
  const visibleItems = isSectionCollapsed ? [] : section.items.slice(0, visibleItemCount);
25391
- const canShowMore = !isSectionCollapsed && (visibleItemCount < section.items.length || sectionHasMore);
25634
+ const canShowMore = !isSectionCollapsed && visibleItemCount < section.items.length;
25392
25635
  const canShowLess = !isSectionCollapsed && visibleItemCount > AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE;
25393
25636
  const showMoreConversations = useCallback10(() => {
25394
- if (visibleItemCount >= section.items.length && sectionHasMore) {
25395
- onLoadMoreConversations(section.id);
25396
- setVisibleItemLimit(
25397
- (current) => current + AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
25398
- );
25399
- return;
25400
- }
25401
25637
  setVisibleItemLimit(
25402
25638
  (current) => Math.min(
25403
25639
  section.items.length,
25404
25640
  current + AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE
25405
25641
  )
25406
25642
  );
25407
- }, [
25408
- onLoadMoreConversations,
25409
- section.id,
25410
- section.items.length,
25411
- sectionHasMore,
25412
- visibleItemCount
25413
- ]);
25643
+ }, [section.items.length]);
25414
25644
  const showLessConversations = useCallback10(() => {
25415
25645
  setVisibleItemLimit(AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE);
25416
25646
  }, []);
@@ -25703,7 +25933,6 @@ var AgentGUIConversationRailSection = memo(
25703
25933
  {
25704
25934
  type: "button",
25705
25935
  className: AgentGUINode_styles_default.conversationSectionPaginationButton,
25706
- disabled: isLoadingMoreConversations,
25707
25936
  onClick: showMoreConversations,
25708
25937
  children: labels.showMoreConversations
25709
25938
  }
@@ -26156,6 +26385,10 @@ function formatQuotaPrimaryLine(row, t) {
26156
26385
  }
26157
26386
  function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
26158
26387
  if (probe.lastError?.code === "unsupported") {
26388
+ lines.push({
26389
+ label: t("agentHost.workspaceAgentProbeDetailQuota"),
26390
+ primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
26391
+ });
26159
26392
  return;
26160
26393
  }
26161
26394
  if (isLoadingUsage && !probe.usage) {
@@ -26164,6 +26397,12 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
26164
26397
  }
26165
26398
  const quotas = probe.usage?.quotas ?? [];
26166
26399
  if (quotas.length === 0) {
26400
+ if (probe.usage) {
26401
+ lines.push({
26402
+ label: t("agentHost.workspaceAgentProbeDetailQuota"),
26403
+ primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
26404
+ });
26405
+ }
26167
26406
  return;
26168
26407
  }
26169
26408
  const rows = buildCompactDisplayQuotas(quotas, t);
@@ -26228,13 +26467,20 @@ function getDockAgentProbeLineLabel(line) {
26228
26467
  function AgentProbeInfoPopover({
26229
26468
  lines,
26230
26469
  testId = "agent-probe-info",
26231
- className
26470
+ className,
26471
+ onOpen
26232
26472
  }) {
26233
26473
  "use memo";
26234
26474
  const anchorRef = useRef13(null);
26235
26475
  const popoverRef = useRef13(null);
26236
26476
  const [isOpen, setIsOpen] = useState12(false);
26237
26477
  const [popoverStyle, setPopoverStyle] = useState12(null);
26478
+ const openPopover = useCallback11(() => {
26479
+ if (!isOpen) {
26480
+ onOpen?.();
26481
+ }
26482
+ setIsOpen(true);
26483
+ }, [isOpen, onOpen]);
26238
26484
  const closeIfPointerLeavesPopover = useCallback11((event) => {
26239
26485
  const nextTarget = event.relatedTarget;
26240
26486
  if (nextTarget instanceof Node && (anchorRef.current?.contains(nextTarget) || popoverRef.current?.contains(nextTarget))) {
@@ -26296,7 +26542,7 @@ function AgentProbeInfoPopover({
26296
26542
  className: "desktop-dock-popup__agent-info-popover desktop-dock-popup__agent-info-popover--portal",
26297
26543
  role: "status",
26298
26544
  style: popoverStyle ?? void 0,
26299
- onMouseEnter: () => setIsOpen(true),
26545
+ onMouseEnter: openPopover,
26300
26546
  onMouseLeave: closeIfPointerLeavesPopover,
26301
26547
  children: /* @__PURE__ */ jsx32("ul", { className: "desktop-dock-popup__agent-info-list", children: lines.map((line) => {
26302
26548
  const label = getDockAgentProbeLineLabel(line);
@@ -26334,12 +26580,12 @@ function AgentProbeInfoPopover({
26334
26580
  "data-testid": testId,
26335
26581
  onMouseEnter: () => {
26336
26582
  updatePopoverPosition();
26337
- setIsOpen(true);
26583
+ openPopover();
26338
26584
  },
26339
26585
  onMouseLeave: closeIfPointerLeavesPopover,
26340
26586
  onFocus: () => {
26341
26587
  updatePopoverPosition();
26342
- setIsOpen(true);
26588
+ openPopover();
26343
26589
  },
26344
26590
  onBlur: () => setIsOpen(false),
26345
26591
  children: [
@@ -26597,11 +26843,11 @@ function slashStatusQuotasFromRuntimeUsage(value) {
26597
26843
  return null;
26598
26844
  }
26599
26845
  const normalized = { quotaType };
26600
- const percentRemaining = numberValue2(record.percentRemaining);
26846
+ const percentRemaining = numberValue3(record.percentRemaining);
26601
26847
  if (percentRemaining !== null) {
26602
26848
  normalized.percentRemaining = percentRemaining;
26603
26849
  }
26604
- const resetsAtUnixMs = numberValue2(record.resetsAtUnixMs);
26850
+ const resetsAtUnixMs = numberValue3(record.resetsAtUnixMs);
26605
26851
  if (resetsAtUnixMs !== null) {
26606
26852
  normalized.resetsAtUnixMs = resetsAtUnixMs;
26607
26853
  }
@@ -26609,7 +26855,7 @@ function slashStatusQuotasFromRuntimeUsage(value) {
26609
26855
  if (resetText) {
26610
26856
  normalized.resetText = resetText;
26611
26857
  }
26612
- const dollarRemaining = numberValue2(record.dollarRemaining);
26858
+ const dollarRemaining = numberValue3(record.dollarRemaining);
26613
26859
  if (dollarRemaining !== null) {
26614
26860
  normalized.dollarRemaining = dollarRemaining;
26615
26861
  }
@@ -26636,7 +26882,7 @@ function agentUsageQuotaTypeValue(value) {
26636
26882
  function objectRecord2(value) {
26637
26883
  return value && typeof value === "object" ? value : null;
26638
26884
  }
26639
- function numberValue2(value) {
26885
+ function numberValue3(value) {
26640
26886
  if (typeof value === "number" && Number.isFinite(value)) {
26641
26887
  return value;
26642
26888
  }
@@ -26664,12 +26910,12 @@ function normalizeSlashStatusModelName(value) {
26664
26910
  return value?.trim().toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") ?? "";
26665
26911
  }
26666
26912
  function agentGuiStateEquals(left, right) {
26667
- return left === right || left.provider === right.provider && (left.providerTargetId ?? null) === (right.providerTargetId ?? null) && agentGUIProviderTargetRefsEqual(
26668
- left.providerTargetRef,
26669
- right.providerTargetRef
26670
- ) && 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(
26913
+ return left === right || left.provider === right.provider && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && 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(
26671
26914
  left.composerOverridesByProvider,
26672
26915
  right.composerOverridesByProvider
26916
+ ) && composerOverridesByAgentTargetIdEqual(
26917
+ left.composerOverridesByAgentTargetId,
26918
+ right.composerOverridesByAgentTargetId
26673
26919
  );
26674
26920
  }
26675
26921
  function composerOverridesByProviderEqual(left, right) {
@@ -26687,12 +26933,26 @@ function composerOverridesByProviderEqual(left, right) {
26687
26933
  }
26688
26934
  return true;
26689
26935
  }
26936
+ function composerOverridesByAgentTargetIdEqual(left, right) {
26937
+ const keys = /* @__PURE__ */ new Set([
26938
+ ...Object.keys(left ?? {}),
26939
+ ...Object.keys(right ?? {})
26940
+ ]);
26941
+ for (const key of keys) {
26942
+ const leftSettings = left?.[key] ?? null;
26943
+ const rightSettings = right?.[key] ?? null;
26944
+ 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)) {
26945
+ return false;
26946
+ }
26947
+ }
26948
+ return true;
26949
+ }
26690
26950
  function areAgentGUINodePropsEqual(previous, next) {
26691
- 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(
26951
+ 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 && workspaceAgentProbeRenderStateEqualsForProvider(
26692
26952
  previous.workspaceAgentProbes,
26693
26953
  next.workspaceAgentProbes,
26694
26954
  previous.state.provider
26695
- ) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && 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;
26955
+ ) && 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;
26696
26956
  }
26697
26957
  var AgentGUINode = memo2(function AgentGUINode2({
26698
26958
  nodeId,
@@ -26719,7 +26979,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
26719
26979
  onCapabilitySettingsRequest,
26720
26980
  onAgentProviderLogin,
26721
26981
  providerTargets,
26982
+ providerTargetsLoading = false,
26722
26983
  defaultProviderTargetId = null,
26984
+ conversationScope = "single-provider",
26723
26985
  onWorkspaceFileReferencesAdded,
26724
26986
  onOpenConversationWindow,
26725
26987
  onClose,
@@ -26738,6 +27000,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
26738
27000
  onShowMessage,
26739
27001
  workspaceAgentProbes,
26740
27002
  onAgentProbeDemandChange,
27003
+ onAgentProbeRefreshRequest,
26741
27004
  managedAgentsState,
26742
27005
  contextMentionProviders,
26743
27006
  workspaceAppIcons,
@@ -26875,9 +27138,11 @@ var AgentGUINode = memo2(function AgentGUINode2({
26875
27138
  workspacePath,
26876
27139
  avoidGroupingEdits: agentSettings.avoidGroupingEdits,
26877
27140
  data: state,
27141
+ conversationScope,
26878
27142
  openSessionRequest,
26879
27143
  prefillPromptRequest,
26880
27144
  providerTargets,
27145
+ providerTargetsLoading,
26881
27146
  defaultProviderTargetId,
26882
27147
  previewMode,
26883
27148
  onDataChange: handleDataChange,
@@ -26916,6 +27181,36 @@ var AgentGUINode = memo2(function AgentGUINode2({
26916
27181
  fallbackAgentLabel: fallbackAgentTitle,
26917
27182
  language: locale
26918
27183
  }) : null;
27184
+ useEffect14(() => {
27185
+ if (previewMode || !viewModel.activeConversation) {
27186
+ return;
27187
+ }
27188
+ const conversationTitle = activeConversationDockTitle?.trim() ?? "";
27189
+ if (!conversationTitle) {
27190
+ return;
27191
+ }
27192
+ const conversationId = viewModel.activeConversation.id;
27193
+ if (state.lastActiveAgentSessionId === conversationId && state.lastActiveConversationTitle === conversationTitle) {
27194
+ return;
27195
+ }
27196
+ onUpdateNode((current) => {
27197
+ if (current.lastActiveAgentSessionId === conversationId && current.lastActiveConversationTitle === conversationTitle) {
27198
+ return current;
27199
+ }
27200
+ return {
27201
+ ...current,
27202
+ lastActiveAgentSessionId: conversationId,
27203
+ lastActiveConversationTitle: conversationTitle
27204
+ };
27205
+ });
27206
+ }, [
27207
+ activeConversationDockTitle,
27208
+ onUpdateNode,
27209
+ previewMode,
27210
+ state.lastActiveAgentSessionId,
27211
+ state.lastActiveConversationTitle,
27212
+ viewModel.activeConversation
27213
+ ]);
26919
27214
  const labels = useMemo11(
26920
27215
  () => ({
26921
27216
  initialPlaceholder: t("agentHost.agentGui.initialPlaceholder", {
@@ -27046,6 +27341,12 @@ var AgentGUINode = memo2(function AgentGUINode2({
27046
27341
  emptyProjectConversations: t(
27047
27342
  "agentHost.agentGui.emptyProjectConversations"
27048
27343
  ),
27344
+ conversationFilterAll: t("agentHost.agentGui.conversationFilterAll"),
27345
+ conversationFilterCodex: t("agentHost.agentGui.conversationFilterCodex"),
27346
+ conversationFilterClaudeCode: t(
27347
+ "agentHost.agentGui.conversationFilterClaudeCode"
27348
+ ),
27349
+ providerSwitchLabel: t("agentHost.agentGui.providerSwitchLabel"),
27049
27350
  startConversation: t("agentHost.agentGui.startConversation"),
27050
27351
  selectConversation: t("agentHost.agentGui.selectConversation"),
27051
27352
  loadingConversations: t("agentHost.agentGui.loadingConversations"),
@@ -27160,6 +27461,10 @@ var AgentGUINode = memo2(function AgentGUINode2({
27160
27461
  submitAnswers: t("agentHost.agentGui.submitAnswers"),
27161
27462
  answerPlaceholder: t("agentHost.agentGui.answerPlaceholder"),
27162
27463
  waitingForAnswer: t("agentHost.agentGui.waitingForAnswer"),
27464
+ waitingForBackgroundAgent: (count) => {
27465
+ const pluralKey = count === 1 ? "agentHost.agentGui.waitingForBackgroundAgent_one" : "agentHost.agentGui.waitingForBackgroundAgent_other";
27466
+ return t(pluralKey, { count });
27467
+ },
27163
27468
  thinkingLabel: t("agentHost.workspaceAgentSessionDetailThinking"),
27164
27469
  toolCallsLabel: (count) => t("agentHost.workspaceAgentSessionDetailToolCalls", { count }),
27165
27470
  openConversationWindow: t("agentHost.agentGui.openConversationWindow"),
@@ -27370,41 +27675,9 @@ var AgentGUINode = memo2(function AgentGUINode2({
27370
27675
  }),
27371
27676
  [t]
27372
27677
  );
27373
- const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle ?? state.lastActiveConversationTitle ?? null : null;
27678
+ const collapsedWindowConversationTitle = isConversationRailCollapsed ? activeConversationDockTitle : null;
27374
27679
  const windowTitle = collapsedWindowConversationTitle || (isConversationRailCollapsed ? activeConversationWindowTitle : null) || windowAgentTitle || title;
27375
27680
  const windowTitleIconUrl = agentGuiDockIconUrls[activeProvider] ?? null;
27376
- useEffect14(() => {
27377
- if (previewMode) {
27378
- return;
27379
- }
27380
- if (!viewModel.activeConversation) {
27381
- return;
27382
- }
27383
- const nextTitle = activeConversationDockTitle;
27384
- const previousTitle = state.lastActiveConversationTitle ?? null;
27385
- if (nextTitle === null && previousTitle !== null && viewModel.activeConversation.id === state.lastActiveAgentSessionId) {
27386
- return;
27387
- }
27388
- if ((state.lastActiveConversationTitle ?? null) === nextTitle) {
27389
- return;
27390
- }
27391
- onUpdateNode((current) => {
27392
- if ((current.lastActiveConversationTitle ?? null) === nextTitle) {
27393
- return current;
27394
- }
27395
- return {
27396
- ...current,
27397
- lastActiveConversationTitle: nextTitle
27398
- };
27399
- });
27400
- }, [
27401
- activeConversationDockTitle,
27402
- onUpdateNode,
27403
- previewMode,
27404
- state.lastActiveAgentSessionId,
27405
- state.lastActiveConversationTitle,
27406
- viewModel.activeConversation
27407
- ]);
27408
27681
  const activeProbeProvider = activeProvider;
27409
27682
  const activeAgentProbe = useMemo11(
27410
27683
  () => findWorkspaceAgentProbeForDockProvider(
@@ -27472,6 +27745,12 @@ var AgentGUINode = memo2(function AgentGUINode2({
27472
27745
  onAgentProbeDemandChange(null, probeSourceId);
27473
27746
  };
27474
27747
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
27748
+ const handleAgentProbeInfoOpen = useCallback12(() => {
27749
+ if (previewMode || !onAgentProbeRefreshRequest) {
27750
+ return;
27751
+ }
27752
+ onAgentProbeRefreshRequest(activeProbeProvider, `agent-gui:${nodeId}`);
27753
+ }, [activeProbeProvider, nodeId, onAgentProbeRefreshRequest, previewMode]);
27475
27754
  return /* @__PURE__ */ jsx33(
27476
27755
  WorkspaceNodeWindow,
27477
27756
  {
@@ -27504,7 +27783,8 @@ var AgentGUINode = memo2(function AgentGUINode2({
27504
27783
  {
27505
27784
  lines: agentProbeLines,
27506
27785
  testId: "agent-gui-window-agent-info",
27507
- className: AgentGUINode_styles_default.windowAgentInfo
27786
+ className: AgentGUINode_styles_default.windowAgentInfo,
27787
+ onOpen: handleAgentProbeInfoOpen
27508
27788
  }
27509
27789
  ),
27510
27790
  /* @__PURE__ */ jsx33(