@tutti-os/agent-gui 0.0.103 → 0.0.105

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 (81) hide show
  1. package/dist/{AgentGUI-D6IQ0F_N.d.ts → AgentGUI-Do6py-T_.d.ts} +10 -6
  2. package/dist/AgentRichTextReadonly-F6PHC5SX.js +18 -0
  3. package/dist/AgentRichTextReadonly-F6PHC5SX.js.map +1 -0
  4. package/dist/agent-conversation/index.d.ts +3 -3
  5. package/dist/agent-conversation/index.js +11 -7
  6. package/dist/agent-conversation/index.js.map +1 -1
  7. package/dist/agent-gui.d.ts +4 -4
  8. package/dist/agent-gui.js +18 -14
  9. package/dist/agent-message-center/index.d.ts +1 -1
  10. package/dist/agent-message-center/index.js +13 -9
  11. package/dist/agent-message-center/index.js.map +1 -1
  12. package/dist/{agentConversationVM-BzHZhwFP.d.ts → agentConversationVM-Bf3Zv3iI.d.ts} +12 -2
  13. package/dist/{agentFileMentionContracts-58IjMU-u.d.ts → agentFileMentionContracts-B70VnPWO.d.ts} +2 -0
  14. package/dist/{agentGuiNodeTypes-8U3q_frv.d.ts → agentGuiNodeTypes-DbgQBiYz.d.ts} +4 -2
  15. package/dist/app/renderer/agentactivity.css +99 -0
  16. package/dist/{chunk-SGGGE2F3.js → chunk-4ZWV57MF.js} +42 -10
  17. package/dist/chunk-4ZWV57MF.js.map +1 -0
  18. package/dist/{chunk-XZD5KTM4.js → chunk-6R7GHXRQ.js} +12 -6
  19. package/dist/chunk-6R7GHXRQ.js.map +1 -0
  20. package/dist/{chunk-UHOVZI6B.js → chunk-7MPN2JGL.js} +122 -154
  21. package/dist/chunk-7MPN2JGL.js.map +1 -0
  22. package/dist/{chunk-5X7YDOC6.js → chunk-D2JUDUYY.js} +1 -1
  23. package/dist/chunk-D2JUDUYY.js.map +1 -0
  24. package/dist/{chunk-IVY4OL7B.js → chunk-IR2CL2X2.js} +1119 -2178
  25. package/dist/chunk-IR2CL2X2.js.map +1 -0
  26. package/dist/{chunk-PCXBTG5X.js → chunk-J2HG7UCP.js} +46 -22
  27. package/dist/chunk-J2HG7UCP.js.map +1 -0
  28. package/dist/{chunk-WXMBD2O7.js → chunk-JG7HGKZL.js} +597 -63
  29. package/dist/chunk-JG7HGKZL.js.map +1 -0
  30. package/dist/chunk-KPMQGPYU.js +43 -0
  31. package/dist/chunk-KPMQGPYU.js.map +1 -0
  32. package/dist/{chunk-6PMLIVTI.js → chunk-LDZ6C3YV.js} +3 -39
  33. package/dist/chunk-LDZ6C3YV.js.map +1 -0
  34. package/dist/{chunk-L2MTZMVH.js → chunk-N3HTEYLZ.js} +1985 -1315
  35. package/dist/chunk-N3HTEYLZ.js.map +1 -0
  36. package/dist/{chunk-3ZBDWWCV.js → chunk-N4WVVCNI.js} +2 -2
  37. package/dist/{chunk-IBFGOAY3.js → chunk-OWW7CU4U.js} +2 -2
  38. package/dist/chunk-SN6UYX54.js +42 -0
  39. package/dist/chunk-SN6UYX54.js.map +1 -0
  40. package/dist/{chunk-RGG5UGJD.js → chunk-TKBEVCHG.js} +5 -5
  41. package/dist/chunk-TKBEVCHG.js.map +1 -0
  42. package/dist/chunk-UFIEUC3Y.js +755 -0
  43. package/dist/chunk-UFIEUC3Y.js.map +1 -0
  44. package/dist/{chunk-5Z4ZXXX4.js → chunk-V5ROOS2O.js} +124 -2
  45. package/dist/chunk-V5ROOS2O.js.map +1 -0
  46. package/dist/chunk-XJ34OIEQ.js +18 -0
  47. package/dist/chunk-XJ34OIEQ.js.map +1 -0
  48. package/dist/{chunk-ZRJS4MOQ.js → chunk-ZSJBCZUH.js} +54 -7
  49. package/dist/chunk-ZSJBCZUH.js.map +1 -0
  50. package/dist/context-mention-palette/index.d.ts +1 -1
  51. package/dist/context-mention-palette/index.js +10 -8
  52. package/dist/{contribution-CTVBPN0R.d.ts → contribution-C6K5YfJ7.d.ts} +1 -0
  53. package/dist/custom-mention.d.ts +6 -0
  54. package/dist/custom-mention.js +1 -1
  55. package/dist/i18n/index.d.ts +4 -4
  56. package/dist/i18n/index.js +2 -2
  57. package/dist/index.d.ts +6 -6
  58. package/dist/index.js +18 -14
  59. package/dist/index.js.map +1 -1
  60. package/dist/mention-search.d.ts +42 -6
  61. package/dist/mention-search.js +8 -6
  62. package/dist/workbench/contribution.d.ts +1 -1
  63. package/dist/workbench/contribution.js +3 -3
  64. package/dist/workbench/index.d.ts +3 -2
  65. package/dist/workbench/index.js +3 -3
  66. package/dist/workbench/sessionTitle.js +2 -2
  67. package/package.json +14 -14
  68. package/dist/chunk-5X7YDOC6.js.map +0 -1
  69. package/dist/chunk-5Z4ZXXX4.js.map +0 -1
  70. package/dist/chunk-6PMLIVTI.js.map +0 -1
  71. package/dist/chunk-IVY4OL7B.js.map +0 -1
  72. package/dist/chunk-L2MTZMVH.js.map +0 -1
  73. package/dist/chunk-PCXBTG5X.js.map +0 -1
  74. package/dist/chunk-RGG5UGJD.js.map +0 -1
  75. package/dist/chunk-SGGGE2F3.js.map +0 -1
  76. package/dist/chunk-UHOVZI6B.js.map +0 -1
  77. package/dist/chunk-WXMBD2O7.js.map +0 -1
  78. package/dist/chunk-XZD5KTM4.js.map +0 -1
  79. package/dist/chunk-ZRJS4MOQ.js.map +0 -1
  80. /package/dist/{chunk-3ZBDWWCV.js.map → chunk-N4WVVCNI.js.map} +0 -0
  81. /package/dist/{chunk-IBFGOAY3.js.map → chunk-OWW7CU4U.js.map} +0 -0
@@ -9,19 +9,23 @@ import {
9
9
  resolveAgentGuiSessionProviderFlatIconUrl,
10
10
  resolveNextAgentGUIConversationRailWidthPx,
11
11
  shouldAutoCollapseAgentGUIConversationRail
12
- } from "./chunk-ZRJS4MOQ.js";
12
+ } from "./chunk-ZSJBCZUH.js";
13
13
  import {
14
14
  AGENT_PROVIDERS,
15
15
  AGENT_PROVIDER_LABEL,
16
16
  deriveAgentGUIOptimisticConversationTitle,
17
17
  isAgentGUIProviderUnresolved,
18
18
  normalizeAgentGUIProviderIdentity,
19
+ resolveAgentGUIConversationBrowserFreeTitle,
19
20
  resolveAgentGUIConversationDisplayTitle,
20
21
  resolveAgentGUIConversationTitle,
22
+ resolveAgentGUIConversationTitleDisplayPrompt,
23
+ resolveAgentGUIConversationTitleLeadingMentionKind,
21
24
  resolveAgentGUIExplicitConversationTitle,
25
+ resolveAgentGUIFirstUserMessageDisplayPrompt,
22
26
  resolveAgentGUIProviderDisplayLabel,
23
27
  resolveAgentGUIProviderIdentity
24
- } from "./chunk-5Z4ZXXX4.js";
28
+ } from "./chunk-V5ROOS2O.js";
25
29
  import {
26
30
  resolveAgentGuiWorkbenchProviderLabel
27
31
  } from "./chunk-L3GMMGRS.js";
@@ -30,49 +34,50 @@ import {
30
34
  Button,
31
35
  MAX_AGENT_COMPOSER_DRAFT_IMAGES,
32
36
  agentComposerDraftAttachmentProjection,
33
- agentComposerDraftDisplayPrompt,
34
37
  agentComposerDraftFiles,
35
38
  agentComposerDraftHasContent,
36
39
  agentComposerDraftImages,
37
40
  agentComposerDraftLargeTexts,
38
41
  agentComposerDraftPrompt,
39
- agentComposerDraftToPromptContent,
40
42
  agentPromptContentDisplayText,
41
43
  agentPromptContentHasImage,
42
44
  agentPromptContentImageBlocks,
43
45
  agentPromptContentToComposerDraft,
44
- agentRichTextContentToPromptText,
45
- attachSubAgentLanesToConversationVM,
46
46
  buildAgentComposerDraft,
47
- buildSubAgentLanesByCallId,
48
47
  buildWorkspaceAgentSessionDetailViewModel,
49
- createAgentRichTextInputExtensions,
50
- editorToPromptText,
51
48
  emptyAgentComposerDraft,
52
49
  getAppErrorCode,
53
- labelForProviderSkill,
50
+ isWorkspaceAgentToolCallItem,
54
51
  materializePastedTextInstructions,
55
52
  normalizeAgentPromptContentBlocks,
56
- partitionSubAgentTimelineItems,
57
53
  pastedTextPreview,
58
- plainTextToAgentRichTextDoc,
59
- plainTextToAgentRichTextInlineContent,
54
+ projectAgentComposerDraftSubmission,
60
55
  projectAgentConversationVM,
61
- skillDescriptionForDisplay,
62
- skillTriggerForPrefix,
56
+ resolveWorkspaceAgentNoticeCommandSemantics,
57
+ resolveWorkspaceAgentToolName,
63
58
  snapshotAgentComposerDraft,
64
59
  textPromptContent,
65
60
  toLocalShortDateTime,
66
61
  updateAgentComposerDraft,
67
62
  useProjectedAgentConversation
68
- } from "./chunk-IVY4OL7B.js";
63
+ } from "./chunk-IR2CL2X2.js";
64
+ import {
65
+ agentRichTextContentToPromptText,
66
+ createAgentRichTextInputExtensions,
67
+ editorToPromptText,
68
+ labelForProviderSkill,
69
+ plainTextToAgentRichTextDoc,
70
+ plainTextToAgentRichTextInlineContent,
71
+ skillDescriptionForDisplay,
72
+ skillTriggerForPrefix
73
+ } from "./chunk-UFIEUC3Y.js";
69
74
  import {
70
75
  openAgentEnvPanel
71
76
  } from "./chunk-7BXWPI4F.js";
72
77
  import {
73
78
  AgentFileMentionPalette,
74
79
  agentMentionItemKey
75
- } from "./chunk-XZD5KTM4.js";
80
+ } from "./chunk-6R7GHXRQ.js";
76
81
  import {
77
82
  normalizeAgentGUIAgents,
78
83
  projectAgentGUIAgentsToInternalTargets
@@ -83,17 +88,18 @@ import {
83
88
  DEFAULT_AGENT_MENTION_FILTER,
84
89
  agentGuiScheduler,
85
90
  buildWorkspaceAgentActivityListViewModel
86
- } from "./chunk-WXMBD2O7.js";
91
+ } from "./chunk-JG7HGKZL.js";
87
92
  import {
88
93
  AGENT_RICH_TEXT_CARET_ANCHOR,
89
94
  createAgentSessionMarkdownLink,
90
95
  createAgentSessionMentionHref,
91
96
  exitAgentFileMentionSuggestion,
92
97
  formatAgentMentionMarkdown,
98
+ materializeAgentCustomMentionPromptText,
93
99
  mentionItemToAttrs,
94
100
  normalizeAgentSessionMentionTitle,
95
101
  parseMentionItemFromHref
96
- } from "./chunk-PCXBTG5X.js";
102
+ } from "./chunk-J2HG7UCP.js";
97
103
  import {
98
104
  AgentInteractivePromptSurface,
99
105
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
@@ -103,34 +109,38 @@ import {
103
109
  dispatchAgentPlanPromptAction,
104
110
  latestPlanTurnId,
105
111
  planImplementationPromptFromPlanTurn
106
- } from "./chunk-SGGGE2F3.js";
112
+ } from "./chunk-4ZWV57MF.js";
107
113
  import {
108
114
  useEngineSelector
109
115
  } from "./chunk-2RQM7PJN.js";
110
116
  import {
111
117
  AgentMessageMarkdown,
112
- AgentTargetPresentationProvider,
113
118
  ZoomableImage,
119
+ resolveWorkspaceLinkAction
120
+ } from "./chunk-7MPN2JGL.js";
121
+ import {
122
+ AgentTargetPresentationProvider,
114
123
  cn,
115
124
  resolveAgentTargetPresentation,
116
- resolveWorkspaceLinkAction,
117
125
  useAgentTargetPresentations
118
- } from "./chunk-UHOVZI6B.js";
126
+ } from "./chunk-KPMQGPYU.js";
119
127
  import {
120
128
  resolveWorkspaceAgentSessionSortTimeUnixMs
121
129
  } from "./chunk-YMXYBG7U.js";
122
130
  import {
123
131
  AgentActivityHostProvider,
124
- MANAGED_AGENT_ICON_FALLBACK_URL,
125
- MANAGED_AGENT_ICON_URLS,
126
- MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS,
127
132
  getOptionalAgentHostApi,
128
133
  useAgentActivityRuntime,
129
134
  useAgentActivitySnapshot,
130
135
  useAgentHostApi,
131
136
  useOptionalAgentActivityRuntime,
132
137
  useOptionalAgentHostApi
133
- } from "./chunk-6PMLIVTI.js";
138
+ } from "./chunk-LDZ6C3YV.js";
139
+ import {
140
+ MANAGED_AGENT_ICON_FALLBACK_URL,
141
+ MANAGED_AGENT_ICON_URLS,
142
+ MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS
143
+ } from "./chunk-SN6UYX54.js";
134
144
  import {
135
145
  normalizeManagedAgentProvider
136
146
  } from "./chunk-H6IQ63DQ.js";
@@ -138,7 +148,7 @@ import {
138
148
  AgentGuiI18nProvider,
139
149
  translate,
140
150
  useTranslation
141
- } from "./chunk-IBFGOAY3.js";
151
+ } from "./chunk-OWW7CU4U.js";
142
152
  import {
143
153
  migratedAgentGUIProviderIdentityCatalog,
144
154
  resolveAgentGUIProviderCatalogIdentity,
@@ -151,7 +161,7 @@ import {
151
161
 
152
162
  // AgentGUI.tsx
153
163
  import { memo as memo15 } from "react";
154
- import { TooltipProvider as TooltipProvider6 } from "@tutti-os/ui-system";
164
+ import { TooltipProvider as TooltipProvider5 } from "@tutti-os/ui-system";
155
165
 
156
166
  // agent-gui/agentGuiNode/AgentGUINode.tsx
157
167
  import { memo as memo14, useCallback as useCallback50, useEffect as useEffect39, useMemo as useMemo39 } from "react";
@@ -2005,8 +2015,11 @@ var trafficLightIconPathByName = {
2005
2015
  };
2006
2016
 
2007
2017
  // agent-gui/agentGuiNode/controller/useAgentGUINodeController.ts
2008
- import { selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions2 } from "@tutti-os/agent-activity-core";
2009
- import { useCallback as useCallback24, useEffect as useEffect14, useMemo as useMemo18, useRef as useRef16 } from "react";
2018
+ import {
2019
+ selectEngineSessionIsRespondingToInteraction as selectEngineSessionIsRespondingToInteraction2,
2020
+ selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions2
2021
+ } from "@tutti-os/agent-activity-core";
2022
+ import { useCallback as useCallback24, useEffect as useEffect14, useMemo as useMemo18, useRef as useRef17 } from "react";
2010
2023
 
2011
2024
  // host/agentHostAccountStore.ts
2012
2025
  import { create as create2 } from "zustand";
@@ -2134,6 +2147,657 @@ function mergeProfilesIntoSnapshot(snapshot, users) {
2134
2147
  };
2135
2148
  }
2136
2149
 
2150
+ // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
2151
+ function projectWorkspaceAgentMessagesToTimelineItems(messages) {
2152
+ const sortedMessages = latestMessageSnapshots(messages).sort(
2153
+ compareMessagesByDisplayOrder
2154
+ );
2155
+ const mergedToolPayloadByKey = /* @__PURE__ */ new Map();
2156
+ return sortedMessages.map((message, index) => {
2157
+ const kind = normalizeToken(message.kind);
2158
+ const role = normalizeToken(message.role);
2159
+ const payload = normalizedPayload(message.payload);
2160
+ const id = normalizedMessageId(message.version, index);
2161
+ const seq = index + 1;
2162
+ const eventId = message.messageId.trim() || `message:${id}`;
2163
+ const turnId = message.turnId?.trim() || void 0;
2164
+ const occurredAtUnixMs = messageDisplayOrderTime(message);
2165
+ if (kind === "tool_call") {
2166
+ const callId = firstNonEmptyString(
2167
+ messagePayloadString(message, "callId"),
2168
+ message.messageId
2169
+ );
2170
+ const title = messagePayloadString(message, "title");
2171
+ const toolKey = callId || eventId;
2172
+ const payloadToolName = displayToolNameCandidate(
2173
+ stringValue(payload.toolName),
2174
+ callId
2175
+ );
2176
+ const titleToolName = displayToolNameCandidate(title, callId);
2177
+ const toolName = firstNonEmptyString(payloadToolName, titleToolName);
2178
+ const toolPayload = sanitizedToolPayload(payload, callId);
2179
+ const mergedPayload = mergePayload(mergedToolPayloadByKey.get(toolKey), {
2180
+ ...toolPayload,
2181
+ ...toolName ? { toolName } : {},
2182
+ ...message.status?.trim() ? { status: message.status.trim() } : {}
2183
+ });
2184
+ mergedToolPayloadByKey.set(toolKey, mergedPayload);
2185
+ const callType = firstNonEmptyString(stringValue(mergedPayload.callType)) || "tool";
2186
+ const workspaceId = workspaceIdFromMessage(message);
2187
+ return {
2188
+ id,
2189
+ ...workspaceTimelineFields(workspaceId),
2190
+ agentSessionId: message.agentSessionId,
2191
+ seq,
2192
+ ...turnId ? { turnId } : {},
2193
+ eventId,
2194
+ actorType: "agent",
2195
+ actorId: message.agentSessionId,
2196
+ itemType: toolCallItemType(message.status ?? void 0),
2197
+ role: "assistant",
2198
+ callType,
2199
+ callId,
2200
+ name: firstNonEmptyString(toolName, titleToolName) || "Tool",
2201
+ ...message.status !== void 0 ? { status: message.status } : {},
2202
+ payload: mergedPayload,
2203
+ ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
2204
+ ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
2205
+ };
2206
+ }
2207
+ if (kind === "reasoning") {
2208
+ return messageTimelineItem({
2209
+ message,
2210
+ id,
2211
+ seq,
2212
+ eventId,
2213
+ turnId,
2214
+ actorType: "agent",
2215
+ itemType: "message.assistant_thinking",
2216
+ role: "assistant_thinking",
2217
+ content: messageText(message),
2218
+ occurredAtUnixMs
2219
+ });
2220
+ }
2221
+ if (kind === "text" && role === "user") {
2222
+ return messageTimelineItem({
2223
+ message,
2224
+ id,
2225
+ seq,
2226
+ eventId,
2227
+ turnId,
2228
+ actorType: "user",
2229
+ itemType: "message.user",
2230
+ role: "user",
2231
+ content: messageText(message),
2232
+ occurredAtUnixMs
2233
+ });
2234
+ }
2235
+ if (kind === "text" && (role === "assistant" || role === "agent")) {
2236
+ const projectedMessage = normalizeLegacyCompactNotice(message, payload);
2237
+ return messageTimelineItem({
2238
+ message: projectedMessage,
2239
+ id,
2240
+ seq,
2241
+ eventId,
2242
+ turnId,
2243
+ actorType: "agent",
2244
+ itemType: "message.assistant",
2245
+ role: "assistant",
2246
+ content: messageText(projectedMessage),
2247
+ occurredAtUnixMs
2248
+ });
2249
+ }
2250
+ const statusTurnId = turnId ?? `session-status:${kind === "error" ? "error" : "notice"}`;
2251
+ const statusMessage = {
2252
+ ...message,
2253
+ payload: kind === "error" ? {
2254
+ ...payload,
2255
+ detail: messageText(message),
2256
+ kind: "agent_visible_error"
2257
+ } : {
2258
+ ...payload,
2259
+ detail: messageText(message),
2260
+ kind: "agent_system_notice",
2261
+ noticeKind: kind,
2262
+ severity: "info"
2263
+ }
2264
+ };
2265
+ return messageTimelineItem({
2266
+ message: statusMessage,
2267
+ id,
2268
+ seq,
2269
+ eventId,
2270
+ turnId: statusTurnId,
2271
+ actorType: role === "user" ? "user" : "agent",
2272
+ itemType: role === "user" ? "message.user" : "message.assistant",
2273
+ role: role === "user" ? "user" : "assistant",
2274
+ content: statusMessageText(statusMessage),
2275
+ occurredAtUnixMs
2276
+ });
2277
+ });
2278
+ }
2279
+ function normalizeLegacyCompactNotice(message, payload) {
2280
+ const commandSemantics = resolveWorkspaceAgentNoticeCommandSemantics({
2281
+ eventId: message.messageId,
2282
+ messageSemantics: message.semantics,
2283
+ payload,
2284
+ status: message.status
2285
+ });
2286
+ if (commandSemantics?.command !== "compact") {
2287
+ return message;
2288
+ }
2289
+ const commandStatus = commandSemantics.commandStatus;
2290
+ const title = stringValue(payload.title) || (commandStatus === "completed" ? "Context compacted." : commandStatus === "running" ? "Compacting context." : "Context compaction interrupted.");
2291
+ const originalText = messageText(message);
2292
+ const detail = stringValue(payload.detail) || (commandStatus === "failed" || commandStatus === "canceled" ? originalText.replace(/^Compacting failed:\s*/iu, "").trim() : "");
2293
+ return {
2294
+ ...message,
2295
+ semantics: {
2296
+ ...message.semantics,
2297
+ noticeCommand: "compact",
2298
+ noticeCommandStatus: commandStatus
2299
+ },
2300
+ payload: {
2301
+ ...payload,
2302
+ kind: "agent_system_notice",
2303
+ noticeKind: stringValue(payload.noticeKind) || "system_notice",
2304
+ noticeCommand: "compact",
2305
+ noticeCommandStatus: commandStatus,
2306
+ title,
2307
+ text: title,
2308
+ content: title,
2309
+ ...detail ? { detail } : {}
2310
+ }
2311
+ };
2312
+ }
2313
+ function latestMessageSnapshots(messages) {
2314
+ const latestByKey = /* @__PURE__ */ new Map();
2315
+ const unkeyedMessages = [];
2316
+ for (const message of messages) {
2317
+ const key = messageSnapshotKey(message);
2318
+ if (!key) {
2319
+ unkeyedMessages.push(message);
2320
+ continue;
2321
+ }
2322
+ const previous = latestByKey.get(key);
2323
+ if (!previous || (message.version ?? 0) >= (previous.version ?? 0)) {
2324
+ latestByKey.set(key, mergeMessageSnapshot(previous, message));
2325
+ } else {
2326
+ latestByKey.set(key, mergeMessageSnapshot(message, previous));
2327
+ }
2328
+ }
2329
+ return [...unkeyedMessages, ...latestByKey.values()];
2330
+ }
2331
+ function mergeMessageSnapshot(previous, next) {
2332
+ const semantics = previous?.semantics || next.semantics ? { ...previous?.semantics, ...next.semantics } : void 0;
2333
+ return {
2334
+ ...previous,
2335
+ ...next,
2336
+ ...semantics ? { semantics } : {},
2337
+ payload: {
2338
+ ...previous?.payload ?? {},
2339
+ ...next.payload ?? {}
2340
+ }
2341
+ };
2342
+ }
2343
+ function messageSnapshotKey(message) {
2344
+ const messageId = message.messageId.trim();
2345
+ if (!messageId) {
2346
+ return null;
2347
+ }
2348
+ return `${message.agentSessionId.trim()}\0${messageId}`;
2349
+ }
2350
+ function messageTimelineItem({
2351
+ message,
2352
+ id,
2353
+ seq,
2354
+ eventId,
2355
+ turnId,
2356
+ actorType,
2357
+ itemType,
2358
+ role,
2359
+ content,
2360
+ occurredAtUnixMs
2361
+ }) {
2362
+ const workspaceId = workspaceIdFromMessage(message);
2363
+ return {
2364
+ id,
2365
+ ...workspaceTimelineFields(workspaceId),
2366
+ agentSessionId: message.agentSessionId,
2367
+ seq,
2368
+ ...turnId ? { turnId } : {},
2369
+ eventId,
2370
+ actorType,
2371
+ actorId: actorType === "user" ? "user" : message.agentSessionId,
2372
+ itemType,
2373
+ role,
2374
+ status: message.status,
2375
+ ...message.semantics ? { messageSemantics: message.semantics } : {},
2376
+ content,
2377
+ payload: normalizedPayload(message.payload),
2378
+ ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
2379
+ ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
2380
+ };
2381
+ }
2382
+ function workspaceIdFromMessage(message) {
2383
+ return message.workspaceId?.trim() || "";
2384
+ }
2385
+ function workspaceTimelineFields(workspaceId) {
2386
+ return {
2387
+ workspaceId
2388
+ };
2389
+ }
2390
+ function compareMessagesByDisplayOrder(left, right) {
2391
+ const leftTime = messageDisplayOrderTime(left);
2392
+ const rightTime = messageDisplayOrderTime(right);
2393
+ if (leftTime > 0 && rightTime > 0 && leftTime !== rightTime) {
2394
+ return leftTime - rightTime;
2395
+ }
2396
+ const leftVersion = normalizedPositiveNumber(left.version);
2397
+ const rightVersion = normalizedPositiveNumber(right.version);
2398
+ if (leftVersion > 0 && rightVersion > 0 && leftVersion !== rightVersion) {
2399
+ return leftVersion - rightVersion;
2400
+ }
2401
+ return 0;
2402
+ }
2403
+ function normalizedMessageId(id, index) {
2404
+ const normalizedId = typeof id === "number" ? id : 0;
2405
+ return Number.isFinite(normalizedId) && normalizedId > 0 ? normalizedId : index + 1;
2406
+ }
2407
+ function normalizedPositiveNumber(value) {
2408
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
2409
+ }
2410
+ function messageDisplayOrderTime(message) {
2411
+ return normalizedPositiveNumber(message.startedAtUnixMs) || normalizedPositiveNumber(message.occurredAtUnixMs) || normalizedPositiveNumber(message.completedAtUnixMs);
2412
+ }
2413
+ function toolCallItemType(status) {
2414
+ switch (normalizeToken(status)) {
2415
+ case "running":
2416
+ case "working":
2417
+ case "active":
2418
+ return "call.started";
2419
+ case "completed":
2420
+ case "complete":
2421
+ case "done":
2422
+ case "success":
2423
+ case "succeeded":
2424
+ return "call.completed";
2425
+ case "failed":
2426
+ case "error":
2427
+ return "call.failed";
2428
+ case "canceled":
2429
+ return "call.canceled";
2430
+ default:
2431
+ return "call";
2432
+ }
2433
+ }
2434
+ function messageText(message) {
2435
+ const payload = normalizedPayload(message.payload);
2436
+ const title = messagePayloadString(message, "title");
2437
+ return firstNonEmptyString(
2438
+ stringValue(payload.displayPrompt),
2439
+ stringValue(payload.text),
2440
+ stringValue(payload.content),
2441
+ stringValue(payload.message),
2442
+ stringValue(payload.body),
2443
+ title
2444
+ );
2445
+ }
2446
+ function statusMessageText(message) {
2447
+ const title = messagePayloadString(message, "title") ?? "";
2448
+ const text = messageText(message);
2449
+ if (title && text && title !== text) {
2450
+ return `${title}
2451
+
2452
+ ${text}`;
2453
+ }
2454
+ return title || text;
2455
+ }
2456
+ function messagePayloadString(message, key) {
2457
+ return stringValue(normalizedPayload(message.payload)[key]);
2458
+ }
2459
+ function mergePayload(previous, next) {
2460
+ if (!previous) {
2461
+ return next;
2462
+ }
2463
+ const merged = { ...previous, ...next };
2464
+ for (const key of [
2465
+ "input",
2466
+ "output",
2467
+ "error",
2468
+ "metadata",
2469
+ "toolState",
2470
+ "tool_state"
2471
+ ]) {
2472
+ if (isRecord(previous[key]) || isRecord(next[key])) {
2473
+ merged[key] = {
2474
+ ...isRecord(previous[key]) ? previous[key] : {},
2475
+ ...isRecord(next[key]) ? next[key] : {}
2476
+ };
2477
+ }
2478
+ }
2479
+ return merged;
2480
+ }
2481
+ function normalizedPayload(payload) {
2482
+ return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2483
+ }
2484
+ function sanitizedToolPayload(payload, callId) {
2485
+ if (!isOpaqueCallIdentifierString(stringValue(payload.toolName), callId)) {
2486
+ return payload;
2487
+ }
2488
+ const { toolName: _toolName, ...rest } = payload;
2489
+ return rest;
2490
+ }
2491
+ function isRecord(value) {
2492
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2493
+ }
2494
+ function stringValue(value) {
2495
+ return typeof value === "string" && value.trim() ? value.trim() : "";
2496
+ }
2497
+ function firstNonEmptyString(...values) {
2498
+ for (const value of values) {
2499
+ if (typeof value === "string" && value.trim()) {
2500
+ return value.trim();
2501
+ }
2502
+ }
2503
+ return "";
2504
+ }
2505
+ function displayToolNameCandidate(value, callId) {
2506
+ const trimmed = value?.trim() ?? "";
2507
+ if (!trimmed || isOpaqueCallIdentifierString(trimmed, callId)) {
2508
+ return "";
2509
+ }
2510
+ return trimmed;
2511
+ }
2512
+ function isOpaqueCallIdentifierString(value, callId) {
2513
+ const trimmed = value.trim();
2514
+ if (!trimmed) {
2515
+ return false;
2516
+ }
2517
+ if (callId?.trim() && trimmed === callId.trim()) {
2518
+ return true;
2519
+ }
2520
+ const lower = trimmed.toLowerCase();
2521
+ if (lower.startsWith("call_")) {
2522
+ return isOpaqueIdentifierTail(trimmed.slice("call_".length));
2523
+ }
2524
+ if (lower.startsWith("ws_")) {
2525
+ return isOpaqueIdentifierTail(trimmed.slice("ws_".length));
2526
+ }
2527
+ return false;
2528
+ }
2529
+ function isOpaqueIdentifierTail(value) {
2530
+ return value.length >= 12 && /^[a-z0-9]+$/i.test(value);
2531
+ }
2532
+ function normalizeToken(value) {
2533
+ return value?.trim().toLowerCase() ?? "";
2534
+ }
2535
+
2536
+ // shared/agentConversation/projection/childSessionLanes.ts
2537
+ function buildChildSessionLanesByParentToolCallId(input) {
2538
+ const rootSessionId = input.rootSession.agentSessionId.trim();
2539
+ const childrenByParentSessionId = /* @__PURE__ */ new Map();
2540
+ for (const childSession of input.childSessions) {
2541
+ if (childSession.kind !== "child" || childSession.rootAgentSessionId !== rootSessionId || !childSession.parentAgentSessionId?.trim() || !childSession.parentToolCallId?.trim()) {
2542
+ continue;
2543
+ }
2544
+ const parentSessionId = childSession.parentAgentSessionId.trim();
2545
+ const siblings = childrenByParentSessionId.get(parentSessionId) ?? [];
2546
+ siblings.push(childSession);
2547
+ childrenByParentSessionId.set(parentSessionId, siblings);
2548
+ }
2549
+ for (const siblings of childrenByParentSessionId.values()) {
2550
+ siblings.sort(compareChildSessions);
2551
+ }
2552
+ const lanesByParentToolCallId = /* @__PURE__ */ new Map();
2553
+ const directChildren = childrenByParentSessionId.get(rootSessionId) ?? [];
2554
+ const visited = /* @__PURE__ */ new Set();
2555
+ for (const childSession of directChildren) {
2556
+ const parentToolCallId = childSession.parentToolCallId?.trim();
2557
+ if (!parentToolCallId) continue;
2558
+ const lanes = lanesByParentToolCallId.get(parentToolCallId) ?? [];
2559
+ lanes.push(
2560
+ buildChildSessionLane({
2561
+ childSession,
2562
+ childrenByParentSessionId,
2563
+ messagesBySessionId: input.messagesBySessionId,
2564
+ parentTimelineItems: input.rootTimelineItems,
2565
+ visited
2566
+ })
2567
+ );
2568
+ lanesByParentToolCallId.set(parentToolCallId, lanes);
2569
+ }
2570
+ for (const lanes of lanesByParentToolCallId.values()) {
2571
+ assignLanePositions(lanes);
2572
+ }
2573
+ return lanesByParentToolCallId;
2574
+ }
2575
+ function attachChildSessionLanesToConversationVM(conversation, lanesByParentToolCallId) {
2576
+ if (!conversation || lanesByParentToolCallId.size === 0) {
2577
+ return conversation;
2578
+ }
2579
+ let changed = false;
2580
+ const rows = conversation.rows.map((row) => {
2581
+ if (row.kind !== "tool-group") return row;
2582
+ const nextRow = toolGroupRowWithChildSessions(row, lanesByParentToolCallId);
2583
+ if (nextRow !== row) changed = true;
2584
+ return nextRow;
2585
+ });
2586
+ return changed ? { ...conversation, rows } : conversation;
2587
+ }
2588
+ function deriveSubAgentNameFromTask(task) {
2589
+ if (!task) return null;
2590
+ const firstSentence = task.trim().split(/[。..!?!?,,\n]/, 1)[0]?.trim();
2591
+ if (!firstSentence) return null;
2592
+ const selfAddress = /^(你现在是|你現在是|你是|you are|act as)\s*/i;
2593
+ if (!selfAddress.test(firstSentence)) return null;
2594
+ const stripped = firstSentence.replace(selfAddress, "").replace(/\s+/g, " ").trim();
2595
+ return stripped.length >= 2 && stripped.length <= 36 ? stripped : null;
2596
+ }
2597
+ function buildChildSessionLane(input) {
2598
+ const childSessionId = input.childSession.agentSessionId.trim();
2599
+ if (input.visited.has(childSessionId)) {
2600
+ return emptyCycleLane(input.childSession);
2601
+ }
2602
+ input.visited.add(childSessionId);
2603
+ const childMessages = input.messagesBySessionId[childSessionId] ?? [];
2604
+ const childTimelineItems = projectWorkspaceAgentMessagesToTimelineItems(childMessages);
2605
+ const parentToolCallId = input.childSession.parentToolCallId?.trim() ?? "";
2606
+ const parentCall = parentToolCall(
2607
+ input.parentTimelineItems,
2608
+ parentToolCallId
2609
+ );
2610
+ const task = parentCall?.task ?? null;
2611
+ const childSessions = (input.childrenByParentSessionId.get(childSessionId) ?? []).map(
2612
+ (nestedChild) => buildChildSessionLane({
2613
+ childSession: nestedChild,
2614
+ childrenByParentSessionId: input.childrenByParentSessionId,
2615
+ messagesBySessionId: input.messagesBySessionId,
2616
+ parentTimelineItems: childTimelineItems,
2617
+ visited: input.visited
2618
+ })
2619
+ );
2620
+ assignSiblingLanePositions(childSessions);
2621
+ input.visited.delete(childSessionId);
2622
+ const activity = childSessionActivityLog(childTimelineItems);
2623
+ const latestActivity = activity.entries.at(-1) ?? null;
2624
+ const latestMessageAtUnixMs = childMessages.reduce(
2625
+ (latest, message) => Math.max(latest, message.occurredAtUnixMs),
2626
+ 0
2627
+ );
2628
+ const latestTurn = input.childSession.latestTurn;
2629
+ const status = childSessionStatus(input.childSession);
2630
+ const terminalAtUnixMs = status === "running" ? null : latestTurn?.settledAtUnixMs ?? input.childSession.endedAtUnixMs;
2631
+ return {
2632
+ childSessionId,
2633
+ parentToolCallId,
2634
+ status,
2635
+ name: normalizedString(input.childSession.title) ?? deriveSubAgentNameFromTask(task),
2636
+ task,
2637
+ laneIndex: 1,
2638
+ laneCount: 1,
2639
+ latestActivity: latestActivity?.text ?? null,
2640
+ latestActivityKind: latestActivity?.kind ?? null,
2641
+ activityLog: activity.entries,
2642
+ activityOmittedCount: activity.omittedCount,
2643
+ queued: input.childSession.activeTurn?.phase === "submitted",
2644
+ failureDetail: status === "failed" ? latestTurn?.error?.message?.trim() ?? null : null,
2645
+ startedAtUnixMs: input.childSession.activeTurn?.startedAtUnixMs ?? latestTurn?.startedAtUnixMs ?? input.childSession.createdAtUnixMs,
2646
+ latestActivityAtUnixMs: Math.max(
2647
+ latestMessageAtUnixMs,
2648
+ latestTurn?.updatedAtUnixMs ?? 0,
2649
+ input.childSession.updatedAtUnixMs
2650
+ ),
2651
+ terminalAtUnixMs,
2652
+ childSessions
2653
+ };
2654
+ }
2655
+ function emptyCycleLane(session) {
2656
+ return {
2657
+ childSessionId: session.agentSessionId,
2658
+ parentToolCallId: session.parentToolCallId ?? "",
2659
+ status: childSessionStatus(session),
2660
+ name: normalizedString(session.title),
2661
+ task: null,
2662
+ laneIndex: 1,
2663
+ laneCount: 1,
2664
+ latestActivity: null,
2665
+ latestActivityKind: null,
2666
+ activityLog: [],
2667
+ activityOmittedCount: 0,
2668
+ failureDetail: session.latestTurn?.error?.message?.trim() ?? null,
2669
+ startedAtUnixMs: session.createdAtUnixMs,
2670
+ latestActivityAtUnixMs: session.updatedAtUnixMs,
2671
+ terminalAtUnixMs: session.latestTurn?.settledAtUnixMs ?? session.endedAtUnixMs,
2672
+ childSessions: []
2673
+ };
2674
+ }
2675
+ function childSessionStatus(session) {
2676
+ const activeTurn = session.activeTurn;
2677
+ if (activeTurn && activeTurn.phase !== "settled") return "running";
2678
+ const latestTurn = session.latestTurn;
2679
+ if (!latestTurn || latestTurn.phase !== "settled") return "running";
2680
+ switch (latestTurn.outcome) {
2681
+ case "failed":
2682
+ return "failed";
2683
+ case "canceled":
2684
+ case "interrupted":
2685
+ return "canceled";
2686
+ case "completed":
2687
+ default:
2688
+ return "completed";
2689
+ }
2690
+ }
2691
+ function parentToolCall(timelineItems, parentToolCallId) {
2692
+ if (!parentToolCallId) return null;
2693
+ for (const item of timelineItems) {
2694
+ if (!isWorkspaceAgentToolCallItem(item)) continue;
2695
+ const callId = firstString(item.callId, stringValue2(item.payload?.callId));
2696
+ if (callId !== parentToolCallId) continue;
2697
+ const input = recordValue(item.payload?.input);
2698
+ return {
2699
+ task: firstString(
2700
+ stringValue2(input?.task),
2701
+ stringValue2(input?.prompt),
2702
+ stringValue2(input?.description)
2703
+ )
2704
+ };
2705
+ }
2706
+ return null;
2707
+ }
2708
+ function toolGroupRowWithChildSessions(row, lanesByParentToolCallId) {
2709
+ let changed = false;
2710
+ const callsById = /* @__PURE__ */ new Map();
2711
+ const calls = row.calls.map((call) => {
2712
+ const lanes = call.task ? lanesByParentToolCallId.get(toolCallRawId(call.id)) : null;
2713
+ if (!lanes?.length || !call.task) return call;
2714
+ changed = true;
2715
+ const nextCall = {
2716
+ ...call,
2717
+ task: { ...call.task, subAgents: lanes }
2718
+ };
2719
+ callsById.set(nextCall.id, nextCall);
2720
+ return nextCall;
2721
+ });
2722
+ if (!changed) return row;
2723
+ const entries = row.entries.map((entry) => {
2724
+ if (entry.kind !== "tool-call") return entry;
2725
+ const nextCall = callsById.get(entry.call.id);
2726
+ return nextCall ? { ...entry, call: nextCall } : entry;
2727
+ });
2728
+ return { ...row, calls, entries };
2729
+ }
2730
+ function toolCallRawId(id) {
2731
+ return id.startsWith("call:") ? id.slice("call:".length) : id;
2732
+ }
2733
+ var CHILD_ACTIVITY_LOG_CAP = 20;
2734
+ function childSessionActivityLog(timelineItems) {
2735
+ const entries = timelineItems.map(displayableActivityEntry).filter((entry) => entry !== null);
2736
+ const omittedCount = Math.max(0, entries.length - CHILD_ACTIVITY_LOG_CAP);
2737
+ return { entries: entries.slice(omittedCount), omittedCount };
2738
+ }
2739
+ function displayableActivityEntry(item) {
2740
+ const atUnixMs = timelineItemTime(item) || null;
2741
+ if (isWorkspaceAgentToolCallItem(item)) {
2742
+ const name = firstString(
2743
+ resolveWorkspaceAgentToolName(item),
2744
+ item.name,
2745
+ stringValue2(item.payload?.name)
2746
+ );
2747
+ return name ? { kind: "tool", text: name, atUnixMs } : null;
2748
+ }
2749
+ const text = snippet(timelineItemText(item));
2750
+ if (!text) return null;
2751
+ const itemType = item.itemType?.trim().toLowerCase() ?? "";
2752
+ const role = item.role?.trim().toLowerCase() ?? "";
2753
+ return itemType === "message.assistant_thinking" || role === "assistant_thinking" ? { kind: "reasoning", text, atUnixMs } : { kind: "message", text, atUnixMs };
2754
+ }
2755
+ function timelineItemText(item) {
2756
+ return (stringValue2(item.payload?.text) ?? stringValue2(item.payload?.content) ?? stringValue2(item.content) ?? "").replace(/\s+/g, " ").trim();
2757
+ }
2758
+ function snippet(text) {
2759
+ return text.length <= 140 ? text : String.fromCodePoint(8230) + text.slice(-140);
2760
+ }
2761
+ function assignSiblingLanePositions(lanes) {
2762
+ const lanesByCallId = /* @__PURE__ */ new Map();
2763
+ for (const lane of lanes) {
2764
+ const siblings = lanesByCallId.get(lane.parentToolCallId) ?? [];
2765
+ siblings.push(lane);
2766
+ lanesByCallId.set(lane.parentToolCallId, siblings);
2767
+ }
2768
+ for (const siblings of lanesByCallId.values()) assignLanePositions(siblings);
2769
+ }
2770
+ function assignLanePositions(lanes) {
2771
+ for (let index = 0; index < lanes.length; index += 1) {
2772
+ const lane = lanes[index];
2773
+ if (!lane) continue;
2774
+ lane.laneIndex = index + 1;
2775
+ lane.laneCount = lanes.length;
2776
+ }
2777
+ }
2778
+ function compareChildSessions(left, right) {
2779
+ return left.createdAtUnixMs - right.createdAtUnixMs || left.agentSessionId.localeCompare(right.agentSessionId);
2780
+ }
2781
+ function timelineItemTime(item) {
2782
+ return item?.occurredAtUnixMs ?? item?.createdAtUnixMs ?? 0;
2783
+ }
2784
+ function normalizedString(value) {
2785
+ return typeof value === "string" && value.trim() ? value.trim() : null;
2786
+ }
2787
+ function stringValue2(value) {
2788
+ return typeof value === "string" && value.trim() ? value.trim() : null;
2789
+ }
2790
+ function recordValue(value) {
2791
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
2792
+ }
2793
+ function firstString(...values) {
2794
+ for (const value of values) {
2795
+ const normalized = normalizedString(value);
2796
+ if (normalized) return normalized;
2797
+ }
2798
+ return null;
2799
+ }
2800
+
2137
2801
  // agent-gui/agentGuiNode/model/agentGuiConversationFilter.ts
2138
2802
  function createAgentGUIConversationFilterState(filter = { kind: "all" }) {
2139
2803
  return {
@@ -2180,7 +2844,7 @@ function matchesAgentGUIConversationFilterAgentTarget(agentTargetId, provider, f
2180
2844
  }
2181
2845
 
2182
2846
  // agent-gui/agentGuiNode/model/agentGuiConversationModel.ts
2183
- import { selectCanonicalAgentActivitySessions } from "@tutti-os/agent-activity-core";
2847
+ import { selectRootAgentActivitySessions } from "@tutti-os/agent-activity-core";
2184
2848
 
2185
2849
  // agent-gui/agentGuiNode/model/agentGuiConversationProjectResolver.ts
2186
2850
  import { resolveWorkspaceUserProjectDisplayLabel } from "@tutti-os/workspace-user-project/core";
@@ -2588,6 +3252,8 @@ function buildAgentGUIConversationDetail({
2588
3252
  function buildAgentGUIConversationModels({
2589
3253
  timelineItems,
2590
3254
  conversation,
3255
+ childSessions = [],
3256
+ childMessagesBySessionId = {},
2591
3257
  workspaceRoot = null,
2592
3258
  avoidGroupingEdits = false
2593
3259
  }) {
@@ -2599,13 +3265,16 @@ function buildAgentGUIConversationModels({
2599
3265
  if (!detail) {
2600
3266
  return { conversation: null, detail: null };
2601
3267
  }
2602
- const subAgentLanesByCallId = buildSubAgentLanesByCallId(
2603
- partitionSubAgentTimelineItems(timelineItems)
2604
- );
3268
+ const childSessionLanesByParentToolCallId = buildChildSessionLanesByParentToolCallId({
3269
+ rootSession: detail.session,
3270
+ rootTimelineItems: timelineItems,
3271
+ childSessions,
3272
+ messagesBySessionId: childMessagesBySessionId
3273
+ });
2605
3274
  return {
2606
- conversation: attachSubAgentLanesToConversationVM(
3275
+ conversation: attachChildSessionLanesToConversationVM(
2607
3276
  projectAgentConversationVM(detail, { avoidGroupingEdits }),
2608
- subAgentLanesByCallId
3277
+ childSessionLanesByParentToolCallId
2609
3278
  ),
2610
3279
  detail
2611
3280
  };
@@ -2633,6 +3302,7 @@ function conversationSummaryFromAgentSession(session, options = {}) {
2633
3302
  session.activeTurnId ? "working" : "idle"
2634
3303
  ),
2635
3304
  cwd: session.cwd?.trim() ?? "",
3305
+ railSectionKey: session.railSectionKey,
2636
3306
  project: resolveConversationProject(session, projectResolver),
2637
3307
  ...isExternalImportNoProjectSession(session) ? { projectMode: "none" } : {},
2638
3308
  pinnedAtUnixMs: session.pinnedAtUnixMs ?? null,
@@ -2916,354 +3586,6 @@ function stringField(record, field) {
2916
3586
  return typeof value === "string" ? value.trim() : "";
2917
3587
  }
2918
3588
 
2919
- // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
2920
- function projectWorkspaceAgentMessagesToTimelineItems(messages) {
2921
- const sortedMessages = latestMessageSnapshots(messages).sort(
2922
- compareMessagesByDisplayOrder
2923
- );
2924
- const mergedToolPayloadByKey = /* @__PURE__ */ new Map();
2925
- return sortedMessages.map((message, index) => {
2926
- const kind = normalizeToken(message.kind);
2927
- const role = normalizeToken(message.role);
2928
- const payload = normalizedPayload(message.payload);
2929
- const id = normalizedMessageId(message.version, index);
2930
- const seq = index + 1;
2931
- const eventId = message.messageId.trim() || `message:${id}`;
2932
- const turnId = message.turnId?.trim() || void 0;
2933
- const occurredAtUnixMs = messageDisplayOrderTime(message);
2934
- if (kind === "tool_call") {
2935
- const callId = firstNonEmptyString(
2936
- messagePayloadString(message, "callId"),
2937
- message.messageId
2938
- );
2939
- const title = messagePayloadString(message, "title");
2940
- const toolKey = callId || eventId;
2941
- const payloadToolName = displayToolNameCandidate(
2942
- stringValue(payload.toolName),
2943
- callId
2944
- );
2945
- const titleToolName = displayToolNameCandidate(title, callId);
2946
- const toolName = firstNonEmptyString(payloadToolName, titleToolName);
2947
- const toolPayload = sanitizedToolPayload(payload, callId);
2948
- const mergedPayload = mergePayload(mergedToolPayloadByKey.get(toolKey), {
2949
- ...toolPayload,
2950
- ...toolName ? { toolName } : {},
2951
- ...message.status?.trim() ? { status: message.status.trim() } : {}
2952
- });
2953
- mergedToolPayloadByKey.set(toolKey, mergedPayload);
2954
- const callType = firstNonEmptyString(stringValue(mergedPayload.callType)) || "tool";
2955
- const workspaceId = workspaceIdFromMessage(message);
2956
- return {
2957
- id,
2958
- ...workspaceTimelineFields(workspaceId),
2959
- agentSessionId: message.agentSessionId,
2960
- seq,
2961
- ...turnId ? { turnId } : {},
2962
- eventId,
2963
- actorType: "agent",
2964
- actorId: message.agentSessionId,
2965
- itemType: toolCallItemType(message.status ?? void 0),
2966
- role: "assistant",
2967
- callType,
2968
- callId,
2969
- name: firstNonEmptyString(toolName, titleToolName) || "Tool",
2970
- ...message.status !== void 0 ? { status: message.status } : {},
2971
- payload: mergedPayload,
2972
- ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
2973
- ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
2974
- };
2975
- }
2976
- if (kind === "reasoning") {
2977
- return messageTimelineItem({
2978
- message,
2979
- id,
2980
- seq,
2981
- eventId,
2982
- turnId,
2983
- actorType: "agent",
2984
- itemType: "message.assistant_thinking",
2985
- role: "assistant_thinking",
2986
- content: messageText(message),
2987
- occurredAtUnixMs
2988
- });
2989
- }
2990
- if (kind === "text" && role === "user") {
2991
- return messageTimelineItem({
2992
- message,
2993
- id,
2994
- seq,
2995
- eventId,
2996
- turnId,
2997
- actorType: "user",
2998
- itemType: "message.user",
2999
- role: "user",
3000
- content: messageText(message),
3001
- occurredAtUnixMs
3002
- });
3003
- }
3004
- if (kind === "text" && (role === "assistant" || role === "agent")) {
3005
- return messageTimelineItem({
3006
- message,
3007
- id,
3008
- seq,
3009
- eventId,
3010
- turnId,
3011
- actorType: "agent",
3012
- itemType: "message.assistant",
3013
- role: "assistant",
3014
- content: messageText(message),
3015
- occurredAtUnixMs
3016
- });
3017
- }
3018
- const statusTurnId = turnId ?? `session-status:${kind === "error" ? "error" : "notice"}`;
3019
- const statusMessage = {
3020
- ...message,
3021
- payload: kind === "error" ? {
3022
- ...payload,
3023
- detail: messageText(message),
3024
- kind: "agent_visible_error"
3025
- } : {
3026
- ...payload,
3027
- detail: messageText(message),
3028
- kind: "agent_system_notice",
3029
- noticeKind: kind,
3030
- severity: "info"
3031
- }
3032
- };
3033
- return messageTimelineItem({
3034
- message: statusMessage,
3035
- id,
3036
- seq,
3037
- eventId,
3038
- turnId: statusTurnId,
3039
- actorType: role === "user" ? "user" : "agent",
3040
- itemType: role === "user" ? "message.user" : "message.assistant",
3041
- role: role === "user" ? "user" : "assistant",
3042
- content: statusMessageText(statusMessage),
3043
- occurredAtUnixMs
3044
- });
3045
- });
3046
- }
3047
- function latestMessageSnapshots(messages) {
3048
- const latestByKey = /* @__PURE__ */ new Map();
3049
- const unkeyedMessages = [];
3050
- for (const message of messages) {
3051
- const key = messageSnapshotKey(message);
3052
- if (!key) {
3053
- unkeyedMessages.push(message);
3054
- continue;
3055
- }
3056
- const previous = latestByKey.get(key);
3057
- if (!previous || (message.version ?? 0) >= (previous.version ?? 0)) {
3058
- latestByKey.set(key, mergeMessageSnapshot(previous, message));
3059
- } else {
3060
- latestByKey.set(key, mergeMessageSnapshot(message, previous));
3061
- }
3062
- }
3063
- return [...unkeyedMessages, ...latestByKey.values()];
3064
- }
3065
- function mergeMessageSnapshot(previous, next) {
3066
- return {
3067
- ...previous,
3068
- ...next,
3069
- payload: {
3070
- ...previous?.payload ?? {},
3071
- ...next.payload ?? {}
3072
- }
3073
- };
3074
- }
3075
- function messageSnapshotKey(message) {
3076
- const messageId = message.messageId.trim();
3077
- if (!messageId) {
3078
- return null;
3079
- }
3080
- return `${message.agentSessionId.trim()}\0${messageId}`;
3081
- }
3082
- function messageTimelineItem({
3083
- message,
3084
- id,
3085
- seq,
3086
- eventId,
3087
- turnId,
3088
- actorType,
3089
- itemType,
3090
- role,
3091
- content,
3092
- occurredAtUnixMs
3093
- }) {
3094
- const workspaceId = workspaceIdFromMessage(message);
3095
- return {
3096
- id,
3097
- ...workspaceTimelineFields(workspaceId),
3098
- agentSessionId: message.agentSessionId,
3099
- seq,
3100
- ...turnId ? { turnId } : {},
3101
- eventId,
3102
- actorType,
3103
- actorId: actorType === "user" ? "user" : message.agentSessionId,
3104
- itemType,
3105
- role,
3106
- status: message.status,
3107
- content,
3108
- payload: normalizedPayload(message.payload),
3109
- ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
3110
- ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
3111
- };
3112
- }
3113
- function workspaceIdFromMessage(message) {
3114
- return message.workspaceId?.trim() || "";
3115
- }
3116
- function workspaceTimelineFields(workspaceId) {
3117
- return {
3118
- workspaceId
3119
- };
3120
- }
3121
- function compareMessagesByDisplayOrder(left, right) {
3122
- const leftTime = messageDisplayOrderTime(left);
3123
- const rightTime = messageDisplayOrderTime(right);
3124
- if (leftTime > 0 && rightTime > 0 && leftTime !== rightTime) {
3125
- return leftTime - rightTime;
3126
- }
3127
- const leftVersion = normalizedPositiveNumber(left.version);
3128
- const rightVersion = normalizedPositiveNumber(right.version);
3129
- if (leftVersion > 0 && rightVersion > 0 && leftVersion !== rightVersion) {
3130
- return leftVersion - rightVersion;
3131
- }
3132
- return 0;
3133
- }
3134
- function normalizedMessageId(id, index) {
3135
- const normalizedId = typeof id === "number" ? id : 0;
3136
- return Number.isFinite(normalizedId) && normalizedId > 0 ? normalizedId : index + 1;
3137
- }
3138
- function normalizedPositiveNumber(value) {
3139
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
3140
- }
3141
- function messageDisplayOrderTime(message) {
3142
- return normalizedPositiveNumber(message.startedAtUnixMs) || normalizedPositiveNumber(message.occurredAtUnixMs) || normalizedPositiveNumber(message.completedAtUnixMs);
3143
- }
3144
- function toolCallItemType(status) {
3145
- switch (normalizeToken(status)) {
3146
- case "running":
3147
- case "working":
3148
- case "active":
3149
- return "call.started";
3150
- case "completed":
3151
- case "complete":
3152
- case "done":
3153
- case "success":
3154
- case "succeeded":
3155
- return "call.completed";
3156
- case "failed":
3157
- case "error":
3158
- return "call.failed";
3159
- case "canceled":
3160
- return "call.canceled";
3161
- default:
3162
- return "call";
3163
- }
3164
- }
3165
- function messageText(message) {
3166
- const payload = normalizedPayload(message.payload);
3167
- const title = messagePayloadString(message, "title");
3168
- return firstNonEmptyString(
3169
- stringValue(payload.displayPrompt),
3170
- stringValue(payload.text),
3171
- stringValue(payload.content),
3172
- stringValue(payload.message),
3173
- stringValue(payload.body),
3174
- title
3175
- );
3176
- }
3177
- function statusMessageText(message) {
3178
- const title = messagePayloadString(message, "title") ?? "";
3179
- const text = messageText(message);
3180
- if (title && text && title !== text) {
3181
- return `${title}
3182
-
3183
- ${text}`;
3184
- }
3185
- return title || text;
3186
- }
3187
- function messagePayloadString(message, key) {
3188
- return stringValue(normalizedPayload(message.payload)[key]);
3189
- }
3190
- function mergePayload(previous, next) {
3191
- if (!previous) {
3192
- return next;
3193
- }
3194
- const merged = { ...previous, ...next };
3195
- for (const key of [
3196
- "input",
3197
- "output",
3198
- "error",
3199
- "metadata",
3200
- "toolState",
3201
- "tool_state"
3202
- ]) {
3203
- if (isRecord2(previous[key]) || isRecord2(next[key])) {
3204
- merged[key] = {
3205
- ...isRecord2(previous[key]) ? previous[key] : {},
3206
- ...isRecord2(next[key]) ? next[key] : {}
3207
- };
3208
- }
3209
- }
3210
- return merged;
3211
- }
3212
- function normalizedPayload(payload) {
3213
- return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
3214
- }
3215
- function sanitizedToolPayload(payload, callId) {
3216
- if (!isOpaqueCallIdentifierString(stringValue(payload.toolName), callId)) {
3217
- return payload;
3218
- }
3219
- const { toolName: _toolName, ...rest } = payload;
3220
- return rest;
3221
- }
3222
- function isRecord2(value) {
3223
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3224
- }
3225
- function stringValue(value) {
3226
- return typeof value === "string" && value.trim() ? value.trim() : "";
3227
- }
3228
- function firstNonEmptyString(...values) {
3229
- for (const value of values) {
3230
- if (typeof value === "string" && value.trim()) {
3231
- return value.trim();
3232
- }
3233
- }
3234
- return "";
3235
- }
3236
- function displayToolNameCandidate(value, callId) {
3237
- const trimmed = value?.trim() ?? "";
3238
- if (!trimmed || isOpaqueCallIdentifierString(trimmed, callId)) {
3239
- return "";
3240
- }
3241
- return trimmed;
3242
- }
3243
- function isOpaqueCallIdentifierString(value, callId) {
3244
- const trimmed = value.trim();
3245
- if (!trimmed) {
3246
- return false;
3247
- }
3248
- if (callId?.trim() && trimmed === callId.trim()) {
3249
- return true;
3250
- }
3251
- const lower = trimmed.toLowerCase();
3252
- if (lower.startsWith("call_")) {
3253
- return isOpaqueIdentifierTail(trimmed.slice("call_".length));
3254
- }
3255
- if (lower.startsWith("ws_")) {
3256
- return isOpaqueIdentifierTail(trimmed.slice("ws_".length));
3257
- }
3258
- return false;
3259
- }
3260
- function isOpaqueIdentifierTail(value) {
3261
- return value.length >= 12 && /^[a-z0-9]+$/i.test(value);
3262
- }
3263
- function normalizeToken(value) {
3264
- return value?.trim().toLowerCase() ?? "";
3265
- }
3266
-
3267
3589
  // agent-gui/agentGuiNode/controller/agentGuiController.promptHelpers.ts
3268
3590
  function createAgentGUIConversationId() {
3269
3591
  if (typeof globalThis.crypto?.randomUUID === "function") {
@@ -3617,7 +3939,7 @@ function reasoningOptionsFromRuntimeConfig(runtimeContext) {
3617
3939
  return null;
3618
3940
  }
3619
3941
  for (const rawOption of configOptions) {
3620
- const option = recordValue(rawOption);
3942
+ const option = recordValue2(rawOption);
3621
3943
  const id = normalizeConfigOptionValue(option?.id);
3622
3944
  if (!option || !id || !["reasoning_effort", "model_reasoning_effort", "effort"].includes(id)) {
3623
3945
  continue;
@@ -3628,7 +3950,7 @@ function reasoningOptionsFromRuntimeConfig(runtimeContext) {
3628
3950
  }
3629
3951
  const options = [];
3630
3952
  for (const rawEntry of rawEntries) {
3631
- const entry = recordValue(rawEntry);
3953
+ const entry = recordValue2(rawEntry);
3632
3954
  const value = normalizeConfigOptionValue(entry?.value);
3633
3955
  if (!entry || !value || options.some((candidate) => candidate.value === value)) {
3634
3956
  continue;
@@ -3650,7 +3972,7 @@ function reasoningOptionsFromRuntimeConfig(runtimeContext) {
3650
3972
  }
3651
3973
  return null;
3652
3974
  }
3653
- function recordValue(value) {
3975
+ function recordValue2(value) {
3654
3976
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
3655
3977
  }
3656
3978
  function reasoningProfileForModel(options, model) {
@@ -4719,7 +5041,12 @@ function toRuntimeSendContent(content) {
4719
5041
  return materializePastedTextInstructions(content, {
4720
5042
  header: () => translate("agentHost.agentGui.pastedTextFilesHeader"),
4721
5043
  line: (preview, path) => translate("agentHost.agentGui.pastedTextFileLine", { preview, path })
4722
- });
5044
+ }).map(
5045
+ (block) => block.type === "text" ? {
5046
+ ...block,
5047
+ text: materializeAgentCustomMentionPromptText(block.text ?? "").trim()
5048
+ } : block
5049
+ );
4723
5050
  }
4724
5051
  function shouldClearSubmittedDraft(input) {
4725
5052
  return Boolean(
@@ -5012,16 +5339,16 @@ function conversationDetailSessionsEqual(left, right) {
5012
5339
  return left.workspaceId === right.workspaceId && left.agentSessionId === right.agentSessionId && left.userId === right.userId && left.agentTargetId === right.agentTargetId && left.provider === right.provider && left.providerSessionId === right.providerSessionId && left.model === right.model && left.resumable === right.resumable && left.endedAtUnixMs === right.endedAtUnixMs && left.title === right.title && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.cwd === right.cwd && left.activeTurnId === right.activeTurnId && left.activeTurn?.updatedAtUnixMs === right.activeTurn?.updatedAtUnixMs && left.latestTurn?.updatedAtUnixMs === right.latestTurn?.updatedAtUnixMs && left.pendingInteractions === right.pendingInteractions && left.latestTurnInteractions === right.latestTurnInteractions;
5013
5340
  }
5014
5341
  function conversationSummariesRenderEqual(left, right) {
5015
- return left.id === right.id && left.userId === right.userId && left.provider === right.provider && left.title === right.title && conversationTitleFallbacksRenderEqual(
5342
+ return left.id === right.id && left.userId === right.userId && left.provider === right.provider && left.title === right.title && left.titleLeadingMentionKind === right.titleLeadingMentionKind && conversationTitleFallbacksRenderEqual(
5016
5343
  left.titleFallback,
5017
5344
  right.titleFallback
5018
- ) && left.status === right.status && left.cwd === right.cwd && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sortTimeUnixMs === right.sortTimeUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.projectionSource === right.projectionSource && left.isImported === right.isImported && left.hasUnreadCompletion === right.hasUnreadCompletion && left.unreadCompletionKey === right.unreadCompletionKey && conversationProjectsRenderEqual(left.project, right.project);
5345
+ ) && left.status === right.status && left.cwd === right.cwd && left.railSectionKey === right.railSectionKey && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sortTimeUnixMs === right.sortTimeUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.projectionSource === right.projectionSource && left.isImported === right.isImported && left.hasUnreadCompletion === right.hasUnreadCompletion && left.unreadCompletionKey === right.unreadCompletionKey && conversationProjectsRenderEqual(left.project, right.project);
5019
5346
  }
5020
5347
  function conversationTitleFallbacksRenderEqual(left, right) {
5021
5348
  return left === right || JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
5022
5349
  }
5023
5350
  function conversationProjectsRenderEqual(left, right) {
5024
- 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);
5351
+ return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.sectionKey === right.sectionKey && left.label === right.label && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs);
5025
5352
  }
5026
5353
  function draftAgentSessionIdFromComposerOptions(options) {
5027
5354
  return normalizeConfigOptionValue(options?.draftAgentSessionId);
@@ -6160,21 +6487,66 @@ import {
6160
6487
  selectPendingActivations,
6161
6488
  selectWorkspaceReconcileState
6162
6489
  } from "@tutti-os/agent-activity-core";
6163
- function projectCanonicalAgentGUIConversationSummaries(sessions) {
6490
+
6491
+ // shared/agentConversationRailTitlePromptSelector.ts
6492
+ import {
6493
+ selectSessionMessagesById
6494
+ } from "@tutti-os/agent-activity-core";
6495
+ function createAgentGUIConversationRailTitlePromptSelector() {
6496
+ let previous = {};
6497
+ return (state) => {
6498
+ const next = {};
6499
+ for (const [agentSessionId, messages] of Object.entries(
6500
+ selectSessionMessagesById(state)
6501
+ )) {
6502
+ const displayPrompt = resolveAgentGUIFirstUserMessageDisplayPrompt(messages);
6503
+ if (displayPrompt) {
6504
+ next[agentSessionId] = displayPrompt;
6505
+ }
6506
+ }
6507
+ if (agentGUIConversationRailTitlePromptsEqual(previous, next)) {
6508
+ return previous;
6509
+ }
6510
+ previous = next;
6511
+ return previous;
6512
+ };
6513
+ }
6514
+ function agentGUIConversationRailTitlePromptsEqual(left, right) {
6515
+ const leftKeys = Object.keys(left);
6516
+ const rightKeys = Object.keys(right);
6517
+ return leftKeys.length === rightKeys.length && leftKeys.every((key) => left[key] === right[key]);
6518
+ }
6519
+
6520
+ // contexts/workspace/presentation/renderer/agentGuiConversationList/useAgentGuiConversationList.ts
6521
+ var EMPTY_AGENT_GUI_AGENT_TARGETS = [];
6522
+ function projectCanonicalAgentGUIConversationSummaries(sessions, firstUserDisplayPromptsBySessionId = {}) {
6164
6523
  return sessions.map((item) => {
6165
6524
  const provider = resolveAgentGUIProviderIdentity({
6166
6525
  sessionProvider: item.session.provider
6167
6526
  });
6168
- const { title, titleFallback } = resolveAgentGUIConversationTitle(
6527
+ const { title: canonicalTitle } = resolveAgentGUIConversationTitle(
6169
6528
  item.session.title
6170
6529
  );
6530
+ const firstUserDisplayPrompt = firstUserDisplayPromptsBySessionId[item.session.agentSessionId];
6531
+ const titleDisplayPrompt = resolveAgentGUIConversationTitleDisplayPrompt({
6532
+ firstUserDisplayPrompt,
6533
+ title: canonicalTitle
6534
+ });
6535
+ const { title, titleFallback } = resolveAgentGUIConversationTitle(
6536
+ resolveAgentGUIConversationBrowserFreeTitle({
6537
+ firstUserDisplayPrompt,
6538
+ title: canonicalTitle
6539
+ })
6540
+ );
6171
6541
  const canonicalUpdatedAtUnixMs = item.session.updatedAtUnixMs ?? item.session.createdAtUnixMs ?? 0;
6542
+ const titleLeadingMentionKind = resolveAgentGUIConversationTitleLeadingMentionKind(titleDisplayPrompt);
6172
6543
  return {
6173
6544
  agentTargetId: item.session.agentTargetId ?? null,
6174
6545
  cwd: item.session.cwd,
6175
6546
  id: item.session.agentSessionId,
6176
6547
  pinnedAtUnixMs: item.session.pinnedAtUnixMs ?? null,
6177
6548
  provider,
6549
+ railSectionKey: item.session.railSectionKey,
6178
6550
  resumable: item.session.resumable,
6179
6551
  sortTimeUnixMs: resolveWorkspaceAgentSessionSortTimeUnixMs({
6180
6552
  createdAtUnixMs: item.session.createdAtUnixMs,
@@ -6182,13 +6554,14 @@ function projectCanonicalAgentGUIConversationSummaries(sessions) {
6182
6554
  }),
6183
6555
  status: item.displayStatus === "idle" ? "ready" : item.displayStatus,
6184
6556
  title,
6557
+ titleLeadingMentionKind,
6185
6558
  titleFallback,
6186
6559
  updatedAtUnixMs: canonicalUpdatedAtUnixMs,
6187
6560
  userId: item.session.userId?.trim() ?? ""
6188
6561
  };
6189
6562
  });
6190
6563
  }
6191
- function useAgentGuiConversationList(engine, query, agentTargets = []) {
6564
+ function useAgentGuiConversationList(engine, query, agentTargets = EMPTY_AGENT_GUI_AGENT_TARGETS) {
6192
6565
  const workspaceReconcile = useEngineSelector(
6193
6566
  engine,
6194
6567
  selectWorkspaceReconcileState
@@ -6203,6 +6576,15 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6203
6576
  selectPendingActivations,
6204
6577
  pendingActivationsEqual
6205
6578
  );
6579
+ const selectRailTitlePrompts = useMemo5(
6580
+ () => createAgentGUIConversationRailTitlePromptSelector(),
6581
+ [engine]
6582
+ );
6583
+ const firstUserDisplayPromptsBySessionId = useEngineSelector(
6584
+ engine,
6585
+ selectRailTitlePrompts,
6586
+ Object.is
6587
+ );
6206
6588
  return useMemo5(() => {
6207
6589
  if (!query) return null;
6208
6590
  const canonicalIds = new Set(
@@ -6222,9 +6604,24 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6222
6604
  const provider = resolveAgentGUIProviderIdentity({
6223
6605
  sessionProvider: target?.provider ?? query.provider
6224
6606
  });
6225
- const { title, titleFallback } = resolveAgentGUIConversationTitle(
6607
+ const { title: canonicalTitle } = resolveAgentGUIConversationTitle(
6226
6608
  activation.optimisticTitle ?? activation.title ?? ""
6227
6609
  );
6610
+ const titleDisplayPrompt = resolveAgentGUIConversationTitleDisplayPrompt({
6611
+ activation,
6612
+ allowEmptyTitle: true,
6613
+ title: canonicalTitle
6614
+ });
6615
+ const { title, titleFallback } = resolveAgentGUIConversationTitle(
6616
+ resolveAgentGUIConversationBrowserFreeTitle({
6617
+ activation,
6618
+ allowEmptyTitle: true,
6619
+ title: canonicalTitle
6620
+ })
6621
+ );
6622
+ const titleLeadingMentionKind = resolveAgentGUIConversationTitleLeadingMentionKind(
6623
+ titleDisplayPrompt
6624
+ );
6228
6625
  return {
6229
6626
  agentTargetId: activation.agentTargetId,
6230
6627
  cwd: activation.cwd,
@@ -6234,6 +6631,7 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6234
6631
  status: "working",
6235
6632
  projectionSource: "pending_activation",
6236
6633
  title,
6634
+ titleLeadingMentionKind,
6237
6635
  titleFallback,
6238
6636
  updatedAtUnixMs: activation.requestedAtUnixMs,
6239
6637
  userId: query.userId
@@ -6243,7 +6641,8 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6243
6641
  ...projectCanonicalAgentGUIConversationSummaries(
6244
6642
  sessions.filter(
6245
6643
  (item) => item.session.workspaceId === query.workspaceId
6246
- )
6644
+ ),
6645
+ firstUserDisplayPromptsBySessionId
6247
6646
  ).map((conversation) => {
6248
6647
  const canonicalUpdatedAtUnixMs = conversation.updatedAtUnixMs;
6249
6648
  const activation = latestNewActivationBySessionId.get(conversation.id);
@@ -6251,11 +6650,27 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6251
6650
  const optimisticTitle = activation?.optimisticTitle?.trim() ?? "";
6252
6651
  const shouldUseOptimisticTitle = conversation.title.trim().length === 0 && optimisticTitle.length > 0;
6253
6652
  const projectedTitle = shouldUseOptimisticTitle ? optimisticTitle : activationIsNewer && activation?.title ? activation.title : conversation.title;
6254
- const { title, titleFallback } = resolveAgentGUIConversationTitle(projectedTitle);
6653
+ const { title: projectedCanonicalTitle } = resolveAgentGUIConversationTitle(projectedTitle);
6654
+ const titleDisplayPrompt = resolveAgentGUIConversationTitleDisplayPrompt({
6655
+ activation,
6656
+ allowEmptyTitle: shouldUseOptimisticTitle,
6657
+ title: projectedCanonicalTitle
6658
+ });
6659
+ const { title, titleFallback } = resolveAgentGUIConversationTitle(
6660
+ resolveAgentGUIConversationBrowserFreeTitle({
6661
+ activation,
6662
+ allowEmptyTitle: shouldUseOptimisticTitle,
6663
+ title: projectedCanonicalTitle
6664
+ })
6665
+ );
6666
+ const titleLeadingMentionKind = resolveAgentGUIConversationTitleLeadingMentionKind(
6667
+ titleDisplayPrompt
6668
+ ) ?? conversation.titleLeadingMentionKind;
6255
6669
  return {
6256
6670
  ...conversation,
6257
6671
  sortTimeUnixMs: activationIsNewer ? activation.requestedAtUnixMs : conversation.sortTimeUnixMs,
6258
6672
  title,
6673
+ titleLeadingMentionKind,
6259
6674
  titleFallback,
6260
6675
  updatedAtUnixMs: activationIsNewer ? activation.requestedAtUnixMs : canonicalUpdatedAtUnixMs
6261
6676
  };
@@ -6285,7 +6700,14 @@ function useAgentGuiConversationList(engine, query, agentTargets = []) {
6285
6700
  query.sessionOrigin
6286
6701
  ].join("::")
6287
6702
  };
6288
- }, [agentTargets, pendingActivations, query, sessions, workspaceReconcile]);
6703
+ }, [
6704
+ agentTargets,
6705
+ firstUserDisplayPromptsBySessionId,
6706
+ pendingActivations,
6707
+ query,
6708
+ sessions,
6709
+ workspaceReconcile
6710
+ ]);
6289
6711
  }
6290
6712
  function pendingActivationsEqual(left, right) {
6291
6713
  return left.length === right.length && left.every((item, index) => item === right[index]);
@@ -6294,7 +6716,9 @@ function consumerSessionsEqual(left, right) {
6294
6716
  if (left.length !== right.length) return false;
6295
6717
  return left.every((item, index) => {
6296
6718
  const other = right[index];
6297
- return other !== void 0 && item.session === other.session && item.activeTurn === other.activeTurn && item.latestTurn === other.latestTurn && item.pendingInteractions === other.pendingInteractions && item.displayStatus === other.displayStatus;
6719
+ return other !== void 0 && item.session === other.session && item.activeTurn === other.activeTurn && item.latestTurn === other.latestTurn && item.pendingInteractions.length === other.pendingInteractions.length && item.pendingInteractions.every(
6720
+ (interaction, interactionIndex) => interaction === other.pendingInteractions[interactionIndex]
6721
+ ) && item.displayStatus === other.displayStatus;
6298
6722
  });
6299
6723
  }
6300
6724
 
@@ -6473,7 +6897,6 @@ function useAgentGUIComposerCapabilities(input) {
6473
6897
  [usageSource]
6474
6898
  );
6475
6899
  return {
6476
- backgroundAgentCount: input.activeEngineSession?.backgroundAgents?.count ?? 0,
6477
6900
  compactSupported: sessionCapabilities?.compact ?? resolveAgentActivityCapability2("compact", {
6478
6901
  composerOptions: providerComposerOptions,
6479
6902
  sessionCapabilities
@@ -6496,7 +6919,7 @@ function useAgentGUIComposerCapabilities(input) {
6496
6919
  import {
6497
6920
  selectLatestActivationForSession as selectLatestActivationForSession2
6498
6921
  } from "@tutti-os/agent-activity-core";
6499
- import { useCallback as useCallback7, useEffect as useEffect5 } from "react";
6922
+ import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef8 } from "react";
6500
6923
 
6501
6924
  // host/agentHostEventBus.ts
6502
6925
  var LOG_PREFIX = "[agent-host-event-bus]";
@@ -6652,6 +7075,10 @@ function subscribeCoalesced(type, options, callback) {
6652
7075
 
6653
7076
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerOptionsSync.ts
6654
7077
  function useAgentGUIComposerOptionsSync(input) {
7078
+ const previousActiveConversationIdRef = useRef8(input.activeConversationId);
7079
+ const previousIsCreatingConversationRef = useRef8(
7080
+ input.isCreatingConversation
7081
+ );
6655
7082
  const loadComposerOptionsForTarget = useCallback7(
6656
7083
  (targetData, options) => {
6657
7084
  if (input.isCreatingConversation || !targetData.agentTargetId) return;
@@ -6747,8 +7174,12 @@ function useAgentGUIComposerOptionsSync(input) {
6747
7174
  }, [input.loadSessionState, input.previewMode, loadDraftComposerOptions]);
6748
7175
  useEffect5(() => {
6749
7176
  if (input.previewMode) return;
7177
+ const conversationActivated = input.activeConversationId !== null && previousActiveConversationIdRef.current !== input.activeConversationId;
7178
+ const conversationCreationSettled = previousIsCreatingConversationRef.current && !input.isCreatingConversation;
7179
+ previousActiveConversationIdRef.current = input.activeConversationId;
7180
+ previousIsCreatingConversationRef.current = input.isCreatingConversation;
6750
7181
  loadDraftComposerOptions(
6751
- input.providerComposerOptions?.behavior?.prewarmDraftSession === true && input.isComposerHome ? { force: true } : void 0
7182
+ conversationActivated || conversationCreationSettled || input.providerComposerOptions?.behavior?.prewarmDraftSession === true && input.isComposerHome ? { force: true } : void 0
6752
7183
  );
6753
7184
  }, [
6754
7185
  input.activeConversationId,
@@ -6796,54 +7227,54 @@ function useAgentGUIComposerOptionsSync(input) {
6796
7227
  }
6797
7228
 
6798
7229
  // agent-gui/agentGuiNode/controller/useAgentGUIControllerRefs.ts
6799
- import { useRef as useRef8 } from "react";
7230
+ import { useRef as useRef9 } from "react";
6800
7231
  function useAgentGUIControllerRefs(input) {
6801
- const activeConversationIdRef = useRef8(input.activeConversationId);
6802
- const selectedProjectPathRef = useRef8(input.selectedProjectPath);
6803
- const userProjectsRef = useRef8(input.userProjects);
6804
- const isNoProjectPathRef = useRef8(input.isNoProjectPath);
6805
- const userProjectsLoadSeqRef = useRef8(0);
6806
- const composerOptionsProjectKeyRef = useRef8(null);
6807
- const conversationsRef = useRef8(input.conversations);
6808
- const isMountedRef = useRef8(true);
6809
- const agentActivitySnapshotRef = useRef8(input.agentActivitySnapshot);
6810
- const dataRef = useRef8(input.data);
6811
- const selectedAgentTargetRef = useRef8(input.effectiveSelectedProviderTarget);
6812
- const selectedAgentTargetIsExplicitRef = useRef8(
7232
+ const activeConversationIdRef = useRef9(input.activeConversationId);
7233
+ const selectedProjectPathRef = useRef9(input.selectedProjectPath);
7234
+ const userProjectsRef = useRef9(input.userProjects);
7235
+ const isNoProjectPathRef = useRef9(input.isNoProjectPath);
7236
+ const userProjectsLoadSeqRef = useRef9(0);
7237
+ const composerOptionsProjectKeyRef = useRef9(null);
7238
+ const conversationsRef = useRef9(input.conversations);
7239
+ const isMountedRef = useRef9(true);
7240
+ const agentActivitySnapshotRef = useRef9(input.agentActivitySnapshot);
7241
+ const dataRef = useRef9(input.data);
7242
+ const selectedAgentTargetRef = useRef9(input.effectiveSelectedProviderTarget);
7243
+ const selectedAgentTargetIsExplicitRef = useRef9(
6813
7244
  input.homeComposerTargetOverride ? true : input.selectedAgentTargetIsExplicit
6814
7245
  );
6815
- const agentTargetsProvidedRef = useRef8(input.agentTargetsProvided);
6816
- const selectedComposerTargetDataRef = useRef8(
7246
+ const agentTargetsProvidedRef = useRef9(input.agentTargetsProvided);
7247
+ const selectedComposerTargetDataRef = useRef9(
6817
7248
  input.selectedComposerTargetData
6818
7249
  );
6819
- const draftByScopeKeyRef = useRef8(input.draftByScopeKey);
6820
- const draftSettingsBySessionIdRef = useRef8(input.draftSettingsBySessionId);
6821
- const onDataChangeRef = useRef8(input.onDataChange);
6822
- const onRememberComposerDefaultsRef = useRef8(
7250
+ const draftByScopeKeyRef = useRef9(input.draftByScopeKey);
7251
+ const draftSettingsBySessionIdRef = useRef9(input.draftSettingsBySessionId);
7252
+ const onDataChangeRef = useRef9(input.onDataChange);
7253
+ const onRememberComposerDefaultsRef = useRef9(
6823
7254
  input.onRememberComposerDefaults
6824
7255
  );
6825
- const onShowMessageRef = useRef8(input.onShowMessage);
6826
- const handledPrefillPromptSequenceRef = useRef8(null);
6827
- const handledComposerAppendSequenceRef = useRef8(null);
6828
- const loadDraftComposerOptionsRef = useRef8(() => {
7256
+ const onShowMessageRef = useRef9(input.onShowMessage);
7257
+ const handledPrefillPromptSequenceRef = useRef9(null);
7258
+ const handledComposerAppendSequenceRef = useRef9(null);
7259
+ const loadDraftComposerOptionsRef = useRef9(() => {
6829
7260
  });
6830
- const lastActiveModelByProviderRef = useRef8({});
6831
- const conversationIdsRef = useRef8(
7261
+ const lastActiveModelByProviderRef = useRef9({});
7262
+ const conversationIdsRef = useRef9(
6832
7263
  new Set(input.conversations.map((conversation) => conversation.id))
6833
7264
  );
6834
- const lastRenderStateDiagnosticKeyRef = useRef8(null);
6835
- const handledOpenSessionSequenceRef = useRef8(null);
6836
- const pendingOpenSessionRequestRef = useRef8(null);
6837
- const executePromptRef = useRef8(() => {
7265
+ const lastRenderStateDiagnosticKeyRef = useRef9(null);
7266
+ const handledOpenSessionSequenceRef = useRef9(null);
7267
+ const pendingOpenSessionRequestRef = useRef9(null);
7268
+ const executePromptRef = useRef9(() => {
6838
7269
  });
6839
- const submitPromptRef = useRef8(() => {
7270
+ const submitPromptRef = useRef9(() => {
6840
7271
  });
6841
- const reloadSelectedConversationRef = useRef8(() => {
7272
+ const reloadSelectedConversationRef = useRef9(() => {
6842
7273
  });
6843
- const syncConversationListProjectionRef = useRef8(async () => {
7274
+ const syncConversationListProjectionRef = useRef9(async () => {
6844
7275
  });
6845
- const isComposerHomeRef = useRef8(input.isComposerHome);
6846
- const isCreatingConversationRef = useRef8(input.isCreatingConversation);
7276
+ const isComposerHomeRef = useRef9(input.isComposerHome);
7277
+ const isCreatingConversationRef = useRef9(input.isCreatingConversation);
6847
7278
  activeConversationIdRef.current = input.activeConversationId;
6848
7279
  selectedProjectPathRef.current = input.selectedProjectPath;
6849
7280
  userProjectsRef.current = input.userProjects;
@@ -6908,9 +7339,26 @@ import { useCallback as useCallback18 } from "react";
6908
7339
 
6909
7340
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerSettingsActions.ts
6910
7341
  import {
6911
- selectEngineSession
7342
+ selectEngineSession,
7343
+ selectEngineSessionSettingsUpdate
6912
7344
  } from "@tutti-os/agent-activity-core";
6913
7345
  import { useCallback as useCallback8 } from "react";
7346
+
7347
+ // agent-gui/agentGuiNode/model/composerModeSelection.ts
7348
+ function permissionModeSelectionPatch(permissionModeId, options) {
7349
+ return options.clearsPlanMode ? { permissionModeId, planMode: false } : { permissionModeId };
7350
+ }
7351
+ function resolvePermissionModeControlsDisabled(options) {
7352
+ if (options.changeDuringTurnSupported) {
7353
+ return options.isSubmittingPrompt;
7354
+ }
7355
+ return options.isSendingTurn || options.isSubmittingPrompt || options.showStopButton;
7356
+ }
7357
+ function shouldRetrySessionSettingsUpdate(status) {
7358
+ return status === "unknown";
7359
+ }
7360
+
7361
+ // agent-gui/agentGuiNode/controller/useAgentGUIComposerSettingsActions.ts
6914
7362
  function useAgentGUIComposerSettingsActions(input) {
6915
7363
  const {
6916
7364
  activation,
@@ -7062,27 +7510,35 @@ function useAgentGUIComposerSettingsActions(input) {
7062
7510
  }
7063
7511
  }
7064
7512
  if (Object.keys(sessionSettingsPatch).length > 0 && (canonicalSession !== null || isPreActivationSession)) {
7065
- void onRememberComposerDefaultsRef.current?.({
7066
- agentTargetId: normalizeOptionalText(dataRef.current.agentTargetId),
7067
- provider: dataRef.current.provider,
7068
- defaults: composerDefaultsPatchFromSettings(
7069
- sessionSettingsPatch,
7070
- sessionSettingsPatch
7071
- )
7072
- });
7073
- const durableNodeDefaultsPatch = {};
7074
- for (const field of rememberComposerDefaultsFields) {
7075
- if (sessionSettingsPatch[field] !== void 0) {
7076
- durableNodeDefaultsPatch[field] = sessionSettingsPatch[field];
7513
+ const rememberedDefaultsPatch = composerDefaultsPatchFromSettings(
7514
+ sessionSettingsPatch,
7515
+ sessionSettingsPatch
7516
+ );
7517
+ if (rememberedDefaultsPatch) {
7518
+ const defaultAgentTargetId = normalizeOptionalText(canonicalSession?.agentTargetId) ?? normalizeOptionalText(dataRef.current.agentTargetId);
7519
+ const defaultProvider = canonicalSession?.provider ?? dataRef.current.provider;
7520
+ void onRememberComposerDefaultsRef.current?.({
7521
+ agentTargetId: defaultAgentTargetId,
7522
+ provider: defaultProvider,
7523
+ defaults: rememberedDefaultsPatch
7524
+ });
7525
+ const durableNodeDefaultsPatch = {};
7526
+ for (const field of rememberComposerDefaultsFields) {
7527
+ if (sessionSettingsPatch[field] !== void 0) {
7528
+ durableNodeDefaultsPatch[field] = sessionSettingsPatch[field];
7529
+ }
7077
7530
  }
7078
- }
7079
- if (Object.keys(durableNodeDefaultsPatch).length > 0) {
7080
7531
  const defaultDraftKey = nodeDefaultDraftKey(
7081
- dataRef.current.provider,
7082
- dataRef.current.agentTargetId
7532
+ defaultProvider,
7533
+ defaultAgentTargetId
7083
7534
  );
7535
+ const defaultData = {
7536
+ ...dataRef.current,
7537
+ provider: defaultProvider,
7538
+ agentTargetId: defaultAgentTargetId
7539
+ };
7084
7540
  const storedNodeDefaults = readNodeDefaultDraftSettings({
7085
- data: dataRef.current,
7541
+ data: defaultData,
7086
7542
  defaultReasoningEffort,
7087
7543
  drafts: draftSettingsBySessionIdRef.current
7088
7544
  });
@@ -7099,7 +7555,14 @@ function useAgentGUIComposerSettingsActions(input) {
7099
7555
  [defaultDraftKey]: nextNodeDefaults
7100
7556
  }));
7101
7557
  onDataChangeRef.current(
7102
- (current) => nodeDataFromComposerSettings(current, nextNodeDefaults)
7558
+ (current) => nodeDataFromComposerSettings(
7559
+ {
7560
+ ...current,
7561
+ provider: defaultProvider,
7562
+ agentTargetId: defaultAgentTargetId
7563
+ },
7564
+ nextNodeDefaults
7565
+ )
7103
7566
  );
7104
7567
  }
7105
7568
  if (isPreActivationSession) {
@@ -7109,9 +7572,14 @@ function useAgentGUIComposerSettingsActions(input) {
7109
7572
  settings: { ...sessionSettingsPatch }
7110
7573
  });
7111
7574
  } else {
7575
+ const settingsUpdate = selectEngineSessionSettingsUpdate(
7576
+ sessionEngine.getSnapshot(),
7577
+ agentSessionId
7578
+ );
7112
7579
  sessionEngine.dispatch({
7113
7580
  agentSessionId,
7114
7581
  commandId: `settings:${createAgentGUIConversationId()}`,
7582
+ retry: shouldRetrySessionSettingsUpdate(settingsUpdate?.status),
7115
7583
  settings: { ...sessionSettingsPatch },
7116
7584
  timeoutMs: 3e4,
7117
7585
  type: "session/settingsUpdateRequested",
@@ -7136,12 +7604,12 @@ function useAgentGUIComposerSettingsActions(input) {
7136
7604
  }
7137
7605
 
7138
7606
  // agent-gui/agentGuiNode/controller/useAgentGUIContinueConversation.ts
7139
- import { useCallback as useCallback9, useRef as useRef9 } from "react";
7607
+ import { useCallback as useCallback9, useRef as useRef10 } from "react";
7140
7608
  function buildContinueInNewConversationDraft(input) {
7141
7609
  return updateAgentComposerDraft(input.sourceDraft, { prompt: input.prompt });
7142
7610
  }
7143
7611
  function useAgentGUIContinueConversation(input) {
7144
- const inputRef = useRef9(input);
7612
+ const inputRef = useRef10(input);
7145
7613
  inputRef.current = input;
7146
7614
  return useCallback9(() => {
7147
7615
  const current = inputRef.current;
@@ -7558,6 +8026,17 @@ import {
7558
8026
  } from "react";
7559
8027
 
7560
8028
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerAppendRequest.ts
8029
+ function appendAgentGUIComposerPrompt(draft, incomingPrompt) {
8030
+ const currentPrompt = agentComposerDraftPrompt(draft);
8031
+ const normalizedPrompt = incomingPrompt.trim();
8032
+ if (!normalizedPrompt || currentPrompt.includes(normalizedPrompt)) {
8033
+ return draft;
8034
+ }
8035
+ const separator = currentPrompt && !/\s$/u.test(currentPrompt) ? " " : "";
8036
+ return updateAgentComposerDraft(draft, {
8037
+ prompt: `${currentPrompt}${separator}${normalizedPrompt} `
8038
+ });
8039
+ }
7561
8040
  function appendAgentGUIComposerFiles(draft, incomingFiles) {
7562
8041
  const files = agentComposerDraftFiles(draft);
7563
8042
  const knownIds = new Set(files.map((file) => file.id));
@@ -7585,7 +8064,10 @@ function resolveAgentGUIComposerAppendRequest(input) {
7585
8064
  const currentDraft = draftByScopeKey[draftKey] ?? emptyAgentComposerDraft();
7586
8065
  return {
7587
8066
  draftKey,
7588
- nextDraft: appendAgentGUIComposerFiles(currentDraft, request.files),
8067
+ nextDraft: appendAgentGUIComposerFiles(
8068
+ appendAgentGUIComposerPrompt(currentDraft, request.prompt ?? ""),
8069
+ request.files ?? []
8070
+ ),
7589
8071
  sequence: request.sequence
7590
8072
  };
7591
8073
  }
@@ -8391,6 +8873,21 @@ var AgentGUIHomeDraftSettlementController = class {
8391
8873
  }
8392
8874
  };
8393
8875
 
8876
+ // agent-gui/agentGuiNode/controller/agentGuiController.interactionHelpers.ts
8877
+ function resolveAgentGUIInteractionTarget(interactions, requestId) {
8878
+ const normalizedRequestId = requestId.trim();
8879
+ if (!normalizedRequestId) return null;
8880
+ for (let index = interactions.length - 1; index >= 0; index -= 1) {
8881
+ const interaction = interactions[index];
8882
+ if (interaction?.requestId.trim() !== normalizedRequestId) continue;
8883
+ const agentSessionId = interaction.agentSessionId.trim();
8884
+ const turnId = interaction.turnId.trim();
8885
+ if (!agentSessionId || !turnId) return null;
8886
+ return { agentSessionId, turnId };
8887
+ }
8888
+ return null;
8889
+ }
8890
+
8394
8891
  // agent-gui/agentGuiNode/controller/useAgentGUISubmitInteractionActions.ts
8395
8892
  function useAgentGUISubmitInteractionActions(input) {
8396
8893
  const {
@@ -8793,12 +9290,14 @@ function useAgentGUISubmitInteractionActions(input) {
8793
9290
  planActionsRef.current.skip();
8794
9291
  return;
8795
9292
  }
8796
- const agentSessionId = activeConversationIdRef.current;
8797
9293
  const normalizedRequestId = input2.requestId.trim();
8798
9294
  const normalizedOptionId = input2.optionId?.trim() ?? "";
8799
- const turnId = activeEnginePendingInteractions.find(
8800
- (interaction) => interaction.requestId === normalizedRequestId
8801
- )?.turnId ?? "";
9295
+ const target = resolveAgentGUIInteractionTarget(
9296
+ activeEnginePendingInteractions,
9297
+ normalizedRequestId
9298
+ );
9299
+ const agentSessionId = target?.agentSessionId ?? "";
9300
+ const turnId = target?.turnId ?? "";
8802
9301
  if (!agentSessionId || !normalizedRequestId || !turnId || isRespondingToInteraction) {
8803
9302
  return;
8804
9303
  }
@@ -8975,7 +9474,6 @@ function useAgentGUIViewModel(candidate) {
8975
9474
  [
8976
9475
  candidate.detail.availability,
8977
9476
  candidate.detail.avoidGroupingEdits,
8978
- candidate.detail.backgroundAgentCount,
8979
9477
  candidate.detail.conversation,
8980
9478
  candidate.detail.conversationDetail,
8981
9479
  candidate.detail.hasOlderMessages,
@@ -9883,9 +10381,9 @@ function useAgentGUIControllerActions(actions) {
9883
10381
  import {
9884
10382
  selectEngineAvailableCommands
9885
10383
  } from "@tutti-os/agent-activity-core";
9886
- import { useEffect as useEffect9, useMemo as useMemo11, useRef as useRef10 } from "react";
10384
+ import { useEffect as useEffect9, useMemo as useMemo11, useRef as useRef11 } from "react";
9887
10385
  function useAgentGUIConversationDetail(input) {
9888
- const projectionConversationRef = useRef10(null);
10386
+ const projectionConversationRef = useRef11(null);
9889
10387
  const activeCanonicalLiveTurn = Boolean(
9890
10388
  input.activeTurn && input.activeTurn.phase !== "settled"
9891
10389
  );
@@ -9932,20 +10430,30 @@ function useAgentGUIConversationDetail(input) {
9932
10430
  [input.providerComposerOptions]
9933
10431
  )
9934
10432
  );
9935
- const conversationModels = useMemo11(
9936
- () => projectionConversation ? buildAgentGUIConversationModels({
10433
+ const conversationModels = useMemo11(() => {
10434
+ if (!projectionConversation) {
10435
+ return { conversation: null, detail: null };
10436
+ }
10437
+ const rootSessionId = projectionConversation.id.trim();
10438
+ const childSessions = input.agentActivitySnapshot.sessions.filter(
10439
+ (session) => session.kind === "child" && session.rootAgentSessionId === rootSessionId
10440
+ );
10441
+ return buildAgentGUIConversationModels({
9937
10442
  timelineItems: input.activeTimelineItems,
9938
10443
  conversation: projectionConversation,
10444
+ childSessions,
10445
+ childMessagesBySessionId: input.agentActivitySnapshot.sessionMessagesById,
9939
10446
  workspaceRoot: input.workspacePath,
9940
10447
  avoidGroupingEdits: input.avoidGroupingEdits
9941
- }) : { conversation: null, detail: null },
9942
- [
9943
- input.activeTimelineItems,
9944
- input.avoidGroupingEdits,
9945
- input.workspacePath,
9946
- projectionConversation
9947
- ]
9948
- );
10448
+ });
10449
+ }, [
10450
+ input.activeTimelineItems,
10451
+ input.agentActivitySnapshot.sessionMessagesById,
10452
+ input.agentActivitySnapshot.sessions,
10453
+ input.avoidGroupingEdits,
10454
+ input.workspacePath,
10455
+ projectionConversation
10456
+ ]);
9949
10457
  const conversationDetail = useStableConversationDetail(
9950
10458
  conversationModels.detail
9951
10459
  );
@@ -9960,7 +10468,7 @@ function useAgentGUIConversationDetail(input) {
9960
10468
  }
9961
10469
  return conversationModels.conversation;
9962
10470
  }, [conversationDetail, conversationModels.conversation]);
9963
- const diagnosticKeyRef = useRef10(null);
10471
+ const diagnosticKeyRef = useRef11(null);
9964
10472
  useEffect9(() => {
9965
10473
  if (!input.activeConversationId || !conversation) {
9966
10474
  diagnosticKeyRef.current = null;
@@ -10051,9 +10559,9 @@ function useAgentGUIConversationDetail(input) {
10051
10559
  }
10052
10560
 
10053
10561
  // agent-gui/agentGuiNode/controller/useAgentGUIConversationPresentation.ts
10054
- import { useEffect as useEffect10, useMemo as useMemo12, useRef as useRef11 } from "react";
10562
+ import { useEffect as useEffect10, useMemo as useMemo12, useRef as useRef12 } from "react";
10055
10563
  function useAgentGUIConversationPresentation(input) {
10056
- const visibleConversationsRef = useRef11(
10564
+ const visibleConversationsRef = useRef12(
10057
10565
  null
10058
10566
  );
10059
10567
  const conversationProjection = useMemo12(() => {
@@ -10084,7 +10592,7 @@ function useAgentGUIConversationPresentation(input) {
10084
10592
  input.userProjects
10085
10593
  ]);
10086
10594
  const visibleConversations = conversationProjection.visibleConversations;
10087
- const activeConversationRef = useRef11(
10595
+ const activeConversationRef = useRef12(
10088
10596
  null
10089
10597
  );
10090
10598
  const activeConversation = useMemo12(() => {
@@ -10215,10 +10723,10 @@ function useAgentGUIConversationPresentation(input) {
10215
10723
  import {
10216
10724
  useCallback as useCallback19,
10217
10725
  useEffect as useEffect11,
10218
- useRef as useRef12
10726
+ useRef as useRef13
10219
10727
  } from "react";
10220
10728
  function useAgentGUIProviderHome(input) {
10221
- const inputRef = useRef12(input);
10729
+ const inputRef = useRef13(input);
10222
10730
  inputRef.current = input;
10223
10731
  const resolveDefaultHomeComposerTarget = useCallback19(() => {
10224
10732
  const current = inputRef.current;
@@ -10799,7 +11307,6 @@ function useAgentGUIViewAssembly(input) {
10799
11307
  isLoadingOlderMessages: input.activeSessionView?.isLoadingOlderMessages ?? false,
10800
11308
  hasOlderMessages: input.activeSessionView?.hasOlderMessages ?? false,
10801
11309
  usage: input.usage,
10802
- backgroundAgentCount: input.backgroundAgentCount,
10803
11310
  hasSentUserMessage: session.hasSentUserMessage,
10804
11311
  avoidGroupingEdits: input.avoidGroupingEdits,
10805
11312
  conversation: detail.conversation,
@@ -11021,7 +11528,7 @@ import {
11021
11528
  selectEngineSessionError,
11022
11529
  selectEngineSessionIsRespondingToInteraction,
11023
11530
  selectEngineSessionReconcile as selectEngineSessionReconcile2,
11024
- selectEngineSessionSettingsUpdate,
11531
+ selectEngineSessionSettingsUpdate as selectEngineSessionSettingsUpdate2,
11025
11532
  selectEngineSubmitAvailability,
11026
11533
  selectLatestActivationForSession as selectLatestActivationForSession4,
11027
11534
  selectLatestPendingSubmitForSession,
@@ -11151,7 +11658,7 @@ function useAgentGUISessionEngineState(input) {
11151
11658
  );
11152
11659
  const activeEngineSettingsUpdate = useEngineSelector(
11153
11660
  sessionEngine,
11154
- (state) => selectEngineSessionSettingsUpdate(state, activeConversationId)
11661
+ (state) => selectEngineSessionSettingsUpdate2(state, activeConversationId)
11155
11662
  );
11156
11663
  const activeEngineError = activeEngineLifecycleError ?? activeEngineInteractionError ?? activeEngineSettingsUpdate?.errorMessage ?? activeEngineQueueError;
11157
11664
  const isRespondingToInteraction = useEngineSelector(
@@ -11210,7 +11717,7 @@ import { useCallback as useCallback23, useMemo as useMemo17 } from "react";
11210
11717
  import { useCallback as useCallback22 } from "react";
11211
11718
 
11212
11719
  // contexts/workspace/presentation/renderer/agentSessions/useAgentSessionPagingState.ts
11213
- import { useCallback as useCallback20, useRef as useRef13, useState as useState5 } from "react";
11720
+ import { useCallback as useCallback20, useRef as useRef14, useState as useState5 } from "react";
11214
11721
  var EMPTY_ENTRY = {
11215
11722
  error: null,
11216
11723
  isLoadingMessages: false,
@@ -11218,7 +11725,7 @@ var EMPTY_ENTRY = {
11218
11725
  };
11219
11726
  function useAgentSessionPagingState() {
11220
11727
  const [entries, setEntries] = useState5({});
11221
- const entriesRef = useRef13(entries);
11728
+ const entriesRef = useRef14(entries);
11222
11729
  entriesRef.current = entries;
11223
11730
  const update = useCallback20(
11224
11731
  (ref, updater) => {
@@ -11264,7 +11771,7 @@ function sessionKey(ref) {
11264
11771
  }
11265
11772
 
11266
11773
  // contexts/workspace/presentation/renderer/agentSessions/useAgentSessionTransport.ts
11267
- import { useCallback as useCallback21, useRef as useRef14, useState as useState6 } from "react";
11774
+ import { useCallback as useCallback21, useRef as useRef15, useState as useState6 } from "react";
11268
11775
  var EMPTY_ENTRY2 = {
11269
11776
  olderMessages: [],
11270
11777
  hasOlderMessages: false,
@@ -11272,7 +11779,7 @@ var EMPTY_ENTRY2 = {
11272
11779
  };
11273
11780
  function useAgentSessionTransport() {
11274
11781
  const [entries, setEntries] = useState6({});
11275
- const entriesRef = useRef14(entries);
11782
+ const entriesRef = useRef15(entries);
11276
11783
  entriesRef.current = entries;
11277
11784
  const update = useCallback21(
11278
11785
  (ref, updater) => {
@@ -11549,7 +12056,7 @@ function useAgentGUISessionDetailTransport(input) {
11549
12056
  }
11550
12057
 
11551
12058
  // agent-gui/agentGuiNode/controller/useAgentGUILocalState.ts
11552
- import { useRef as useRef15, useState as useState7 } from "react";
12059
+ import { useRef as useRef16, useState as useState7 } from "react";
11553
12060
  function useAgentGUILocalState({
11554
12061
  data,
11555
12062
  userProjectsApi
@@ -11568,7 +12075,7 @@ function useAgentGUILocalState({
11568
12075
  data.lastActiveAgentSessionId === null
11569
12076
  );
11570
12077
  const [draftByScopeKey, setDraftByScopeKey] = useState7({});
11571
- const submittedDraftSnapshotsRef = useRef15({});
12078
+ const submittedDraftSnapshotsRef = useRef16({});
11572
12079
  const [draftSettingsBySessionId, setDraftSettingsBySessionId] = useState7({});
11573
12080
  const [isLoadingMessages, setIsLoadingMessages] = useState7(false);
11574
12081
  const [isDeletingConversation, setIsDeletingConversation] = useState7(false);
@@ -11729,9 +12236,26 @@ function useAgentGUINodeController({
11729
12236
  activeSessionState,
11730
12237
  isCreatingConversation
11731
12238
  } = sessionEngineState;
11732
- const updateComposerSettingsRef = useRef16(() => {
12239
+ const activeRelatedPendingInteractions = useMemo18(() => {
12240
+ if (!activeConversationId) return [];
12241
+ return agentActivitySnapshot.sessions.filter(
12242
+ (session) => session.agentSessionId === activeConversationId || session.kind === "child" && session.rootAgentSessionId === activeConversationId
12243
+ ).flatMap((session) => session.pendingInteractions).sort(
12244
+ (left, right) => left.createdAtUnixMs - right.createdAtUnixMs || left.agentSessionId.localeCompare(right.agentSessionId) || left.requestId.localeCompare(right.requestId)
12245
+ );
12246
+ }, [activeConversationId, agentActivitySnapshot.sessions]);
12247
+ const activeRelatedIsRespondingToInteraction = useEngineSelector(
12248
+ sessionEngine,
12249
+ (state) => activeRelatedPendingInteractions.some(
12250
+ (interaction) => selectEngineSessionIsRespondingToInteraction2(
12251
+ state,
12252
+ interaction.agentSessionId
12253
+ )
12254
+ )
12255
+ );
12256
+ const updateComposerSettingsRef = useRef17(() => {
11733
12257
  });
11734
- const planActionsRef = useRef16({ implement: () => {
12258
+ const planActionsRef = useRef17({ implement: () => {
11735
12259
  }, feedback: () => {
11736
12260
  }, skip: () => {
11737
12261
  } });
@@ -11750,7 +12274,7 @@ function useAgentGUINodeController({
11750
12274
  defaultReasoningEffort,
11751
12275
  providerComposerOptions
11752
12276
  } = composerCapabilities;
11753
- const planImplementationTurnIdRef = useRef16(null);
12277
+ const planImplementationTurnIdRef = useRef17(null);
11754
12278
  const accountProfilesByUserId = useAccountStore(
11755
12279
  (state) => state.profilesByUserId
11756
12280
  );
@@ -12042,6 +12566,7 @@ function useAgentGUINodeController({
12042
12566
  ...controllerRefs,
12043
12567
  ...sessionDetailTransport,
12044
12568
  ...conversationSelection,
12569
+ activeEnginePendingInteractions: activeRelatedPendingInteractions,
12045
12570
  accountProfilesByUserId,
12046
12571
  activation,
12047
12572
  agentActivityRuntime,
@@ -12054,6 +12579,7 @@ function useAgentGUINodeController({
12054
12579
  data,
12055
12580
  defaultAgentTargetId,
12056
12581
  isExplicitAgentGUIAgentTarget,
12582
+ isRespondingToInteraction: activeRelatedIsRespondingToInteraction,
12057
12583
  loadDraftComposerOptions,
12058
12584
  normalizedExplicitProviderTargets,
12059
12585
  normalizedProviderTargets,
@@ -12083,11 +12609,14 @@ function useAgentGUINodeController({
12083
12609
  ...conversationSelection,
12084
12610
  ...operationActions,
12085
12611
  activeCancelStatus: sessionEngineState.activeCancelState?.status ?? null,
12086
- activePendingInteractions: sessionEngineState.activeEnginePendingInteractions,
12612
+ activePendingInteractions: activeRelatedPendingInteractions,
12087
12613
  activeTurn: sessionEngineState.activeEngineActiveTurn,
12088
12614
  activeLatestPendingSubmitTurnId: sessionEngineState.activeLatestPendingSubmit?.turnId ?? null,
12089
12615
  activeMessages,
12090
12616
  activeTimelineItems,
12617
+ agentActivitySnapshot,
12618
+ activeEngineHasPendingInteractions: activeRelatedPendingInteractions.length > 0,
12619
+ isRespondingToInteraction: activeRelatedIsRespondingToInteraction,
12091
12620
  activeConversationLiveState,
12092
12621
  activationState: activeConversationLiveState,
12093
12622
  activityDisplayStatus: activeConversationId ? agentActivityDisplayStatuses.get(activeConversationId) ?? null : null,
@@ -12131,10 +12660,10 @@ import {
12131
12660
  useCallback as useCallback48,
12132
12661
  useEffect as useEffect37,
12133
12662
  useMemo as useMemo37,
12134
- useRef as useRef42,
12663
+ useRef as useRef43,
12135
12664
  useState as useState36
12136
12665
  } from "react";
12137
- import { TooltipProvider as TooltipProvider5 } from "@tutti-os/ui-system";
12666
+ import { TooltipProvider as TooltipProvider4 } from "@tutti-os/ui-system";
12138
12667
 
12139
12668
  // shared/workspaceSettingsPanel/workspaceSettingsPanelStore.ts
12140
12669
  import { useSnapshot } from "valtio";
@@ -12278,6 +12807,7 @@ var styles = {
12278
12807
  conversationStatusGlyph: "agent-gui-node__conversation-status-glyph",
12279
12808
  conversationTime: "agent-gui-node__conversation-time",
12280
12809
  conversationTitle: "agent-gui-node__conversation-title",
12810
+ conversationTitleMentionIcon: "agent-gui-node__conversation-title-mention-icon",
12281
12811
  conversationTitleRow: "agent-gui-node__conversation-title-row",
12282
12812
  conversationUnreadLamp: "agent-gui-node__conversation-unread-lamp",
12283
12813
  detailHeader: "agent-gui-node__detail-header",
@@ -12365,7 +12895,7 @@ var styles = {
12365
12895
  var AgentGUINode_styles_default = styles;
12366
12896
 
12367
12897
  // agent-gui/agentGuiNode/view/agentGUIViewUtils.ts
12368
- import { useCallback as useCallback25, useLayoutEffect, useMemo as useMemo19, useRef as useRef17 } from "react";
12898
+ import { useCallback as useCallback25, useLayoutEffect, useMemo as useMemo19, useRef as useRef18 } from "react";
12369
12899
  function objectRecord(value) {
12370
12900
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
12371
12901
  }
@@ -12379,18 +12909,18 @@ function numberValue(value) {
12379
12909
  }
12380
12910
  return null;
12381
12911
  }
12382
- function stringValue2(value) {
12912
+ function stringValue3(value) {
12383
12913
  return typeof value === "string" ? value : "";
12384
12914
  }
12385
12915
  function useStableEventCallback(callback) {
12386
- const callbackRef = useRef17(callback);
12916
+ const callbackRef = useRef18(callback);
12387
12917
  useLayoutEffect(() => {
12388
12918
  callbackRef.current = callback;
12389
12919
  }, [callback]);
12390
12920
  return useCallback25((...args) => callbackRef.current(...args), []);
12391
12921
  }
12392
12922
  function useOptionalStableEventCallback(callback) {
12393
- const callbackRef = useRef17(callback);
12923
+ const callbackRef = useRef18(callback);
12394
12924
  useLayoutEffect(() => {
12395
12925
  callbackRef.current = callback;
12396
12926
  }, [callback]);
@@ -13017,10 +13547,10 @@ import {
13017
13547
  memo as memo4,
13018
13548
  useCallback as useCallback40,
13019
13549
  useMemo as useMemo30,
13020
- useRef as useRef31,
13550
+ useRef as useRef32,
13021
13551
  useState as useState24
13022
13552
  } from "react";
13023
- import { Tooltip as Tooltip6, TooltipContent as TooltipContent6, TooltipTrigger as TooltipTrigger6 } from "@tutti-os/ui-system";
13553
+ import { Tooltip as Tooltip5, TooltipContent as TooltipContent5, TooltipTrigger as TooltipTrigger5 } from "@tutti-os/ui-system";
13024
13554
 
13025
13555
  // agent-gui/agentGuiNode/model/agentGuiProviderRailOrder.ts
13026
13556
  var AGENT_GUI_PROVIDER_RAIL_PREFERENCES_STORAGE_KEY = "agent-gui:provider-rail-preferences";
@@ -14568,13 +15098,7 @@ var AgentGUIHeroAgentCarousel = class extends Component {
14568
15098
  };
14569
15099
 
14570
15100
  // agent-gui/agentGuiNode/AgentSessionChrome.tsx
14571
- import {
14572
- Button as Button2,
14573
- Tooltip,
14574
- TooltipContent,
14575
- TooltipProvider,
14576
- TooltipTrigger
14577
- } from "@tutti-os/ui-system";
15101
+ import { Button as Button2 } from "@tutti-os/ui-system";
14578
15102
 
14579
15103
  // app/renderer/components/icons/CastIcon.tsx
14580
15104
  import {
@@ -14582,7 +15106,7 @@ import {
14582
15106
  useCallback as useCallback27,
14583
15107
  useEffect as useEffect17,
14584
15108
  useImperativeHandle,
14585
- useRef as useRef18
15109
+ useRef as useRef19
14586
15110
  } from "react";
14587
15111
  import {
14588
15112
  motion as motion2,
@@ -14613,7 +15137,7 @@ var CastIcon = forwardRef2(
14613
15137
  }, ref) => {
14614
15138
  const controls = useAnimation();
14615
15139
  const reduceMotion = useReducedMotion();
14616
- const isControlledRef = useRef18(false);
15140
+ const isControlledRef = useRef19(false);
14617
15141
  const startAnimation = useCallback27(() => {
14618
15142
  if (reduceMotion) {
14619
15143
  return;
@@ -14729,7 +15253,6 @@ var styles2 = {
14729
15253
  chromeCardSuccess: "agent-gui-chrome__card--success",
14730
15254
  chromeIcon: "agent-gui-chrome__icon",
14731
15255
  chromeMessageSlot: "agent-gui-chrome__message-slot",
14732
- chromeMessageTooltip: "agent-gui-chrome__message-tooltip",
14733
15256
  chromeInlineActions: "agent-gui-chrome__inline-actions",
14734
15257
  chromeNoticeDescription: "agent-gui-chrome__notice-description",
14735
15258
  chromeNoticeMessage: "agent-gui-chrome__notice-message",
@@ -14766,24 +15289,6 @@ function LoadingEllipsis() {
14766
15289
  /* @__PURE__ */ jsx19("span", {})
14767
15290
  ] });
14768
15291
  }
14769
- function ChromeMessageTooltip({
14770
- message,
14771
- children
14772
- }) {
14773
- "use memo";
14774
- return /* @__PURE__ */ jsx19(TooltipProvider, { delayDuration: 250, children: /* @__PURE__ */ jsxs12(Tooltip, { children: [
14775
- /* @__PURE__ */ jsx19(TooltipTrigger, { asChild: true, children }),
14776
- /* @__PURE__ */ jsx19(
14777
- TooltipContent,
14778
- {
14779
- className: AgentGUIChrome_styles_default.chromeMessageTooltip,
14780
- side: "top",
14781
- sideOffset: 6,
14782
- children: message
14783
- }
14784
- )
14785
- ] }) });
14786
- }
14787
15292
  function AgentChromeNotice({
14788
15293
  tone,
14789
15294
  title,
@@ -14839,7 +15344,15 @@ function AgentSessionChrome({
14839
15344
  }
14840
15345
  return /* @__PURE__ */ jsxs12("div", { className: AgentGUIChrome_styles_default.sessionChrome, children: [
14841
15346
  visibleAuth ? /* @__PURE__ */ jsx19("section", { className: cn(AgentGUIChrome_styles_default.chromeCard, AgentGUIChrome_styles_default.chromeCardWarning), children: /* @__PURE__ */ jsxs12("div", { className: AgentGUIChrome_styles_default.chromeMetaRow, children: [
14842
- /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: /* @__PURE__ */ jsx19(ChromeMessageTooltip, { message: visibleAuth.message, children: /* @__PURE__ */ jsx19("p", { className: AgentGUIChrome_styles_default.chromeMessage, tabIndex: 0, children: visibleAuth.message }) }) }),
15347
+ /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.chromeMessageSlot, children: /* @__PURE__ */ jsx19(
15348
+ "p",
15349
+ {
15350
+ className: AgentGUIChrome_styles_default.chromeMessage,
15351
+ tabIndex: 0,
15352
+ title: visibleAuth.message,
15353
+ children: visibleAuth.message
15354
+ }
15355
+ ) }),
14843
15356
  /* @__PURE__ */ jsxs12("div", { className: AgentGUIChrome_styles_default.chromeInlineActions, children: [
14844
15357
  onAuthLogin ? /* @__PURE__ */ jsx19(
14845
15358
  Button2,
@@ -14902,18 +15415,19 @@ function AgentSessionChrome({
14902
15415
  size: 16
14903
15416
  }
14904
15417
  ) : null,
14905
- /* @__PURE__ */ jsx19(ChromeMessageTooltip, { message: recoveryMessage, children: /* @__PURE__ */ jsx19(
15418
+ /* @__PURE__ */ jsx19(
14906
15419
  "p",
14907
15420
  {
14908
15421
  className: AgentGUIChrome_styles_default.chromeMessage,
14909
15422
  "aria-label": visibleRecovery.kind === "activating" ? recoveryMessage : void 0,
14910
15423
  tabIndex: 0,
15424
+ title: recoveryMessage,
14911
15425
  children: visibleRecovery.kind === "activating" ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
14912
15426
  /* @__PURE__ */ jsx19("span", { className: "tsh-inline-loading-label", children: activatingMessage.label }),
14913
15427
  activatingMessage.ellipsis ? /* @__PURE__ */ jsx19(LoadingEllipsis, {}) : null
14914
15428
  ] }) : recoveryMessage
14915
15429
  }
14916
- ) })
15430
+ )
14917
15431
  ] }),
14918
15432
  /* @__PURE__ */ jsx19("div", { className: AgentGUIChrome_styles_default.chromeInlineActions, children: visibleRecovery.kind === "resume-unavailable" ? /* @__PURE__ */ jsx19(
14919
15433
  Button2,
@@ -14943,7 +15457,7 @@ function AgentSessionChrome({
14943
15457
  }
14944
15458
 
14945
15459
  // agent-gui/agentGuiNode/AgentComposer.tsx
14946
- import { useEffect as useEffect28, useRef as useRef29, useState as useState20 } from "react";
15460
+ import { useEffect as useEffect28, useRef as useRef30, useState as useState20 } from "react";
14947
15461
  import { repairMentionPaletteHighlight } from "@tutti-os/ui-rich-text/at-panel";
14948
15462
 
14949
15463
  // agent-gui/agentGuiNode/AgentSlashStatusPanel.tsx
@@ -15074,7 +15588,7 @@ function AgentSlashStatusPanel({
15074
15588
  import { flushSync as flushSync3 } from "react-dom";
15075
15589
  import {
15076
15590
  useCallback as useCallback28,
15077
- useRef as useRef19
15591
+ useRef as useRef20
15078
15592
  } from "react";
15079
15593
 
15080
15594
  // agent-gui/agentGuiNode/composer/composerDraftUtils.ts
@@ -15136,7 +15650,7 @@ function agentComposerDevConsoleDiagnosticSinkEnabled(runtime) {
15136
15650
 
15137
15651
  // agent-gui/agentGuiNode/composer/useComposerDraftAttachments.ts
15138
15652
  function useStableEventCallback2(callback) {
15139
- const callbackRef = useRef19(callback);
15653
+ const callbackRef = useRef20(callback);
15140
15654
  callbackRef.current = callback;
15141
15655
  return useCallback28((...args) => callbackRef.current(...args), []);
15142
15656
  }
@@ -15192,7 +15706,7 @@ function useComposerDraftAttachments({
15192
15706
  return next;
15193
15707
  }
15194
15708
  );
15195
- const openReferencesForEntityRef = useRef19(null);
15709
+ const openReferencesForEntityRef = useRef20(null);
15196
15710
  const handleDraftChange = useStableEventCallback2(
15197
15711
  (nextDraft) => {
15198
15712
  if (isGoalModeActive) {
@@ -16194,7 +16708,7 @@ import {
16194
16708
  import {
16195
16709
  useCallback as useCallback29,
16196
16710
  useEffect as useEffect18,
16197
- useRef as useRef20,
16711
+ useRef as useRef21,
16198
16712
  useState as useState10
16199
16713
  } from "react";
16200
16714
  import {
@@ -16242,14 +16756,14 @@ function AgentUsageChip({
16242
16756
  }) {
16243
16757
  "use memo";
16244
16758
  const [usagePopoverOpen, setUsagePopoverOpen] = useState10(false);
16245
- const usagePopoverHoverTimerRef = useRef20(null);
16246
- const usagePopoverContentRef = useRef20(null);
16759
+ const usagePopoverHoverTimerRef = useRef21(null);
16760
+ const usagePopoverContentRef = useRef21(null);
16247
16761
  const clampedPercent = Math.max(0, Math.min(100, percentUsed));
16248
16762
  const chipLabel = labels.usageChipLabel({ percent: clampedPercent });
16249
16763
  const showTokens = usedTokens !== null && totalTokens !== null;
16250
16764
  const usageLevel = agentUsageChipLevel(clampedPercent);
16251
16765
  const ringColor = agentUsageRingColor(usageLevel);
16252
- const usagePopoverCloseTimerRef = useRef20(null);
16766
+ const usagePopoverCloseTimerRef = useRef21(null);
16253
16767
  const clearUsagePopoverHoverTimer = useCallback29(() => {
16254
16768
  if (usagePopoverHoverTimerRef.current) {
16255
16769
  clearTimeout(usagePopoverHoverTimerRef.current);
@@ -16675,23 +17189,10 @@ function useMentionPaletteFrame(inputShellRef, showFileMentionPalette) {
16675
17189
  import {
16676
17190
  useCallback as useCallback31,
16677
17191
  useMemo as useMemo23,
16678
- useRef as useRef21
17192
+ useRef as useRef22
16679
17193
  } from "react";
16680
-
16681
- // agent-gui/agentGuiNode/model/composerModeSelection.ts
16682
- function permissionModeSelectionPatch(permissionModeId, options) {
16683
- return options.clearsPlanMode ? { permissionModeId, planMode: false } : { permissionModeId };
16684
- }
16685
- function resolvePermissionModeControlsDisabled(options) {
16686
- if (options.changeDuringTurnSupported) {
16687
- return options.isSubmittingPrompt;
16688
- }
16689
- return options.isSendingTurn || options.isSubmittingPrompt || options.showStopButton;
16690
- }
16691
-
16692
- // agent-gui/agentGuiNode/composer/useComposerSlashActions.ts
16693
17194
  function useStableEventCallback3(callback) {
16694
- const callbackRef = useRef21(callback);
17195
+ const callbackRef = useRef22(callback);
16695
17196
  callbackRef.current = callback;
16696
17197
  return useCallback31((...args) => callbackRef.current(...args), []);
16697
17198
  }
@@ -17004,25 +17505,24 @@ function useComposerSlashActions(input) {
17004
17505
  }
17005
17506
  }
17006
17507
  setIsPaletteOpen(false);
17007
- const submitContent = agentComposerDraftToPromptContent({
17508
+ const submission = projectAgentComposerDraftSubmission({
17008
17509
  draft: nextDraftContent,
17009
17510
  skills: availableSkills
17010
17511
  });
17011
- const submitDisplayPrompt = agentComposerDraftDisplayPrompt(nextDraftContent);
17012
17512
  if (options?.guidance === true) {
17013
17513
  if (!onSubmitGuidance) {
17014
17514
  return;
17015
17515
  }
17016
- if (submitDisplayPrompt) {
17017
- onSubmitGuidance(submitContent, submitDisplayPrompt);
17516
+ if (submission.displayPrompt) {
17517
+ onSubmitGuidance(submission.content, submission.displayPrompt);
17018
17518
  } else {
17019
- onSubmitGuidance(submitContent);
17519
+ onSubmitGuidance(submission.content);
17020
17520
  }
17021
17521
  } else {
17022
- if (submitDisplayPrompt) {
17023
- onSubmit(submitContent, submitDisplayPrompt);
17522
+ if (submission.displayPrompt) {
17523
+ onSubmit(submission.content, submission.displayPrompt);
17024
17524
  } else {
17025
- onSubmit(submitContent);
17525
+ onSubmit(submission.content);
17026
17526
  }
17027
17527
  }
17028
17528
  }
@@ -17113,7 +17613,7 @@ function useComposerSlashActions(input) {
17113
17613
  import {
17114
17614
  useCallback as useCallback32,
17115
17615
  useEffect as useEffect19,
17116
- useRef as useRef22
17616
+ useRef as useRef23
17117
17617
  } from "react";
17118
17618
  import {
17119
17619
  createMentionPaletteStateAdapter,
@@ -17133,7 +17633,7 @@ function isAgentRichTextImeComposing(event) {
17133
17633
 
17134
17634
  // agent-gui/agentGuiNode/composer/useComposerMentionActions.ts
17135
17635
  function useStableEventCallback4(callback) {
17136
- const callbackRef = useRef22(callback);
17636
+ const callbackRef = useRef23(callback);
17137
17637
  callbackRef.current = callback;
17138
17638
  return useCallback32((...args) => callbackRef.current(...args), []);
17139
17639
  }
@@ -18337,18 +18837,17 @@ import { createPortal as createPortal4 } from "react-dom";
18337
18837
  import {
18338
18838
  Popover as Popover3,
18339
18839
  PopoverAnchor as PopoverAnchor2,
18340
- Spinner as Spinner5,
18341
- Tooltip as Tooltip5,
18342
- TooltipContent as TooltipContent5,
18343
- TooltipProvider as TooltipProvider4,
18344
- TooltipTrigger as TooltipTrigger5
18840
+ Tooltip as Tooltip4,
18841
+ TooltipContent as TooltipContent4,
18842
+ TooltipProvider as TooltipProvider3,
18843
+ TooltipTrigger as TooltipTrigger4
18345
18844
  } from "@tutti-os/ui-system";
18346
18845
 
18347
18846
  // agent-gui/agentGuiNode/AgentQueuedPromptPanel.tsx
18348
18847
  import {
18349
18848
  Component as Component2,
18350
18849
  useLayoutEffect as useLayoutEffect4,
18351
- useRef as useRef23,
18850
+ useRef as useRef24,
18352
18851
  useState as useState15
18353
18852
  } from "react";
18354
18853
  import { ChevronRight } from "lucide-react";
@@ -18357,10 +18856,10 @@ import {
18357
18856
  DropdownMenuContent as DropdownMenuContent2,
18358
18857
  DropdownMenuItem,
18359
18858
  DropdownMenuTrigger as DropdownMenuTrigger2,
18360
- Tooltip as Tooltip2,
18361
- TooltipContent as TooltipContent2,
18362
- TooltipProvider as TooltipProvider2,
18363
- TooltipTrigger as TooltipTrigger2,
18859
+ Tooltip,
18860
+ TooltipContent,
18861
+ TooltipProvider,
18862
+ TooltipTrigger,
18364
18863
  useTextOverflow
18365
18864
  } from "@tutti-os/ui-system";
18366
18865
  import { extractPlainTextFromContent } from "@tutti-os/ui-rich-text";
@@ -18609,9 +19108,9 @@ function AgentQueuedPromptText({
18609
19108
  )
18610
19109
  }
18611
19110
  );
18612
- return /* @__PURE__ */ jsx24(TooltipProvider2, { delayDuration: 200, children: /* @__PURE__ */ jsxs17(Tooltip2, { children: [
18613
- /* @__PURE__ */ jsx24(TooltipTrigger2, { asChild: true, children: content }),
18614
- overflowing && title ? /* @__PURE__ */ jsx24(TooltipContent2, { className: "max-w-[min(520px,calc(100vw-32px))] whitespace-pre-wrap text-left [overflow-wrap:anywhere]", children: title }) : null
19111
+ return /* @__PURE__ */ jsx24(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs17(Tooltip, { children: [
19112
+ /* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: content }),
19113
+ overflowing && title ? /* @__PURE__ */ jsx24(TooltipContent, { className: "max-w-[min(520px,calc(100vw-32px))] whitespace-pre-wrap text-left [overflow-wrap:anywhere]", children: title }) : null
18615
19114
  ] }) });
18616
19115
  }
18617
19116
  function AgentQueuedPromptPanel({
@@ -18630,9 +19129,9 @@ function AgentQueuedPromptPanel({
18630
19129
  "use memo";
18631
19130
  const runtime = useOptionalAgentActivityRuntime();
18632
19131
  const [isExpanded, setIsExpanded] = useState15(false);
18633
- const singlePromptTextRef = useRef23(null);
18634
- const queuedPromptListRef = useRef23(null);
18635
- const pointerHandledEditPromptIdRef = useRef23(null);
19132
+ const singlePromptTextRef = useRef24(null);
19133
+ const queuedPromptListRef = useRef24(null);
19134
+ const pointerHandledEditPromptIdRef = useRef24(null);
18636
19135
  const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState15(false);
18637
19136
  const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState15(280);
18638
19137
  const singlePromptHasImages = queuedPrompts.length === 1 && queuedPromptImages(queuedPrompts[0]).length > 0;
@@ -18886,9 +19385,9 @@ import {
18886
19385
  SelectContent,
18887
19386
  SelectItem,
18888
19387
  SelectTrigger,
18889
- Tooltip as Tooltip3,
18890
- TooltipContent as TooltipContent3,
18891
- TooltipTrigger as TooltipTrigger3,
19388
+ Tooltip as Tooltip2,
19389
+ TooltipContent as TooltipContent2,
19390
+ TooltipTrigger as TooltipTrigger2,
18892
19391
  cn as cn3
18893
19392
  } from "@tutti-os/ui-system";
18894
19393
 
@@ -19482,12 +19981,6 @@ function AgentPermissionModeDropdown({
19482
19981
  })
19483
19982
  );
19484
19983
  };
19485
- const handleSelectedItemPointerDown = (event, permissionModeId) => {
19486
- if (selectDisabled || event.button !== 0 || event.ctrlKey) {
19487
- return;
19488
- }
19489
- applyPermissionModeId(permissionModeId);
19490
- };
19491
19984
  const trigger = /* @__PURE__ */ jsxs19(
19492
19985
  "button",
19493
19986
  {
@@ -19536,9 +20029,9 @@ function AgentPermissionModeDropdown({
19536
20029
  // The trigger is disabled while loading, so pointer events never reach
19537
20030
  // it. Target the tooltip at a focusable wrapper span (Radix's pattern
19538
20031
  // for disabled triggers) so hover/focus reliably surfaces the hint.
19539
- /* @__PURE__ */ jsxs19(Tooltip3, { children: [
19540
- /* @__PURE__ */ jsx26(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx26("span", { className: "inline-flex", tabIndex: 0, children: selectTrigger }) }),
19541
- /* @__PURE__ */ jsx26(TooltipContent3, { side: "top", children: labels.loadingOptions })
20032
+ /* @__PURE__ */ jsxs19(Tooltip2, { children: [
20033
+ /* @__PURE__ */ jsx26(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx26("span", { className: "inline-flex", tabIndex: 0, children: selectTrigger }) }),
20034
+ /* @__PURE__ */ jsx26(TooltipContent2, { side: "top", children: labels.loadingOptions })
19542
20035
  ] })
19543
20036
  ) : selectTrigger,
19544
20037
  isSelectOpen ? /* @__PURE__ */ jsx26(
@@ -19558,7 +20051,6 @@ function AgentPermissionModeDropdown({
19558
20051
  value: option.value,
19559
20052
  disabled: selectDisabled,
19560
20053
  className: cn3(AgentGUINode_styles_default.composerMenuItem, "group/composer-option"),
19561
- onPointerDown: (event) => handleSelectedItemPointerDown(event, option.value),
19562
20054
  children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-1.5", children: [
19563
20055
  /* @__PURE__ */ jsx26("span", { className: "min-w-0 truncate", children: option.label }),
19564
20056
  option.description ? /* @__PURE__ */ jsx26(
@@ -19655,9 +20147,9 @@ function ComposerOptionInfoTooltip({
19655
20147
  if (!tooltipsEnabled) {
19656
20148
  return trigger;
19657
20149
  }
19658
- return /* @__PURE__ */ jsxs19(Tooltip3, { children: [
19659
- /* @__PURE__ */ jsx26(TooltipTrigger3, { asChild: true, children: trigger }),
19660
- /* @__PURE__ */ jsx26(TooltipContent3, { side: "right", className: "max-w-[240px] whitespace-normal", children: description })
20150
+ return /* @__PURE__ */ jsxs19(Tooltip2, { children: [
20151
+ /* @__PURE__ */ jsx26(TooltipTrigger2, { asChild: true, children: trigger }),
20152
+ /* @__PURE__ */ jsx26(TooltipContent2, { side: "right", className: "max-w-[240px] whitespace-normal", children: description })
19661
20153
  ] });
19662
20154
  }
19663
20155
  function resolvePermissionModeTriggerTone(value) {
@@ -19738,9 +20230,9 @@ function AgentModelReasoningDropdown({
19738
20230
  // The trigger is disabled while loading, so pointer events never reach
19739
20231
  // it. Target the tooltip at a focusable wrapper span (Radix's pattern
19740
20232
  // for disabled triggers) so hover/focus reliably surfaces the hint.
19741
- /* @__PURE__ */ jsxs19(Tooltip3, { children: [
19742
- /* @__PURE__ */ jsx26(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx26("span", { className: "inline-flex", tabIndex: 0, children: /* @__PURE__ */ jsx26(DropdownMenuTrigger3, { asChild: true, disabled: menuDisabled, children: trigger }) }) }),
19743
- /* @__PURE__ */ jsx26(TooltipContent3, { side: "top", children: labels.loadingOptions })
20233
+ /* @__PURE__ */ jsxs19(Tooltip2, { children: [
20234
+ /* @__PURE__ */ jsx26(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx26("span", { className: "inline-flex", tabIndex: 0, children: /* @__PURE__ */ jsx26(DropdownMenuTrigger3, { asChild: true, disabled: menuDisabled, children: trigger }) }) }),
20235
+ /* @__PURE__ */ jsx26(TooltipContent2, { side: "top", children: labels.loadingOptions })
19744
20236
  ] })
19745
20237
  ) : /* @__PURE__ */ jsx26(DropdownMenuTrigger3, { asChild: true, disabled: menuDisabled, children: trigger }),
19746
20238
  /* @__PURE__ */ jsxs19(
@@ -19943,12 +20435,12 @@ function ComposerModelOptionTooltip({
19943
20435
  if (!tooltipsEnabled || !option.tooltip) {
19944
20436
  return children;
19945
20437
  }
19946
- return /* @__PURE__ */ jsxs19(Tooltip3, { children: [
19947
- /* @__PURE__ */ jsx26(TooltipTrigger3, { asChild: true, children: cloneElement(children, {
20438
+ return /* @__PURE__ */ jsxs19(Tooltip2, { children: [
20439
+ /* @__PURE__ */ jsx26(TooltipTrigger2, { asChild: true, children: cloneElement(children, {
19948
20440
  "data-agent-model-option-tooltip-trigger": "true"
19949
20441
  }) }),
19950
20442
  /* @__PURE__ */ jsxs19(
19951
- TooltipContent3,
20443
+ TooltipContent2,
19952
20444
  {
19953
20445
  side: "right",
19954
20446
  align: "start",
@@ -19972,7 +20464,7 @@ import {
19972
20464
  useCallback as useCallback36,
19973
20465
  useEffect as useEffect24,
19974
20466
  useMemo as useMemo26,
19975
- useRef as useRef25,
20467
+ useRef as useRef26,
19976
20468
  useState as useState17
19977
20469
  } from "react";
19978
20470
  import { useEditor } from "@tiptap/react";
@@ -20500,7 +20992,7 @@ function useAgentRichTextEditorHandle(input) {
20500
20992
  // agent-gui/agentGuiNode/agentRichText/AgentRichTextEditorSurface.tsx
20501
20993
  import {
20502
20994
  useCallback as useCallback35,
20503
- useRef as useRef24
20995
+ useRef as useRef25
20504
20996
  } from "react";
20505
20997
  import { createPortal as createPortal2 } from "react-dom";
20506
20998
  import { EditorContent } from "@tiptap/react";
@@ -20588,7 +21080,7 @@ function AgentRichTextContextMenuButton({
20588
21080
  label,
20589
21081
  onSelect
20590
21082
  }) {
20591
- const selectionStartedRef = useRef24(false);
21083
+ const selectionStartedRef = useRef25(false);
20592
21084
  const select = useCallback35(() => {
20593
21085
  if (disabled || selectionStartedRef.current) return;
20594
21086
  selectionStartedRef.current = true;
@@ -20690,34 +21182,34 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
20690
21182
  }, ref) {
20691
21183
  "use memo";
20692
21184
  const { t } = useTranslation();
20693
- const lastEmittedPromptRef = useRef25(value);
20694
- const editorRef = useRef25(null);
20695
- const onChangeRef = useRef25(onChange);
20696
- const onFocusRef = useRef25(onFocus);
20697
- const onUserContentChangeRef = useRef25(onUserContentChange);
20698
- const pendingFocusMethodRef = useRef25(null);
20699
- const onSubmitRef = useRef25(onSubmit);
20700
- const onSubmitGuidanceRef = useRef25(onSubmitGuidance);
20701
- const onKeyDownForPaletteRef = useRef25(onKeyDownForPalette);
20702
- const onFileMentionSuggestionChangeRef = useRef25(
21185
+ const lastEmittedPromptRef = useRef26(value);
21186
+ const editorRef = useRef26(null);
21187
+ const onChangeRef = useRef26(onChange);
21188
+ const onFocusRef = useRef26(onFocus);
21189
+ const onUserContentChangeRef = useRef26(onUserContentChange);
21190
+ const pendingFocusMethodRef = useRef26(null);
21191
+ const onSubmitRef = useRef26(onSubmit);
21192
+ const onSubmitGuidanceRef = useRef26(onSubmitGuidance);
21193
+ const onKeyDownForPaletteRef = useRef26(onKeyDownForPalette);
21194
+ const onFileMentionSuggestionChangeRef = useRef26(
20703
21195
  onFileMentionSuggestionChange
20704
21196
  );
20705
- const onFileMentionSuggestionKeyDownRef = useRef25(
21197
+ const onFileMentionSuggestionKeyDownRef = useRef26(
20706
21198
  onFileMentionSuggestionKeyDown
20707
21199
  );
20708
- const onLinkClickRef = useRef25(onLinkClick);
20709
- const onPromptImagesUnsupportedRef = useRef25(onPromptImagesUnsupported);
20710
- const onPasteImagesRef = useRef25(onPasteImages);
20711
- const onPasteLargeTextRef = useRef25(onPasteLargeText);
20712
- const onDropFilesRef = useRef25(onDropFiles);
20713
- const promptImagesSupportedRef = useRef25(promptImagesSupported);
20714
- const getReferenceForFileRef = useRef25(getReferenceForFile);
20715
- const placeholderRef = useRef25(placeholder);
20716
- const removeMentionLabelRef = useRef25(removeMentionLabel);
20717
- const availableSkillsRef = useRef25(availableSkills);
20718
- const availableCapabilitiesRef = useRef25(availableCapabilities);
20719
- const suppressPastedAtSuggestionRef = useRef25(false);
20720
- const scrollFrameRef = useRef25(null);
21200
+ const onLinkClickRef = useRef26(onLinkClick);
21201
+ const onPromptImagesUnsupportedRef = useRef26(onPromptImagesUnsupported);
21202
+ const onPasteImagesRef = useRef26(onPasteImages);
21203
+ const onPasteLargeTextRef = useRef26(onPasteLargeText);
21204
+ const onDropFilesRef = useRef26(onDropFiles);
21205
+ const promptImagesSupportedRef = useRef26(promptImagesSupported);
21206
+ const getReferenceForFileRef = useRef26(getReferenceForFile);
21207
+ const placeholderRef = useRef26(placeholder);
21208
+ const removeMentionLabelRef = useRef26(removeMentionLabel);
21209
+ const availableSkillsRef = useRef26(availableSkills);
21210
+ const availableCapabilitiesRef = useRef26(availableCapabilities);
21211
+ const suppressPastedAtSuggestionRef = useRef26(false);
21212
+ const scrollFrameRef = useRef26(null);
20721
21213
  const [contextMenu, setContextMenu] = useState17(null);
20722
21214
  const closeContextMenu = useCallback36(() => {
20723
21215
  setContextMenu(null);
@@ -21302,7 +21794,7 @@ function AgentReferenceProvenanceFilterControl({
21302
21794
  }
21303
21795
 
21304
21796
  // agent-gui/agentGuiNode/AgentSlashCommandPalette.tsx
21305
- import { Fragment as Fragment8, useEffect as useEffect25, useRef as useRef26 } from "react";
21797
+ import { Fragment as Fragment8, useEffect as useEffect25, useRef as useRef27 } from "react";
21306
21798
  import { Spinner as Spinner3 } from "@tutti-os/ui-system";
21307
21799
  import {
21308
21800
  Globe,
@@ -21349,7 +21841,7 @@ function AgentSlashCommandPalette({
21349
21841
  onSelectSkill
21350
21842
  }) {
21351
21843
  "use memo";
21352
- const highlightedOptionRef = useRef26(null);
21844
+ const highlightedOptionRef = useRef27(null);
21353
21845
  useEffect25(() => {
21354
21846
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
21355
21847
  }, [highlightedIndex]);
@@ -21550,7 +22042,7 @@ function slashPaletteEntryIcon(entry) {
21550
22042
  }
21551
22043
 
21552
22044
  // agent-gui/agentGuiNode/AgentReviewPickerPanel.tsx
21553
- import { useCallback as useCallback37, useEffect as useEffect26, useMemo as useMemo27, useRef as useRef27, useState as useState18 } from "react";
22045
+ import { useCallback as useCallback37, useEffect as useEffect26, useMemo as useMemo27, useRef as useRef28, useState as useState18 } from "react";
21554
22046
  import { menuItemClassName } from "@tutti-os/ui-system";
21555
22047
 
21556
22048
  // agent-gui/agentGuiNode/AgentReviewBranchController.ts
@@ -21668,9 +22160,9 @@ function AgentReviewPickerPanel({
21668
22160
  const [stage, setStage] = useState18("root");
21669
22161
  const [query, setQuery] = useState18("");
21670
22162
  const [highlightedIndex, setHighlightedIndex] = useState18(0);
21671
- const searchInputRef = useRef27(null);
21672
- const highlightedOptionRef = useRef27(null);
21673
- const reviewBranchControllerRef = useRef27(
22163
+ const searchInputRef = useRef28(null);
22164
+ const highlightedOptionRef = useRef28(null);
22165
+ const reviewBranchControllerRef = useRef28(
21674
22166
  null
21675
22167
  );
21676
22168
  const [branchState, setBranchState] = useState18({
@@ -21915,7 +22407,7 @@ import {
21915
22407
  useEffect as useEffect27,
21916
22408
  useLayoutEffect as useLayoutEffect5,
21917
22409
  useMemo as useMemo28,
21918
- useRef as useRef28,
22410
+ useRef as useRef29,
21919
22411
  useState as useState19
21920
22412
  } from "react";
21921
22413
  import { createPortal as createPortal3 } from "react-dom";
@@ -22062,7 +22554,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
22062
22554
  surfaceRef,
22063
22555
  testId
22064
22556
  }, forwardedRef) {
22065
- const localSurfaceRef = useRef28(null);
22557
+ const localSurfaceRef = useRef29(null);
22066
22558
  const frame = useComposerAnchoredMenuFrame({
22067
22559
  anchorRef,
22068
22560
  maxHeight,
@@ -22328,10 +22820,10 @@ import {
22328
22820
  SelectContent as SelectContent2,
22329
22821
  SelectItem as SelectItem2,
22330
22822
  SelectTrigger as SelectTrigger2,
22331
- Tooltip as Tooltip4,
22332
- TooltipContent as TooltipContent4,
22333
- TooltipProvider as TooltipProvider3,
22334
- TooltipTrigger as TooltipTrigger4
22823
+ Tooltip as Tooltip3,
22824
+ TooltipContent as TooltipContent3,
22825
+ TooltipProvider as TooltipProvider2,
22826
+ TooltipTrigger as TooltipTrigger3
22335
22827
  } from "@tutti-os/ui-system";
22336
22828
 
22337
22829
  // app/renderer/assets/icons/add-lined-bold.svg
@@ -22383,8 +22875,8 @@ function ComposerFooter({
22383
22875
  return /* @__PURE__ */ jsx34(Fragment10, { children: /* @__PURE__ */ jsxs24("div", { className: AgentGUINode_styles_default.composerFooter, children: [
22384
22876
  /* @__PURE__ */ jsxs24("div", { className: composerStyles.footerGroup, children: [
22385
22877
  /* @__PURE__ */ jsxs24("div", { className: "inline-flex shrink-0 items-center gap-1", children: [
22386
- previewMode ? /* @__PURE__ */ jsx34(TooltipProvider3, { delayDuration: 120, children: /* @__PURE__ */ jsxs24(Tooltip4, { children: [
22387
- /* @__PURE__ */ jsx34(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx34(
22878
+ previewMode ? /* @__PURE__ */ jsx34(TooltipProvider2, { delayDuration: 120, children: /* @__PURE__ */ jsxs24(Tooltip3, { children: [
22879
+ /* @__PURE__ */ jsx34(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx34(
22388
22880
  "button",
22389
22881
  {
22390
22882
  type: "button",
@@ -22403,50 +22895,47 @@ function ComposerFooter({
22403
22895
  )
22404
22896
  }
22405
22897
  ) }),
22406
- /* @__PURE__ */ jsx34(TooltipContent4, { side: "top", children: labels.addContent })
22407
- ] }) }) : /* @__PURE__ */ jsx34(TooltipProvider3, { delayDuration: 120, children: /* @__PURE__ */ jsxs24(Tooltip4, { children: [
22408
- /* @__PURE__ */ jsx34(
22409
- Select2,
22410
- {
22411
- open: false,
22412
- value: workspaceReferenceSelectValue,
22413
- disabled: !onRequestWorkspaceReferences || composerControlsHardDisabled,
22414
- onOpenChange: (isOpen) => {
22415
- if (isOpen) {
22416
- void handleWorkspaceReferencePicker();
22417
- }
22418
- },
22419
- onValueChange: (nextValue) => {
22420
- if (nextValue === workspaceReferenceOptionValue) {
22421
- void handleWorkspaceReferencePicker();
22422
- }
22423
- },
22424
- children: /* @__PURE__ */ jsx34(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx34(
22425
- SelectTrigger2,
22426
- {
22427
- size: "sm",
22428
- "aria-label": labels.referenceWorkspaceFiles,
22429
- title: labels.referenceWorkspaceFiles,
22430
- className: cn(
22431
- AgentGUINode_styles_default.composerMenuTrigger,
22432
- AgentGUINode_styles_default.composerReferenceTrigger,
22433
- "group w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden"
22434
- ),
22435
- children: /* @__PURE__ */ jsx34(
22436
- AgentComposerMaskIcon,
22437
- {
22438
- iconUrl: add_lined_bold_default,
22439
- marker: "reference-add"
22440
- }
22441
- )
22442
- }
22443
- ) })
22444
- }
22445
- ),
22446
- /* @__PURE__ */ jsx34(TooltipContent4, { side: "top", children: labels.addContent })
22447
- ] }) }),
22448
- /* @__PURE__ */ jsx34(TooltipProvider3, { delayDuration: 120, children: /* @__PURE__ */ jsxs24(Tooltip4, { children: [
22449
- /* @__PURE__ */ jsx34(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx34(
22898
+ /* @__PURE__ */ jsx34(TooltipContent3, { side: "top", children: labels.addContent })
22899
+ ] }) }) : /* @__PURE__ */ jsx34(
22900
+ Select2,
22901
+ {
22902
+ open: false,
22903
+ value: workspaceReferenceSelectValue,
22904
+ disabled: !onRequestWorkspaceReferences || composerControlsHardDisabled,
22905
+ onOpenChange: (isOpen) => {
22906
+ if (isOpen) {
22907
+ void handleWorkspaceReferencePicker();
22908
+ }
22909
+ },
22910
+ onValueChange: (nextValue) => {
22911
+ if (nextValue === workspaceReferenceOptionValue) {
22912
+ void handleWorkspaceReferencePicker();
22913
+ }
22914
+ },
22915
+ children: /* @__PURE__ */ jsx34(
22916
+ SelectTrigger2,
22917
+ {
22918
+ size: "sm",
22919
+ "aria-label": labels.referenceWorkspaceFiles,
22920
+ title: labels.addContent,
22921
+ className: cn(
22922
+ AgentGUINode_styles_default.composerMenuTrigger,
22923
+ AgentGUINode_styles_default.composerReferenceTrigger,
22924
+ "group w-auto justify-center text-[var(--agent-gui-text-secondary)] [&>svg:last-child]:hidden"
22925
+ ),
22926
+ children: /* @__PURE__ */ jsx34(
22927
+ AgentComposerMaskIcon,
22928
+ {
22929
+ iconUrl: add_lined_bold_default,
22930
+ marker: "reference-add"
22931
+ }
22932
+ )
22933
+ }
22934
+ )
22935
+ }
22936
+ ),
22937
+ /* @__PURE__ */ jsx34(TooltipProvider2, { delayDuration: 120, children: /* @__PURE__ */ jsxs24(Tooltip3, { children: [
22938
+ /* @__PURE__ */ jsx34(TooltipTrigger3, { asChild: true, children: /* @__PURE__ */ jsx34(
22450
22939
  "button",
22451
22940
  {
22452
22941
  type: "button",
@@ -22478,99 +22967,96 @@ function ComposerFooter({
22478
22967
  )
22479
22968
  }
22480
22969
  ) }),
22481
- /* @__PURE__ */ jsx34(TooltipContent4, { side: "top", children: labels.mentionPalette })
22970
+ /* @__PURE__ */ jsx34(TooltipContent3, { side: "top", children: labels.mentionPalette })
22482
22971
  ] }) })
22483
22972
  ] }),
22484
- showHandoffSelect ? /* @__PURE__ */ jsx34(TooltipProvider3, { children: /* @__PURE__ */ jsxs24(Tooltip4, { children: [
22485
- /* @__PURE__ */ jsxs24(
22486
- Select2,
22487
- {
22488
- value: HANDOFF_SELECT_IDLE_VALUE,
22489
- disabled: handoffDisabled,
22490
- onValueChange: (nextTargetId) => {
22491
- const target = handoffMenuTargets.find(
22492
- (candidate) => candidate.targetId === nextTargetId
22493
- );
22494
- if (!target || target.disabled === true) {
22495
- return;
22973
+ showHandoffSelect ? /* @__PURE__ */ jsxs24(
22974
+ Select2,
22975
+ {
22976
+ value: HANDOFF_SELECT_IDLE_VALUE,
22977
+ disabled: handoffDisabled,
22978
+ onValueChange: (nextTargetId) => {
22979
+ const target = handoffMenuTargets.find(
22980
+ (candidate) => candidate.targetId === nextTargetId
22981
+ );
22982
+ if (!target || target.disabled === true) {
22983
+ return;
22984
+ }
22985
+ onHandoffConversation?.(target);
22986
+ },
22987
+ children: [
22988
+ /* @__PURE__ */ jsx34(
22989
+ SelectTrigger2,
22990
+ {
22991
+ size: "sm",
22992
+ "aria-label": effectiveHandoffLabel,
22993
+ title: labels.handoffConversationTooltip,
22994
+ onBlur: () => {
22995
+ setIsHandoffIconPlaying(false);
22996
+ },
22997
+ onFocus: () => {
22998
+ setIsHandoffIconPlaying(true);
22999
+ },
23000
+ onMouseEnter: () => {
23001
+ setIsHandoffIconPlaying(true);
23002
+ },
23003
+ onMouseLeave: () => {
23004
+ setIsHandoffIconPlaying(false);
23005
+ },
23006
+ className: cn(
23007
+ AgentGUINode_styles_default.composerMenuTrigger,
23008
+ AgentGUINode_styles_default.composerProviderSelect,
23009
+ AgentGUINode_styles_default.composerHandoffTrigger,
23010
+ "w-auto max-w-[180px] [&>svg:last-child]:hidden"
23011
+ ),
23012
+ children: /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1.5", children: [
23013
+ /* @__PURE__ */ jsx34(
23014
+ AgentComposerHandoffIcon,
23015
+ {
23016
+ disabled: handoffDisabled,
23017
+ isPlaying: isHandoffIconPlaying
23018
+ }
23019
+ ),
23020
+ /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: effectiveHandoffLabel })
23021
+ ] })
22496
23022
  }
22497
- onHandoffConversation?.(target);
22498
- },
22499
- children: [
22500
- /* @__PURE__ */ jsx34(TooltipTrigger4, { asChild: true, children: /* @__PURE__ */ jsx34(
22501
- SelectTrigger2,
22502
- {
22503
- size: "sm",
22504
- "aria-label": effectiveHandoffLabel,
22505
- title: labels.handoffConversationTooltip,
22506
- onBlur: () => {
22507
- setIsHandoffIconPlaying(false);
22508
- },
22509
- onFocus: () => {
22510
- setIsHandoffIconPlaying(true);
22511
- },
22512
- onMouseEnter: () => {
22513
- setIsHandoffIconPlaying(true);
22514
- },
22515
- onMouseLeave: () => {
22516
- setIsHandoffIconPlaying(false);
23023
+ ),
23024
+ /* @__PURE__ */ jsx34(
23025
+ SelectContent2,
23026
+ {
23027
+ align: "start",
23028
+ className: cn(
23029
+ AgentGUINode_styles_default.composerMenuContent,
23030
+ AgentGUINode_styles_default.composerHandoffMenuContent,
23031
+ "min-w-[190px]"
23032
+ ),
23033
+ "aria-label": effectiveHandoffMenuLabel,
23034
+ children: handoffMenuTargets.map((target) => /* @__PURE__ */ jsx34(
23035
+ SelectItem2,
23036
+ {
23037
+ value: target.targetId,
23038
+ className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
23039
+ disabled: target.disabled === true,
23040
+ children: /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1.5", children: [
23041
+ /* @__PURE__ */ jsx34(
23042
+ "img",
23043
+ {
23044
+ alt: "",
23045
+ "aria-hidden": "true",
23046
+ className: "size-4 shrink-0 rounded-[4px]",
23047
+ src: resolveComposerProviderTargetIconUrl(target)
23048
+ }
23049
+ ),
23050
+ /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: target.label })
23051
+ ] })
22517
23052
  },
22518
- className: cn(
22519
- AgentGUINode_styles_default.composerMenuTrigger,
22520
- AgentGUINode_styles_default.composerProviderSelect,
22521
- AgentGUINode_styles_default.composerHandoffTrigger,
22522
- "w-auto max-w-[180px] [&>svg:last-child]:hidden"
22523
- ),
22524
- children: /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22525
- /* @__PURE__ */ jsx34(
22526
- AgentComposerHandoffIcon,
22527
- {
22528
- disabled: handoffDisabled,
22529
- isPlaying: isHandoffIconPlaying
22530
- }
22531
- ),
22532
- /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: effectiveHandoffLabel })
22533
- ] })
22534
- }
22535
- ) }),
22536
- /* @__PURE__ */ jsx34(
22537
- SelectContent2,
22538
- {
22539
- align: "start",
22540
- className: cn(
22541
- AgentGUINode_styles_default.composerMenuContent,
22542
- AgentGUINode_styles_default.composerHandoffMenuContent,
22543
- "min-w-[190px]"
22544
- ),
22545
- "aria-label": effectiveHandoffMenuLabel,
22546
- children: handoffMenuTargets.map((target) => /* @__PURE__ */ jsx34(
22547
- SelectItem2,
22548
- {
22549
- value: target.targetId,
22550
- className: cn(AgentGUINode_styles_default.composerMenuItem, "gap-2"),
22551
- disabled: target.disabled === true,
22552
- children: /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1.5", children: [
22553
- /* @__PURE__ */ jsx34(
22554
- "img",
22555
- {
22556
- alt: "",
22557
- "aria-hidden": "true",
22558
- className: "size-4 shrink-0 rounded-[4px]",
22559
- src: resolveComposerProviderTargetIconUrl(target)
22560
- }
22561
- ),
22562
- /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: target.label })
22563
- ] })
22564
- },
22565
- `${target.provider}:${target.targetId}`
22566
- ))
22567
- }
22568
- )
22569
- ]
22570
- }
22571
- ),
22572
- /* @__PURE__ */ jsx34(TooltipContent4, { side: "top", children: labels.handoffConversationTooltip })
22573
- ] }) }) : showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs24(
23053
+ `${target.provider}:${target.targetId}`
23054
+ ))
23055
+ }
23056
+ )
23057
+ ]
23058
+ }
23059
+ ) : showProviderSelect && selectedProviderSwitchTarget ? /* @__PURE__ */ jsxs24(
22574
23060
  Select2,
22575
23061
  {
22576
23062
  value: selectedProviderSwitchTarget.targetId,
@@ -22825,7 +23311,6 @@ function AgentComposerView(input) {
22825
23311
  previewMode = false,
22826
23312
  layoutMode = "dock",
22827
23313
  providerSelectLabel = "",
22828
- backgroundAgentStatusText = null,
22829
23314
  labels,
22830
23315
  workspaceUserProjectI18n,
22831
23316
  isSubmittingPrompt,
@@ -23020,16 +23505,6 @@ function AgentComposerView(input) {
23020
23505
  ),
23021
23506
  "data-edge-glow": showEdgeGlow ? "true" : void 0,
23022
23507
  children: [
23023
- backgroundAgentStatusText ? /* @__PURE__ */ jsx35(
23024
- AgentChromeNotice,
23025
- {
23026
- tone: "muted",
23027
- role: "status",
23028
- testId: "agent-gui-composer-background-agent-status",
23029
- title: backgroundAgentStatusText,
23030
- icon: /* @__PURE__ */ jsx35(Spinner5, { className: "h-3.5 w-3.5" })
23031
- }
23032
- ) : null,
23033
23508
  input.isSelectedProjectMissing ? /* @__PURE__ */ jsx35(
23034
23509
  AgentChromeNotice,
23035
23510
  {
@@ -23348,10 +23823,10 @@ function AgentComposerView(input) {
23348
23823
  {
23349
23824
  className: AgentGUINode_styles_default.composerPromptTips,
23350
23825
  "data-testid": "agent-gui-prompt-tips",
23351
- children: !previewMode && input.isPromptTipOverflowing && promptTipNode ? /* @__PURE__ */ jsx35(TooltipProvider4, { delayDuration: 0, children: /* @__PURE__ */ jsxs25(Tooltip5, { children: [
23352
- /* @__PURE__ */ jsx35(TooltipTrigger5, { asChild: true, children: promptTipNode }),
23826
+ children: !previewMode && input.isPromptTipOverflowing && promptTipNode ? /* @__PURE__ */ jsx35(TooltipProvider3, { delayDuration: 0, children: /* @__PURE__ */ jsxs25(Tooltip4, { children: [
23827
+ /* @__PURE__ */ jsx35(TooltipTrigger4, { asChild: true, children: promptTipNode }),
23353
23828
  /* @__PURE__ */ jsx35(
23354
- TooltipContent5,
23829
+ TooltipContent4,
23355
23830
  {
23356
23831
  align: "end",
23357
23832
  className: AgentGUINode_styles_default.composerPromptTipTooltip,
@@ -23485,11 +23960,11 @@ function AgentComposer(props) {
23485
23960
  const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState20(false);
23486
23961
  const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState20(false);
23487
23962
  const slashStatusAgentSessionId = slashStatus?.agentSessionId ?? null;
23488
- const previousSlashStatusAgentSessionIdRef = useRef29(
23963
+ const previousSlashStatusAgentSessionIdRef = useRef30(
23489
23964
  slashStatusAgentSessionId
23490
23965
  );
23491
23966
  const selectedProjectPath = composerSettings.selectedProjectPath?.trim() ?? "";
23492
- const previousSelectedProjectPathRef = useRef29(selectedProjectPath);
23967
+ const previousSelectedProjectPathRef = useRef30(selectedProjectPath);
23493
23968
  const [mentionSearchState, setMentionSearchState] = useState20({
23494
23969
  status: "idle",
23495
23970
  query: "",
@@ -23499,26 +23974,26 @@ function AgentComposer(props) {
23499
23974
  groups: [],
23500
23975
  error: null
23501
23976
  });
23502
- const composerRef = useRef29(null);
23503
- const inputShellRef = useRef29(null);
23504
- const promptInputAreaRef = useRef29(null);
23505
- const paletteContentRef = useRef29(null);
23506
- const draftPromptRef = useRef29(draftPrompt);
23507
- const draftImagesRef = useRef29(draftImages);
23508
- const draftFilesRef = useRef29(draftFiles);
23509
- const draftLargeTextsRef = useRef29(draftLargeTexts);
23510
- const draftByScopeKeyRef = useRef29({
23977
+ const composerRef = useRef30(null);
23978
+ const inputShellRef = useRef30(null);
23979
+ const promptInputAreaRef = useRef30(null);
23980
+ const paletteContentRef = useRef30(null);
23981
+ const draftPromptRef = useRef30(draftPrompt);
23982
+ const draftImagesRef = useRef30(draftImages);
23983
+ const draftFilesRef = useRef30(draftFiles);
23984
+ const draftLargeTextsRef = useRef30(draftLargeTexts);
23985
+ const draftByScopeKeyRef = useRef30({
23511
23986
  [draftScopeKey]: draftContent
23512
23987
  });
23513
23988
  draftByScopeKeyRef.current[draftScopeKey] = draftContent;
23514
- const promptTipRef = useRef29(null);
23515
- const mentionControllerRef = useRef29(
23989
+ const promptTipRef = useRef30(null);
23990
+ const mentionControllerRef = useRef30(
23516
23991
  null
23517
23992
  );
23518
- const editorHandleRef = useRef29(null);
23519
- const wasActiveRef = useRef29(isActive);
23520
- const lastComposerFocusRequestRef = useRef29(null);
23521
- const autoMentionHighlightedKeyRef = useRef29(null);
23993
+ const editorHandleRef = useRef30(null);
23994
+ const wasActiveRef = useRef30(isActive);
23995
+ const lastComposerFocusRequestRef = useRef30(null);
23996
+ const autoMentionHighlightedKeyRef = useRef30(null);
23522
23997
  const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState20(false);
23523
23998
  const [dockComposerInputHeight, setDockComposerInputHeight] = useState20(
23524
23999
  DOCK_COMPOSER_INPUT_MIN_HEIGHT2
@@ -24690,7 +25165,7 @@ function EmptyHeroTitle({
24690
25165
 
24691
25166
  // agent-gui/agentGuiNode/view/AgentGUIProviderManagerDialog.tsx
24692
25167
  import {
24693
- useRef as useRef30,
25168
+ useRef as useRef31,
24694
25169
  useState as useState22
24695
25170
  } from "react";
24696
25171
  import { CircleMinus, CirclePlus } from "lucide-react";
@@ -24732,12 +25207,12 @@ function AgentGUIProviderManagerDialog({
24732
25207
  null
24733
25208
  );
24734
25209
  const [dragPreview, setDragPreview] = useState22(null);
24735
- const dragStateRef = useRef30(null);
24736
- const dragPreviewRef = useRef30(null);
25210
+ const dragStateRef = useRef31(null);
25211
+ const dragPreviewRef = useRef31(null);
24737
25212
  const [longPressTargetId, setLongPressTargetId] = useState22(
24738
25213
  null
24739
25214
  );
24740
- const longPressOriginRef = useRef30(null);
25215
+ const longPressOriginRef = useRef31(null);
24741
25216
  const finalAvailableAgent = availableTargets.length === 1;
24742
25217
  const showRunningAgentBlocked = (targetId) => {
24743
25218
  const target = targets.find((candidate) => candidate.targetId === targetId);
@@ -25336,7 +25811,7 @@ var AgentGUIProviderRail = memo4(function AgentGUIProviderRail2({
25336
25811
  preferences: providerRailPreferences
25337
25812
  } = useAgentGUIProviderRailPreferences();
25338
25813
  const [dragState, setDragState] = useState24(null);
25339
- const dragStateRef = useRef31(null);
25814
+ const dragStateRef = useRef32(null);
25340
25815
  const setProviderRailDragState = useCallback40(
25341
25816
  (nextDragState) => {
25342
25817
  dragStateRef.current = nextDragState;
@@ -25796,9 +26271,9 @@ var AgentGUIProviderRail = memo4(function AgentGUIProviderRail2({
25796
26271
  if (previewMode) {
25797
26272
  return tile;
25798
26273
  }
25799
- return /* @__PURE__ */ jsxs30(Tooltip6, { children: [
25800
- /* @__PURE__ */ jsx41(TooltipTrigger6, { asChild: true, children: tile }),
25801
- /* @__PURE__ */ jsx41(TooltipContent6, { side: "right", sideOffset: -4, children: label })
26274
+ return /* @__PURE__ */ jsxs30(Tooltip5, { children: [
26275
+ /* @__PURE__ */ jsx41(TooltipTrigger5, { asChild: true, children: tile }),
26276
+ /* @__PURE__ */ jsx41(TooltipContent5, { side: "right", sideOffset: -4, children: label })
25802
26277
  ] }, `${target.provider}:${target.targetId}:tooltip`);
25803
26278
  })
25804
26279
  ]
@@ -25819,7 +26294,7 @@ import {
25819
26294
  useEffect as useEffect30,
25820
26295
  useLayoutEffect as useLayoutEffect6,
25821
26296
  useMemo as useMemo32,
25822
- useRef as useRef33,
26297
+ useRef as useRef34,
25823
26298
  useState as useState27
25824
26299
  } from "react";
25825
26300
  import {
@@ -25948,279 +26423,10 @@ function AgentConversationListSkeleton({
25948
26423
  );
25949
26424
  }
25950
26425
 
25951
- // agent-gui/agentGuiNode/agentGuiNodeViewConversation.tsx
25952
- import { Spinner as Spinner6 } from "@tutti-os/ui-system";
25953
- import { AskLinedIcon } from "@tutti-os/ui-system/icons";
25954
- import { jsx as jsx44 } from "react/jsx-runtime";
25955
- function ConversationMeta({
25956
- item,
25957
- nowMs,
25958
- labels
25959
- }) {
25960
- "use memo";
25961
- const kind = conversationMetaKind(item);
25962
- if (kind === "loading") {
25963
- return /* @__PURE__ */ jsx44(
25964
- "span",
25965
- {
25966
- className: AgentGUINode_styles_default.conversationMeta,
25967
- "data-kind": kind,
25968
- "data-testid": `agent-gui-conversation-meta-${item.id}`,
25969
- children: /* @__PURE__ */ jsx44(LoadingGlyph, {})
25970
- }
25971
- );
25972
- }
25973
- if (kind === "waiting") {
25974
- return /* @__PURE__ */ jsx44(
25975
- "span",
25976
- {
25977
- className: AgentGUINode_styles_default.conversationMeta,
25978
- "data-kind": kind,
25979
- "data-testid": `agent-gui-conversation-meta-${item.id}`,
25980
- children: /* @__PURE__ */ jsx44(
25981
- AskLinedIcon,
25982
- {
25983
- "aria-hidden": "true",
25984
- className: AgentGUINode_styles_default.conversationStatusGlyph
25985
- }
25986
- )
25987
- }
25988
- );
25989
- }
25990
- if (kind === "failed") {
25991
- return /* @__PURE__ */ jsx44(
25992
- "span",
25993
- {
25994
- className: AgentGUINode_styles_default.conversationMeta,
25995
- "data-kind": kind,
25996
- "data-testid": `agent-gui-conversation-meta-${item.id}`,
25997
- children: /* @__PURE__ */ jsx44(AttentionGlyph, {})
25998
- }
25999
- );
26000
- }
26001
- if (kind === "unread-complete") {
26002
- return /* @__PURE__ */ jsx44(
26003
- "span",
26004
- {
26005
- className: AgentGUINode_styles_default.conversationMeta,
26006
- "data-kind": kind,
26007
- "data-testid": `agent-gui-conversation-meta-${item.id}`,
26008
- children: /* @__PURE__ */ jsx44("span", { className: AgentGUINode_styles_default.conversationUnreadLamp, "aria-hidden": "true" })
26009
- }
26010
- );
26011
- }
26012
- return /* @__PURE__ */ jsx44(
26013
- "span",
26014
- {
26015
- className: AgentGUINode_styles_default.conversationMeta,
26016
- "data-kind": kind,
26017
- "data-testid": `agent-gui-conversation-meta-${item.id}`,
26018
- children: /* @__PURE__ */ jsx44("span", { className: AgentGUINode_styles_default.conversationTime, children: formatConversationRelativeTime(
26019
- resolveAgentGUIConversationSortTimeUnixMs(item),
26020
- nowMs,
26021
- labels
26022
- ) })
26023
- }
26024
- );
26025
- }
26026
- function groupConversations(conversations, labels, userProjects = [], options = {}) {
26027
- const groups = [];
26028
- const pinned = conversations.filter((conversation) => (conversation.pinnedAtUnixMs ?? 0) > 0).sort(
26029
- (left, right) => (right.pinnedAtUnixMs ?? 0) - (left.pinnedAtUnixMs ?? 0) || resolveAgentGUIConversationSortTimeUnixMs(right) - resolveAgentGUIConversationSortTimeUnixMs(left) || left.id.localeCompare(right.id)
26030
- );
26031
- if (pinned.length > 0) {
26032
- groups.push({
26033
- id: "pinned",
26034
- kind: "pinned",
26035
- label: labels.sectionPinned,
26036
- project: null,
26037
- items: pinned
26038
- });
26039
- }
26040
- const projectGroups = /* @__PURE__ */ new Map();
26041
- const normalizedProjectPathByPath = /* @__PURE__ */ new Map();
26042
- const normalizeProjectPath = (path) => normalizeConversationProjectPathCached(path, normalizedProjectPathByPath);
26043
- userProjects.forEach((project, projectOrder) => {
26044
- const normalizedPath = normalizeProjectPath(project.path);
26045
- const sectionId = conversationProjectSectionId(project, normalizedPath);
26046
- if (projectGroups.has(sectionId)) {
26047
- return;
26048
- }
26049
- projectGroups.set(sectionId, {
26050
- id: sectionId,
26051
- kind: "project",
26052
- label: project.label,
26053
- project,
26054
- items: [],
26055
- projectOrder,
26056
- sectionOrder: 0,
26057
- projectUpdatedAtUnixMs: resolveConversationProjectUpdatedAtUnixMs(project)
26058
- });
26059
- });
26060
- if (options.includeEmptyConversations) {
26061
- projectGroups.set("conversations", {
26062
- id: "conversations",
26063
- kind: "conversations",
26064
- label: labels.sectionConversations,
26065
- project: null,
26066
- items: [],
26067
- projectOrder: Number.MAX_SAFE_INTEGER,
26068
- sectionOrder: 1,
26069
- projectUpdatedAtUnixMs: 0
26070
- });
26071
- }
26072
- for (const conversation of conversations) {
26073
- if ((conversation.pinnedAtUnixMs ?? 0) > 0) {
26074
- continue;
26075
- }
26076
- if (!conversation.project) {
26077
- const existing2 = projectGroups.get("conversations");
26078
- if (existing2) {
26079
- existing2.items.push(conversation);
26080
- continue;
26081
- }
26082
- projectGroups.set("conversations", {
26083
- id: "conversations",
26084
- kind: "conversations",
26085
- label: labels.sectionConversations,
26086
- project: null,
26087
- items: [conversation],
26088
- projectOrder: Number.MAX_SAFE_INTEGER,
26089
- sectionOrder: 1,
26090
- projectUpdatedAtUnixMs: 0
26091
- });
26092
- continue;
26093
- }
26094
- const normalizedPath = normalizeProjectPath(conversation.project.path);
26095
- const sectionId = conversationProjectSectionId(
26096
- conversation.project,
26097
- normalizedPath
26098
- );
26099
- const existing = projectGroups.get(sectionId);
26100
- if (existing) {
26101
- existing.items.push(conversation);
26102
- continue;
26103
- }
26104
- projectGroups.set(sectionId, {
26105
- id: sectionId,
26106
- kind: "project",
26107
- label: conversation.project.label,
26108
- project: conversation.project,
26109
- items: [conversation],
26110
- projectOrder: Number.MAX_SAFE_INTEGER - 1,
26111
- sectionOrder: 0,
26112
- projectUpdatedAtUnixMs: resolveConversationProjectUpdatedAtUnixMs(
26113
- conversation.project
26114
- )
26115
- });
26116
- }
26117
- groups.push(
26118
- ...[...projectGroups.values()].filter(
26119
- (group) => options.includeEmptyConversations || group.items.length > 0
26120
- ).sort(
26121
- (left, right) => left.sectionOrder - right.sectionOrder || right.projectUpdatedAtUnixMs - left.projectUpdatedAtUnixMs || left.projectOrder - right.projectOrder || left.label.localeCompare(right.label) || left.id.localeCompare(right.id)
26122
- ).map(
26123
- ({
26124
- projectOrder: _projectOrder,
26125
- sectionOrder: _sectionOrder,
26126
- projectUpdatedAtUnixMs: _projectUpdatedAtUnixMs,
26127
- ...group
26128
- }) => group
26129
- )
26130
- );
26131
- return groups;
26132
- }
26133
- function resolveConversationProjectUpdatedAtUnixMs(project) {
26134
- if (!project) {
26135
- return 0;
26136
- }
26137
- return project.updatedAtUnixMs ?? project.lastUsedAtUnixMs ?? project.createdAtUnixMs ?? 0;
26138
- }
26139
- function normalizeConversationProjectPathCached(path, normalizedPathByPath) {
26140
- const cached = normalizedPathByPath.get(path);
26141
- if (cached !== void 0) {
26142
- return cached;
26143
- }
26144
- const normalized = normalizeAgentGUIProjectPath(path);
26145
- normalizedPathByPath.set(path, normalized);
26146
- return normalized;
26147
- }
26148
- function conversationProjectSectionId(project, normalizedPath) {
26149
- return project.sectionKey?.trim() || `project:${normalizedPath}`;
26150
- }
26151
- function conversationMetaKind(conversation) {
26152
- if (conversation.status === "working") {
26153
- return "loading";
26154
- }
26155
- if (conversation.status === "waiting") {
26156
- return "waiting";
26157
- }
26158
- if (conversation.status === "failed") {
26159
- return "failed";
26160
- }
26161
- if (conversation.hasUnreadCompletion) {
26162
- return "unread-complete";
26163
- }
26164
- return "time";
26165
- }
26166
- function formatConversationRelativeTime(updatedAtUnixMs, nowMs, labels) {
26167
- const elapsedMs = Math.max(0, nowMs - updatedAtUnixMs);
26168
- const elapsedMinutes = Math.floor(elapsedMs / (60 * 1e3));
26169
- if (elapsedMinutes < 1) {
26170
- return labels.relativeTimeJustNow;
26171
- }
26172
- if (elapsedMinutes < 60) {
26173
- return labels.relativeTimeMinutes(elapsedMinutes);
26174
- }
26175
- const elapsedHours = Math.floor(elapsedMinutes / 60);
26176
- if (elapsedHours < 24) {
26177
- return labels.relativeTimeHours(elapsedHours);
26178
- }
26179
- const elapsedDays = Math.floor(elapsedHours / 24);
26180
- if (elapsedDays < 30) {
26181
- return labels.relativeTimeDays(elapsedDays);
26182
- }
26183
- const elapsedMonths = Math.floor(elapsedDays / 30);
26184
- if (elapsedMonths < 12) {
26185
- return labels.relativeTimeMonths(elapsedMonths);
26186
- }
26187
- return labels.relativeTimeYears(Math.floor(elapsedDays / 365));
26188
- }
26189
- function LoadingGlyph() {
26190
- "use memo";
26191
- return /* @__PURE__ */ jsx44(
26192
- Spinner6,
26193
- {
26194
- className: AgentGUINode_styles_default.conversationStatusGlyph,
26195
- size: 14,
26196
- style: { color: "var(--text-secondary)" },
26197
- strokeWidth: 2.25,
26198
- trackColor: "color-mix(in srgb, currentColor 24%, transparent)",
26199
- testId: "agent-gui-conversation-spinner"
26200
- }
26201
- );
26202
- }
26203
- function AttentionGlyph() {
26204
- "use memo";
26205
- return /* @__PURE__ */ jsx44(
26206
- "svg",
26207
- {
26208
- viewBox: "0 0 24 24",
26209
- fill: "none",
26210
- "aria-hidden": "true",
26211
- className: AgentGUINode_styles_default.conversationStatusGlyph,
26212
- children: /* @__PURE__ */ jsx44(
26213
- "path",
26214
- {
26215
- d: "M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM12.5 15C12.7761 15 13 15.2239 13 15.5V16.5C13 16.7761 12.7761 17 12.5 17H11.5C11.2239 17 11 16.7761 11 16.5V15.5C11 15.2239 11.2239 15 11.5 15H12.5ZM12.5 7C12.7761 7 13 7.22386 13 7.5V13.5C13 13.7761 12.7761 14 12.5 14H11.5C11.2239 14 11 13.7761 11 13.5V7.5C11 7.22386 11.2239 7 11.5 7H12.5Z",
26216
- fill: "currentColor"
26217
- }
26218
- )
26219
- }
26220
- );
26221
- }
26222
-
26223
26426
  // agent-gui/agentGuiNode/model/agentGuiConversationRail.ts
26427
+ function isConversationRailInitialLoadPending(input) {
26428
+ return input.runtimeSectionsEnabled && input.pending && input.sections === null;
26429
+ }
26224
26430
  function canonicalConversationRailSummaries(conversations) {
26225
26431
  return conversations.filter(
26226
26432
  (conversation) => conversation.projectionSource !== "pending_activation"
@@ -26237,12 +26443,13 @@ function projectConversationRailSectionsWithTransientConversations(input) {
26237
26443
  const loadedIds = new Set(
26238
26444
  input.sections.flatMap((section) => section.items.map((item) => item.id))
26239
26445
  );
26240
- const transientSections = groupConversations(
26241
- transientConversations.filter(
26446
+ const transientSections = projectConversationsByExactRailSectionKey({
26447
+ conversations: transientConversations.filter(
26242
26448
  (conversation) => !loadedIds.has(conversation.id)
26243
26449
  ),
26244
- input.labels
26245
- );
26450
+ labels: input.labels,
26451
+ sections: input.sections
26452
+ });
26246
26453
  if (transientSections.length === 0) {
26247
26454
  return input.sections;
26248
26455
  }
@@ -26301,44 +26508,33 @@ function projectConversationRailSectionsWithActiveConversation(input) {
26301
26508
  if (!activeConversation || !activeConversationId) {
26302
26509
  return { activeOverlay: null, sections: input.sections };
26303
26510
  }
26304
- const loadedSection = input.sections.find(
26305
- (section) => section.items.some((item) => item.id === activeConversationId)
26511
+ const activeSectionId = conversationRailSectionId(activeConversation);
26512
+ if (!activeSectionId) {
26513
+ return { activeOverlay: null, sections: input.sections };
26514
+ }
26515
+ const matchingSection = input.sections.find(
26516
+ (section) => section.id === activeSectionId
26306
26517
  );
26307
- if (loadedSection) {
26518
+ if (matchingSection) {
26308
26519
  return {
26309
26520
  activeOverlay: {
26310
- conversation: loadedSection.kind === "project" ? conversationWithRailProject(
26521
+ conversation: matchingSection.kind === "project" ? conversationWithRailProject(
26311
26522
  activeConversation,
26312
- loadedSection.project
26523
+ matchingSection.project
26313
26524
  ) : activeConversation,
26314
- sectionId: loadedSection.id
26525
+ sectionId: matchingSection.id
26315
26526
  },
26316
26527
  sections: input.sections
26317
26528
  };
26318
26529
  }
26319
- const activeSection = groupConversations(
26320
- [activeConversation],
26530
+ const activeSection = createExactConversationRailSection(
26531
+ activeConversation,
26321
26532
  input.labels
26322
- )[0];
26533
+ );
26323
26534
  if (!activeSection) {
26324
26535
  return { activeOverlay: null, sections: input.sections };
26325
26536
  }
26326
- const matchingSectionIndex = input.sections.findIndex(
26327
- (section) => section.id === activeSection.id
26328
- );
26329
- if (matchingSectionIndex >= 0) {
26330
- const matchingSection = input.sections[matchingSectionIndex];
26331
- return {
26332
- activeOverlay: {
26333
- conversation: matchingSection?.kind === "project" ? conversationWithRailProject(
26334
- activeConversation,
26335
- matchingSection.project
26336
- ) : activeConversation,
26337
- sectionId: activeSection.id
26338
- },
26339
- sections: input.sections
26340
- };
26341
- }
26537
+ const projectedConversation = activeSection.items[0] ?? activeConversation;
26342
26538
  const transientSection = { ...activeSection, items: [] };
26343
26539
  let sections;
26344
26540
  if (activeSection.kind === "pinned") {
@@ -26361,7 +26557,7 @@ function projectConversationRailSectionsWithActiveConversation(input) {
26361
26557
  }
26362
26558
  return {
26363
26559
  activeOverlay: {
26364
- conversation: activeConversation,
26560
+ conversation: projectedConversation,
26365
26561
  sectionId: activeSection.id
26366
26562
  },
26367
26563
  sections
@@ -26370,6 +26566,139 @@ function projectConversationRailSectionsWithActiveConversation(input) {
26370
26566
  function conversationWithRailProject(conversation, project) {
26371
26567
  return conversationProjectsRenderEqual2(conversation.project, project) ? conversation : { ...conversation, project };
26372
26568
  }
26569
+ function conversationRailSectionId(conversation) {
26570
+ if ((conversation.pinnedAtUnixMs ?? 0) > 0) {
26571
+ return "pinned";
26572
+ }
26573
+ const sectionKey = conversation.railSectionKey?.trim() ?? "";
26574
+ return sectionKey || null;
26575
+ }
26576
+ function createExactConversationRailSection(conversation, labels) {
26577
+ const sectionId = conversationRailSectionId(conversation);
26578
+ if (!sectionId) {
26579
+ return null;
26580
+ }
26581
+ if (sectionId === "pinned") {
26582
+ return {
26583
+ id: sectionId,
26584
+ kind: "pinned",
26585
+ label: labels.sectionPinned,
26586
+ project: null,
26587
+ items: [{ ...conversation, project: null }]
26588
+ };
26589
+ }
26590
+ if (sectionId === "conversations") {
26591
+ return {
26592
+ id: sectionId,
26593
+ kind: "conversations",
26594
+ label: labels.sectionConversations,
26595
+ project: null,
26596
+ items: [{ ...conversation, project: null }]
26597
+ };
26598
+ }
26599
+ const project = conversation.project;
26600
+ if (project?.sectionKey?.trim() !== sectionId) {
26601
+ return null;
26602
+ }
26603
+ return {
26604
+ id: sectionId,
26605
+ kind: "project",
26606
+ label: project.label,
26607
+ project,
26608
+ items: [conversationWithRailProject(conversation, project)]
26609
+ };
26610
+ }
26611
+ function projectConversationsByExactRailSectionKey(input) {
26612
+ const sectionTemplates = new Map(
26613
+ input.sections.map((section) => [section.id, section])
26614
+ );
26615
+ const projected = /* @__PURE__ */ new Map();
26616
+ if (input.includeEmptySections) {
26617
+ for (const section of input.sections) {
26618
+ if (section.kind === "pinned") continue;
26619
+ projected.set(section.id, { ...section, items: [] });
26620
+ }
26621
+ }
26622
+ for (const conversation of input.conversations) {
26623
+ const sectionId = conversationRailSectionId(conversation);
26624
+ if (!sectionId) continue;
26625
+ const template = sectionTemplates.get(sectionId);
26626
+ const section = template ?? createExactConversationRailSection(conversation, input.labels);
26627
+ if (!section) continue;
26628
+ const projectedConversation = section.kind === "project" ? conversationWithRailProject(conversation, section.project) : conversation.project ? { ...conversation, project: null } : conversation;
26629
+ const existing = projected.get(sectionId);
26630
+ if (existing) {
26631
+ existing.items.push(projectedConversation);
26632
+ continue;
26633
+ }
26634
+ projected.set(sectionId, {
26635
+ ...section,
26636
+ items: [projectedConversation]
26637
+ });
26638
+ }
26639
+ const sorted = new Map(
26640
+ [...projected].map(([id, section]) => [
26641
+ id,
26642
+ {
26643
+ ...section,
26644
+ items: section.kind === "pinned" ? sortPinnedConversations(section.items) : sortConversations(section.items)
26645
+ }
26646
+ ])
26647
+ );
26648
+ const result = [];
26649
+ const append = (id) => {
26650
+ const section = sorted.get(id);
26651
+ if (!section) return;
26652
+ result.push(section);
26653
+ sorted.delete(id);
26654
+ };
26655
+ append("pinned");
26656
+ for (const section of input.sections) {
26657
+ if (section.kind === "pinned" || section.kind === "conversations") {
26658
+ continue;
26659
+ }
26660
+ append(section.id);
26661
+ }
26662
+ [...sorted.values()].filter((section) => section.kind === "project").sort((left, right) => left.id.localeCompare(right.id)).forEach((section) => append(section.id));
26663
+ for (const section of input.sections) {
26664
+ if (section.kind === "conversations") append(section.id);
26665
+ }
26666
+ append("conversations");
26667
+ [...sorted.keys()].sort().forEach(append);
26668
+ return result;
26669
+ }
26670
+ function projectConversationRailSectionsByExactKey(input) {
26671
+ const seen = /* @__PURE__ */ new Set();
26672
+ const sections = input.userProjects.flatMap(
26673
+ (project) => {
26674
+ const sectionKey = project.sectionKey?.trim() ?? "";
26675
+ if (!sectionKey || seen.has(sectionKey)) return [];
26676
+ seen.add(sectionKey);
26677
+ return [
26678
+ {
26679
+ id: sectionKey,
26680
+ kind: "project",
26681
+ label: project.label,
26682
+ project,
26683
+ items: []
26684
+ }
26685
+ ];
26686
+ }
26687
+ );
26688
+ sections.push({
26689
+ id: "conversations",
26690
+ kind: "conversations",
26691
+ label: input.labels.sectionConversations,
26692
+ project: null,
26693
+ items: []
26694
+ });
26695
+ return projectConversationsByExactRailSectionKey({
26696
+ conversations: input.conversations,
26697
+ labels: input.labels,
26698
+ sections,
26699
+ includeEmptySections: input.includeEmptySections
26700
+ });
26701
+ }
26373
26702
  function planRuntimeRailMembershipRefresh(input) {
26374
26703
  const previousPendingIds = new Set(
26375
26704
  input.previous.flatMap((conversation) => {
@@ -26488,12 +26817,17 @@ function projectConversationRailMemberships(input) {
26488
26817
  items: section.sessionIds.flatMap((id) => {
26489
26818
  const conversation = conversationsById.get(id);
26490
26819
  if (!conversation) return [];
26820
+ const exactSectionId = conversationRailSectionId(conversation);
26821
+ if (exactSectionId !== section.id) return [];
26491
26822
  return [
26492
26823
  section.kind === "project" ? { ...conversation, project: section.project } : { ...conversation, project: null }
26493
26824
  ];
26494
26825
  })
26495
26826
  }));
26496
26827
  }
26828
+ function projectConversationRailSearchSections(input) {
26829
+ return projectConversationsByExactRailSectionKey(input);
26830
+ }
26497
26831
  function stabilizeConversationSections(previous, next) {
26498
26832
  if (!previous) {
26499
26833
  return [...next];
@@ -26581,10 +26915,60 @@ function comparePinnedConversations(left, right) {
26581
26915
  return (right.pinnedAtUnixMs ?? 0) - (left.pinnedAtUnixMs ?? 0) || (right.sortTimeUnixMs ?? right.updatedAtUnixMs) - (left.sortTimeUnixMs ?? left.updatedAtUnixMs) || left.id.localeCompare(right.id);
26582
26916
  }
26583
26917
  function conversationSummariesRenderEqual2(left, right) {
26584
- return left.id === right.id && left.agentTargetId === right.agentTargetId && left.provider === right.provider && left.title === right.title && left.titleFallback === right.titleFallback && left.status === right.status && left.cwd === right.cwd && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sortTimeUnixMs === right.sortTimeUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.projectionSource === right.projectionSource && left.isImported === right.isImported && left.hasUnreadCompletion === right.hasUnreadCompletion && left.unreadCompletionKey === right.unreadCompletionKey && conversationProjectsRenderEqual2(left.project, right.project);
26918
+ return left.id === right.id && left.agentTargetId === right.agentTargetId && left.provider === right.provider && left.title === right.title && left.titleLeadingMentionKind === right.titleLeadingMentionKind && left.titleFallback === right.titleFallback && left.status === right.status && left.cwd === right.cwd && left.railSectionKey === right.railSectionKey && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sortTimeUnixMs === right.sortTimeUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.projectionSource === right.projectionSource && left.isImported === right.isImported && left.hasUnreadCompletion === right.hasUnreadCompletion && left.unreadCompletionKey === right.unreadCompletionKey && conversationProjectsRenderEqual2(left.project, right.project);
26585
26919
  }
26586
26920
  function conversationProjectsRenderEqual2(left, right) {
26587
- 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 && left.sectionKey === right.sectionKey);
26921
+ return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.sectionKey === right.sectionKey && left.label === right.label && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs && left.sectionKey === right.sectionKey);
26922
+ }
26923
+
26924
+ // agent-gui/agentGuiNode/model/agentGuiConversationRailSectionTemplates.ts
26925
+ function preserveConversationRailSectionTemplates(input) {
26926
+ const existingById = new Map(
26927
+ input.sections.map((section) => [section.id, section])
26928
+ );
26929
+ const result = [];
26930
+ const pinned = existingById.get("pinned");
26931
+ if (pinned && pinned.items.length > 0) {
26932
+ result.push(pinned);
26933
+ }
26934
+ existingById.delete("pinned");
26935
+ const projectSectionKeys = /* @__PURE__ */ new Set();
26936
+ for (const project of input.userProjects) {
26937
+ const sectionKey = project.sectionKey?.trim() ?? "";
26938
+ if (!sectionKey || projectSectionKeys.has(sectionKey)) continue;
26939
+ projectSectionKeys.add(sectionKey);
26940
+ const existing = existingById.get(sectionKey);
26941
+ result.push({
26942
+ id: sectionKey,
26943
+ kind: "project",
26944
+ label: project.label,
26945
+ project,
26946
+ items: existing?.items ?? []
26947
+ });
26948
+ existingById.delete(sectionKey);
26949
+ }
26950
+ for (const section of input.sections) {
26951
+ if (section.kind !== "project" || !existingById.has(section.id)) continue;
26952
+ result.push(section);
26953
+ existingById.delete(section.id);
26954
+ }
26955
+ const conversations = existingById.get("conversations");
26956
+ result.push(
26957
+ conversations ?? {
26958
+ id: "conversations",
26959
+ kind: "conversations",
26960
+ label: input.labels.sectionConversations,
26961
+ project: null,
26962
+ items: []
26963
+ }
26964
+ );
26965
+ existingById.delete("conversations");
26966
+ for (const section of input.sections) {
26967
+ if (!existingById.has(section.id)) continue;
26968
+ result.push(section);
26969
+ existingById.delete(section.id);
26970
+ }
26971
+ return result;
26588
26972
  }
26589
26973
 
26590
26974
  // agent-gui/agentGuiNode/view/AgentGUIConversationRailSection.tsx
@@ -26595,9 +26979,9 @@ import {
26595
26979
  DropdownMenuContent as DropdownMenuContent4,
26596
26980
  DropdownMenuItem as DropdownMenuItem3,
26597
26981
  DropdownMenuTrigger as DropdownMenuTrigger4,
26598
- Tooltip as Tooltip7,
26599
- TooltipContent as TooltipContent7,
26600
- TooltipTrigger as TooltipTrigger7
26982
+ Tooltip as Tooltip6,
26983
+ TooltipContent as TooltipContent6,
26984
+ TooltipTrigger as TooltipTrigger6
26601
26985
  } from "@tutti-os/ui-system";
26602
26986
  import { BareIconButton as BareIconButton2 } from "@tutti-os/ui-system/components";
26603
26987
  import {
@@ -26612,7 +26996,7 @@ import {
26612
26996
  memo as memo5,
26613
26997
  useCallback as useCallback41,
26614
26998
  useMemo as useMemo31,
26615
- useRef as useRef32,
26999
+ useRef as useRef33,
26616
27000
  useState as useState25
26617
27001
  } from "react";
26618
27002
  import { ExternalLink as ExternalLink2 } from "lucide-react";
@@ -26621,6 +27005,11 @@ import {
26621
27005
  ContextMenuContent,
26622
27006
  ContextMenuItem,
26623
27007
  ContextMenuTrigger,
27008
+ AgentSessionsIcon,
27009
+ FileIcon,
27010
+ IssueIcon,
27011
+ NavAgentsIcon,
27012
+ NavApplicationsLinedIcon,
26624
27013
  NewWorkspaceLinedIcon as NewWorkspaceLinedIcon2,
26625
27014
  cn as cn5
26626
27015
  } from "@tutti-os/ui-system";
@@ -26628,10 +27017,10 @@ import { BareIconButton } from "@tutti-os/ui-system/components";
26628
27017
  import { WorkspaceUserProjectSelect as WorkspaceUserProjectSelect2 } from "@tutti-os/workspace-user-project/ui";
26629
27018
 
26630
27019
  // app/renderer/components/icons/PinFilledIcon.tsx
26631
- import { jsx as jsx45 } from "react/jsx-runtime";
27020
+ import { jsx as jsx44 } from "react/jsx-runtime";
26632
27021
  function PinFilledIcon(props) {
26633
27022
  "use memo";
26634
- return /* @__PURE__ */ jsx45(
27023
+ return /* @__PURE__ */ jsx44(
26635
27024
  "svg",
26636
27025
  {
26637
27026
  xmlns: "http://www.w3.org/2000/svg",
@@ -26639,16 +27028,16 @@ function PinFilledIcon(props) {
26639
27028
  fill: "currentColor",
26640
27029
  "aria-hidden": true,
26641
27030
  ...props,
26642
- children: /* @__PURE__ */ jsx45("path", { d: "M21.6066 8.05025C22.1692 8.61286 22.4849 9.37592 22.4849 10.1716C22.4849 10.9672 22.1692 11.7303 21.6066 12.2929C21.044 12.8555 20.2809 13.1713 19.4853 13.1713C18.6896 13.1713 17.9266 12.8555 17.3639 12.2929L14.7054 14.9514L14.6142 15.0564C14.531 15.1669 14.4714 15.2943 14.4395 15.43C14.3972 15.6109 14.406 15.8 14.4651 15.9762L14.4678 15.9831L15.0873 17.8717L15.1466 18.072C15.2691 18.5425 15.2761 19.037 15.1646 19.5124C15.0372 20.0557 14.7607 20.5526 14.3663 20.9474L13.8284 21.4853C13.4533 21.8604 12.9446 22.0709 12.4142 22.0709C11.8838 22.0709 11.3751 21.8604 11 21.4853L7.46445 17.9497L4.63603 20.7782C4.2455 21.1687 3.61234 21.1687 3.22181 20.7782C2.83129 20.3877 2.83129 19.7545 3.22181 19.364L6.05024 16.5355L2.51471 13C2.13963 12.6249 1.92913 12.1162 1.92913 11.5858C1.92913 11.0554 2.13963 10.5466 2.51471 10.1716L3.05263 9.63365L3.20524 9.49209C3.57235 9.17309 4.01205 8.94693 4.48756 8.83539C5.03093 8.70798 5.59924 8.73494 6.12827 8.91273L8.01688 9.53214L8.02379 9.5349C8.19995 9.59404 8.38907 9.60282 8.57 9.56045C8.7057 9.52863 8.83304 9.46898 8.94358 9.38575L9.04854 9.2946L11.7071 6.63604C11.1445 6.07343 10.8287 5.31037 10.8287 4.51472C10.8287 3.71907 11.1445 2.95601 11.7071 2.3934C12.2697 1.83079 13.0328 1.51504 13.8284 1.51504C14.6241 1.51504 15.3871 1.83079 15.9497 2.3934L21.6066 8.05025Z" })
27031
+ children: /* @__PURE__ */ jsx44("path", { d: "M21.6066 8.05025C22.1692 8.61286 22.4849 9.37592 22.4849 10.1716C22.4849 10.9672 22.1692 11.7303 21.6066 12.2929C21.044 12.8555 20.2809 13.1713 19.4853 13.1713C18.6896 13.1713 17.9266 12.8555 17.3639 12.2929L14.7054 14.9514L14.6142 15.0564C14.531 15.1669 14.4714 15.2943 14.4395 15.43C14.3972 15.6109 14.406 15.8 14.4651 15.9762L14.4678 15.9831L15.0873 17.8717L15.1466 18.072C15.2691 18.5425 15.2761 19.037 15.1646 19.5124C15.0372 20.0557 14.7607 20.5526 14.3663 20.9474L13.8284 21.4853C13.4533 21.8604 12.9446 22.0709 12.4142 22.0709C11.8838 22.0709 11.3751 21.8604 11 21.4853L7.46445 17.9497L4.63603 20.7782C4.2455 21.1687 3.61234 21.1687 3.22181 20.7782C2.83129 20.3877 2.83129 19.7545 3.22181 19.364L6.05024 16.5355L2.51471 13C2.13963 12.6249 1.92913 12.1162 1.92913 11.5858C1.92913 11.0554 2.13963 10.5466 2.51471 10.1716L3.05263 9.63365L3.20524 9.49209C3.57235 9.17309 4.01205 8.94693 4.48756 8.83539C5.03093 8.70798 5.59924 8.73494 6.12827 8.91273L8.01688 9.53214L8.02379 9.5349C8.19995 9.59404 8.38907 9.60282 8.57 9.56045C8.7057 9.52863 8.83304 9.46898 8.94358 9.38575L9.04854 9.2946L11.7071 6.63604C11.1445 6.07343 10.8287 5.31037 10.8287 4.51472C10.8287 3.71907 11.1445 2.95601 11.7071 2.3934C12.2697 1.83079 13.0328 1.51504 13.8284 1.51504C14.6241 1.51504 15.3871 1.83079 15.9497 2.3934L21.6066 8.05025Z" })
26643
27032
  }
26644
27033
  );
26645
27034
  }
26646
27035
 
26647
27036
  // app/renderer/components/icons/PinLinedIcon.tsx
26648
- import { jsx as jsx46 } from "react/jsx-runtime";
27037
+ import { jsx as jsx45 } from "react/jsx-runtime";
26649
27038
  function PinLinedIcon(props) {
26650
27039
  "use memo";
26651
- return /* @__PURE__ */ jsx46(
27040
+ return /* @__PURE__ */ jsx45(
26652
27041
  "svg",
26653
27042
  {
26654
27043
  xmlns: "http://www.w3.org/2000/svg",
@@ -26656,7 +27045,154 @@ function PinLinedIcon(props) {
26656
27045
  fill: "currentColor",
26657
27046
  "aria-hidden": true,
26658
27047
  ...props,
26659
- children: /* @__PURE__ */ jsx46("path", { d: "M21.6066 8.05025C22.1692 8.61286 22.4849 9.37592 22.4849 10.1716C22.4849 10.9672 22.1692 11.7303 21.6066 12.2929C21.044 12.8555 20.2809 13.1713 19.4853 13.1713C18.6896 13.1713 17.9266 12.8555 17.3639 12.2929L14.7054 14.9514L14.6142 15.0564C14.531 15.1669 14.4714 15.2943 14.4395 15.43C14.3972 15.6109 14.406 15.8 14.4651 15.9762L14.4678 15.9831L15.0873 17.8717L15.1466 18.072C15.2691 18.5425 15.2761 19.037 15.1646 19.5124C15.0372 20.0557 14.7607 20.5526 14.3663 20.9474L13.8284 21.4853C13.4533 21.8604 12.9446 22.0709 12.4142 22.0709C11.8838 22.0709 11.3751 21.8604 11 21.4853L7.46445 17.9497L4.63603 20.7782C4.2455 21.1687 3.61234 21.1687 3.22181 20.7782C2.83129 20.3877 2.83129 19.7545 3.22181 19.364L6.05024 16.5355L2.51471 13C2.13963 12.6249 1.92913 12.1162 1.92913 11.5858C1.92913 11.0554 2.13963 10.5466 2.51471 10.1716L3.05263 9.63365L3.20524 9.49209C3.57235 9.17309 4.01205 8.94693 4.48756 8.83539C5.03093 8.70798 5.59924 8.73494 6.12827 8.91273L8.01688 9.53214L8.02379 9.5349C8.19995 9.59404 8.38907 9.60282 8.57 9.56045C8.7057 9.52863 8.83304 9.46898 8.94358 9.38575L9.04854 9.2946L11.7071 6.63604C11.1445 6.07343 10.8287 5.31037 10.8287 4.51472C10.8287 3.71907 11.1445 2.95601 11.7071 2.3934C12.2697 1.83079 13.0328 1.51504 13.8284 1.51504C14.6241 1.51504 15.3871 1.83079 15.9497 2.3934L21.6066 8.05025ZM14.5355 3.80761C14.348 3.62008 14.0936 3.51483 13.8284 3.51483C13.5632 3.51483 13.3088 3.62008 13.1213 3.80761C12.9338 3.99515 12.8285 4.2495 12.8285 4.51472C12.8285 4.74685 12.9091 4.97066 13.055 5.14863L13.2539 5.36822C13.5457 5.72416 13.7069 6.17177 13.7069 6.63604C13.7069 7.16647 13.4964 7.67518 13.1213 8.05025L10.4621 10.7095C10.0673 11.1038 9.57037 11.3803 9.02713 11.5078C8.48575 11.6347 7.92002 11.6071 7.39264 11.4311V11.4325L5.49781 10.811L5.49091 10.8082C5.31475 10.7491 5.12562 10.7403 4.94469 10.7827C4.76366 10.8251 4.59774 10.9172 4.46615 11.0486L3.92892 11.5858L12.4142 20.0711L12.9514 19.5338C13.0828 19.4022 13.1748 19.2363 13.2173 19.0553C13.2597 18.8744 13.2509 18.6852 13.1917 18.5091L13.189 18.5022L12.5675 16.6073L12.5682 16.6067C12.3924 16.0795 12.3654 15.514 12.4922 14.9729C12.6197 14.4296 12.8962 13.9327 13.2905 13.5379L15.9497 10.8787C16.3248 10.5036 16.8335 10.2931 17.3639 10.2931C17.8282 10.2931 18.2758 10.4543 18.6318 10.7461L18.8514 10.945C19.0293 11.0909 19.2531 11.1715 19.4853 11.1715C19.7505 11.1715 20.0048 11.0662 20.1924 10.8787C20.3799 10.6911 20.4852 10.4368 20.4852 10.1716C20.4852 9.90636 20.3799 9.652 20.1924 9.46447L14.5355 3.80761Z" })
27048
+ children: /* @__PURE__ */ jsx45("path", { d: "M21.6066 8.05025C22.1692 8.61286 22.4849 9.37592 22.4849 10.1716C22.4849 10.9672 22.1692 11.7303 21.6066 12.2929C21.044 12.8555 20.2809 13.1713 19.4853 13.1713C18.6896 13.1713 17.9266 12.8555 17.3639 12.2929L14.7054 14.9514L14.6142 15.0564C14.531 15.1669 14.4714 15.2943 14.4395 15.43C14.3972 15.6109 14.406 15.8 14.4651 15.9762L14.4678 15.9831L15.0873 17.8717L15.1466 18.072C15.2691 18.5425 15.2761 19.037 15.1646 19.5124C15.0372 20.0557 14.7607 20.5526 14.3663 20.9474L13.8284 21.4853C13.4533 21.8604 12.9446 22.0709 12.4142 22.0709C11.8838 22.0709 11.3751 21.8604 11 21.4853L7.46445 17.9497L4.63603 20.7782C4.2455 21.1687 3.61234 21.1687 3.22181 20.7782C2.83129 20.3877 2.83129 19.7545 3.22181 19.364L6.05024 16.5355L2.51471 13C2.13963 12.6249 1.92913 12.1162 1.92913 11.5858C1.92913 11.0554 2.13963 10.5466 2.51471 10.1716L3.05263 9.63365L3.20524 9.49209C3.57235 9.17309 4.01205 8.94693 4.48756 8.83539C5.03093 8.70798 5.59924 8.73494 6.12827 8.91273L8.01688 9.53214L8.02379 9.5349C8.19995 9.59404 8.38907 9.60282 8.57 9.56045C8.7057 9.52863 8.83304 9.46898 8.94358 9.38575L9.04854 9.2946L11.7071 6.63604C11.1445 6.07343 10.8287 5.31037 10.8287 4.51472C10.8287 3.71907 11.1445 2.95601 11.7071 2.3934C12.2697 1.83079 13.0328 1.51504 13.8284 1.51504C14.6241 1.51504 15.3871 1.83079 15.9497 2.3934L21.6066 8.05025ZM14.5355 3.80761C14.348 3.62008 14.0936 3.51483 13.8284 3.51483C13.5632 3.51483 13.3088 3.62008 13.1213 3.80761C12.9338 3.99515 12.8285 4.2495 12.8285 4.51472C12.8285 4.74685 12.9091 4.97066 13.055 5.14863L13.2539 5.36822C13.5457 5.72416 13.7069 6.17177 13.7069 6.63604C13.7069 7.16647 13.4964 7.67518 13.1213 8.05025L10.4621 10.7095C10.0673 11.1038 9.57037 11.3803 9.02713 11.5078C8.48575 11.6347 7.92002 11.6071 7.39264 11.4311V11.4325L5.49781 10.811L5.49091 10.8082C5.31475 10.7491 5.12562 10.7403 4.94469 10.7827C4.76366 10.8251 4.59774 10.9172 4.46615 11.0486L3.92892 11.5858L12.4142 20.0711L12.9514 19.5338C13.0828 19.4022 13.1748 19.2363 13.2173 19.0553C13.2597 18.8744 13.2509 18.6852 13.1917 18.5091L13.189 18.5022L12.5675 16.6073L12.5682 16.6067C12.3924 16.0795 12.3654 15.514 12.4922 14.9729C12.6197 14.4296 12.8962 13.9327 13.2905 13.5379L15.9497 10.8787C16.3248 10.5036 16.8335 10.2931 17.3639 10.2931C17.8282 10.2931 18.2758 10.4543 18.6318 10.7461L18.8514 10.945C19.0293 11.0909 19.2531 11.1715 19.4853 11.1715C19.7505 11.1715 20.0048 11.0662 20.1924 10.8787C20.3799 10.6911 20.4852 10.4368 20.4852 10.1716C20.4852 9.90636 20.3799 9.652 20.1924 9.46447L14.5355 3.80761Z" })
27049
+ }
27050
+ );
27051
+ }
27052
+
27053
+ // agent-gui/agentGuiNode/agentGuiNodeViewConversation.tsx
27054
+ import { Spinner as Spinner5 } from "@tutti-os/ui-system";
27055
+ import { AskLinedIcon } from "@tutti-os/ui-system/icons";
27056
+ import { jsx as jsx46 } from "react/jsx-runtime";
27057
+ function ConversationMeta({
27058
+ item,
27059
+ nowMs,
27060
+ labels
27061
+ }) {
27062
+ "use memo";
27063
+ const kind = conversationMetaKind(item);
27064
+ if (kind === "loading") {
27065
+ return /* @__PURE__ */ jsx46(
27066
+ "span",
27067
+ {
27068
+ className: AgentGUINode_styles_default.conversationMeta,
27069
+ "data-kind": kind,
27070
+ "data-testid": `agent-gui-conversation-meta-${item.id}`,
27071
+ children: /* @__PURE__ */ jsx46(LoadingGlyph, {})
27072
+ }
27073
+ );
27074
+ }
27075
+ if (kind === "waiting") {
27076
+ return /* @__PURE__ */ jsx46(
27077
+ "span",
27078
+ {
27079
+ className: AgentGUINode_styles_default.conversationMeta,
27080
+ "data-kind": kind,
27081
+ "data-testid": `agent-gui-conversation-meta-${item.id}`,
27082
+ children: /* @__PURE__ */ jsx46(
27083
+ AskLinedIcon,
27084
+ {
27085
+ "aria-hidden": "true",
27086
+ className: AgentGUINode_styles_default.conversationStatusGlyph
27087
+ }
27088
+ )
27089
+ }
27090
+ );
27091
+ }
27092
+ if (kind === "failed") {
27093
+ return /* @__PURE__ */ jsx46(
27094
+ "span",
27095
+ {
27096
+ className: AgentGUINode_styles_default.conversationMeta,
27097
+ "data-kind": kind,
27098
+ "data-testid": `agent-gui-conversation-meta-${item.id}`,
27099
+ children: /* @__PURE__ */ jsx46(AttentionGlyph, {})
27100
+ }
27101
+ );
27102
+ }
27103
+ if (kind === "unread-complete") {
27104
+ return /* @__PURE__ */ jsx46(
27105
+ "span",
27106
+ {
27107
+ className: AgentGUINode_styles_default.conversationMeta,
27108
+ "data-kind": kind,
27109
+ "data-testid": `agent-gui-conversation-meta-${item.id}`,
27110
+ children: /* @__PURE__ */ jsx46("span", { className: AgentGUINode_styles_default.conversationUnreadLamp, "aria-hidden": "true" })
27111
+ }
27112
+ );
27113
+ }
27114
+ return /* @__PURE__ */ jsx46(
27115
+ "span",
27116
+ {
27117
+ className: AgentGUINode_styles_default.conversationMeta,
27118
+ "data-kind": kind,
27119
+ "data-testid": `agent-gui-conversation-meta-${item.id}`,
27120
+ children: /* @__PURE__ */ jsx46("span", { className: AgentGUINode_styles_default.conversationTime, children: formatConversationRelativeTime(
27121
+ resolveAgentGUIConversationSortTimeUnixMs(item),
27122
+ nowMs,
27123
+ labels
27124
+ ) })
27125
+ }
27126
+ );
27127
+ }
27128
+ function conversationMetaKind(conversation) {
27129
+ if (conversation.status === "working") {
27130
+ return "loading";
27131
+ }
27132
+ if (conversation.status === "waiting") {
27133
+ return "waiting";
27134
+ }
27135
+ if (conversation.status === "failed") {
27136
+ return "failed";
27137
+ }
27138
+ if (conversation.hasUnreadCompletion) {
27139
+ return "unread-complete";
27140
+ }
27141
+ return "time";
27142
+ }
27143
+ function formatConversationRelativeTime(updatedAtUnixMs, nowMs, labels) {
27144
+ const elapsedMs = Math.max(0, nowMs - updatedAtUnixMs);
27145
+ const elapsedMinutes = Math.floor(elapsedMs / (60 * 1e3));
27146
+ if (elapsedMinutes < 1) {
27147
+ return labels.relativeTimeJustNow;
27148
+ }
27149
+ if (elapsedMinutes < 60) {
27150
+ return labels.relativeTimeMinutes(elapsedMinutes);
27151
+ }
27152
+ const elapsedHours = Math.floor(elapsedMinutes / 60);
27153
+ if (elapsedHours < 24) {
27154
+ return labels.relativeTimeHours(elapsedHours);
27155
+ }
27156
+ const elapsedDays = Math.floor(elapsedHours / 24);
27157
+ if (elapsedDays < 30) {
27158
+ return labels.relativeTimeDays(elapsedDays);
27159
+ }
27160
+ const elapsedMonths = Math.floor(elapsedDays / 30);
27161
+ if (elapsedMonths < 12) {
27162
+ return labels.relativeTimeMonths(elapsedMonths);
27163
+ }
27164
+ return labels.relativeTimeYears(Math.floor(elapsedDays / 365));
27165
+ }
27166
+ function LoadingGlyph() {
27167
+ "use memo";
27168
+ return /* @__PURE__ */ jsx46(
27169
+ Spinner5,
27170
+ {
27171
+ className: AgentGUINode_styles_default.conversationStatusGlyph,
27172
+ size: 14,
27173
+ style: { color: "var(--text-secondary)" },
27174
+ strokeWidth: 2.25,
27175
+ trackColor: "color-mix(in srgb, currentColor 24%, transparent)",
27176
+ testId: "agent-gui-conversation-spinner"
27177
+ }
27178
+ );
27179
+ }
27180
+ function AttentionGlyph() {
27181
+ "use memo";
27182
+ return /* @__PURE__ */ jsx46(
27183
+ "svg",
27184
+ {
27185
+ viewBox: "0 0 24 24",
27186
+ fill: "none",
27187
+ "aria-hidden": "true",
27188
+ className: AgentGUINode_styles_default.conversationStatusGlyph,
27189
+ children: /* @__PURE__ */ jsx46(
27190
+ "path",
27191
+ {
27192
+ d: "M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM12.5 15C12.7761 15 13 15.2239 13 15.5V16.5C13 16.7761 12.7761 17 12.5 17H11.5C11.2239 17 11 16.7761 11 16.5V15.5C11 15.2239 11.2239 15 11.5 15H12.5ZM12.5 7C12.7761 7 13 7.22386 13 7.5V13.5C13 13.7761 12.7761 14 12.5 14H11.5C11.2239 14 11 13.7761 11 13.5V7.5C11 7.22386 11.2239 7 11.5 7H12.5Z",
27193
+ fill: "currentColor"
27194
+ }
27195
+ )
26660
27196
  }
26661
27197
  );
26662
27198
  }
@@ -26671,6 +27207,10 @@ function agentGUIConversationIconUrl(provider, agentTargetId, workspaceId, agent
26671
27207
  });
26672
27208
  return resolveAgentGuiSessionProviderFlatIconUrl(provider) || targetPresentation?.iconUrl?.trim() || null;
26673
27209
  }
27210
+ function agentGUIConversationRailTitle(item, labels, uiLanguage) {
27211
+ const title = conversationPlainTitle(item, labels, uiLanguage);
27212
+ return item.titleLeadingMentionKind ? title.replace(/^@\s*/, "") : title;
27213
+ }
26674
27214
  var AgentGUIConversationRailItem = memo5(
26675
27215
  function AgentGUIConversationRailItem2({
26676
27216
  item,
@@ -26709,9 +27249,9 @@ var AgentGUIConversationRailItem = memo5(
26709
27249
  [item.id, registerItemElement]
26710
27250
  );
26711
27251
  const [contextMenuResetKey, setContextMenuResetKey] = useState25(0);
26712
- const contextMenuRenameRequestedRef = useRef32(false);
26713
- const contextMenuOpenConversationWindowRequestedRef = useRef32(false);
26714
- const contextMenuCopySessionLinkRequestedRef = useRef32(false);
27252
+ const contextMenuRenameRequestedRef = useRef33(false);
27253
+ const contextMenuOpenConversationWindowRequestedRef = useRef33(false);
27254
+ const contextMenuCopySessionLinkRequestedRef = useRef33(false);
26715
27255
  const agentHostApi = useOptionalAgentHostApi();
26716
27256
  const handleMouseLeave = useCallback41(() => {
26717
27257
  if (isPendingDeleteConversation && !isRailInteractionLocked()) {
@@ -26860,7 +27400,21 @@ var AgentGUIConversationRailItem = memo5(
26860
27400
  }
26861
27401
  }
26862
27402
  ) : null,
26863
- /* @__PURE__ */ jsx47("span", { className: AgentGUINode_styles_default.conversationTitle, children: conversationPlainTitle(item, labels, uiLanguage) })
27403
+ item.titleLeadingMentionKind ? /* @__PURE__ */ jsx47(
27404
+ "span",
27405
+ {
27406
+ "aria-hidden": "true",
27407
+ className: AgentGUINode_styles_default.conversationTitleMentionIcon,
27408
+ "data-agent-gui-conversation-title-mention-icon": item.titleLeadingMentionKind,
27409
+ children: /* @__PURE__ */ jsx47(
27410
+ ConversationTitleMentionIcon,
27411
+ {
27412
+ kind: item.titleLeadingMentionKind
27413
+ }
27414
+ )
27415
+ }
27416
+ ) : null,
27417
+ /* @__PURE__ */ jsx47("span", { className: AgentGUINode_styles_default.conversationTitle, children: agentGUIConversationRailTitle(item, labels, uiLanguage) })
26864
27418
  ] }),
26865
27419
  /* @__PURE__ */ jsx47(ConversationMeta, { item, nowMs: currentTimeMs, labels })
26866
27420
  ]
@@ -27014,6 +27568,15 @@ var AgentGUIConversationRailItem = memo5(
27014
27568
  ] }, contextMenuResetKey);
27015
27569
  }
27016
27570
  );
27571
+ function ConversationTitleMentionIcon({
27572
+ kind
27573
+ }) {
27574
+ if (kind === "task") return /* @__PURE__ */ jsx47(IssueIcon, {});
27575
+ if (kind === "app") return /* @__PURE__ */ jsx47(NavApplicationsLinedIcon, {});
27576
+ if (kind === "file") return /* @__PURE__ */ jsx47(FileIcon, {});
27577
+ if (kind === "agent") return /* @__PURE__ */ jsx47(NavAgentsIcon, {});
27578
+ return /* @__PURE__ */ jsx47(AgentSessionsIcon, {});
27579
+ }
27017
27580
  function AgentGUIProjectRailHeader({
27018
27581
  disabled,
27019
27582
  labels,
@@ -27281,8 +27844,8 @@ var AgentGUIConversationRailSection = memo6(
27281
27844
  onClick: handleCreateConversation,
27282
27845
  children: /* @__PURE__ */ jsx48(CreateChatIcon, { "aria-hidden": "true" })
27283
27846
  }
27284
- ) }) : /* @__PURE__ */ jsxs34(Tooltip7, { children: [
27285
- /* @__PURE__ */ jsx48(TooltipTrigger7, { asChild: true, children: /* @__PURE__ */ jsx48(
27847
+ ) }) : /* @__PURE__ */ jsxs34(Tooltip6, { children: [
27848
+ /* @__PURE__ */ jsx48(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx48(
27286
27849
  "span",
27287
27850
  {
27288
27851
  className: AgentGUINode_styles_default.conversationSectionActionTooltipWrap,
@@ -27300,7 +27863,7 @@ var AgentGUIConversationRailSection = memo6(
27300
27863
  }
27301
27864
  ) }),
27302
27865
  /* @__PURE__ */ jsx48(
27303
- TooltipContent7,
27866
+ TooltipContent6,
27304
27867
  {
27305
27868
  side: "top",
27306
27869
  sideOffset: 6,
@@ -27324,12 +27887,12 @@ var AgentGUIConversationRailSection = memo6(
27324
27887
  }
27325
27888
  )
27326
27889
  }
27327
- ) }) : /* @__PURE__ */ jsxs34(Tooltip7, { children: [
27328
- /* @__PURE__ */ jsx48(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx48(TooltipTrigger7, { asChild: true, children: /* @__PURE__ */ jsx48(
27890
+ ) }) : /* @__PURE__ */ jsxs34(Tooltip6, { children: [
27891
+ /* @__PURE__ */ jsx48(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx48(
27329
27892
  "span",
27330
27893
  {
27331
27894
  className: AgentGUINode_styles_default.conversationSectionActionTooltipWrap,
27332
- children: /* @__PURE__ */ jsx48(
27895
+ children: /* @__PURE__ */ jsx48(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx48(
27333
27896
  BareIconButton2,
27334
27897
  {
27335
27898
  className: AgentGUINode_styles_default.conversationSectionMoreButton,
@@ -27337,11 +27900,11 @@ var AgentGUIConversationRailSection = memo6(
27337
27900
  size: "sm",
27338
27901
  children: /* @__PURE__ */ jsx48(MoreHorizontalIcon, { "aria-hidden": "true" })
27339
27902
  }
27340
- )
27903
+ ) })
27341
27904
  }
27342
- ) }) }),
27905
+ ) }),
27343
27906
  /* @__PURE__ */ jsx48(
27344
- TooltipContent7,
27907
+ TooltipContent6,
27345
27908
  {
27346
27909
  side: "right",
27347
27910
  sideOffset: 6,
@@ -27424,12 +27987,12 @@ var AgentGUIConversationRailSection = memo6(
27424
27987
  }
27425
27988
  )
27426
27989
  }
27427
- ) }) : /* @__PURE__ */ jsxs34(Tooltip7, { children: [
27428
- /* @__PURE__ */ jsx48(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx48(TooltipTrigger7, { asChild: true, children: /* @__PURE__ */ jsx48(
27990
+ ) }) : /* @__PURE__ */ jsxs34(Tooltip6, { children: [
27991
+ /* @__PURE__ */ jsx48(TooltipTrigger6, { asChild: true, children: /* @__PURE__ */ jsx48(
27429
27992
  "span",
27430
27993
  {
27431
27994
  className: AgentGUINode_styles_default.conversationSectionActionTooltipWrap,
27432
- children: /* @__PURE__ */ jsx48(
27995
+ children: /* @__PURE__ */ jsx48(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx48(
27433
27996
  BareIconButton2,
27434
27997
  {
27435
27998
  className: AgentGUINode_styles_default.conversationSectionMoreButton,
@@ -27437,11 +28000,11 @@ var AgentGUIConversationRailSection = memo6(
27437
28000
  size: "sm",
27438
28001
  children: /* @__PURE__ */ jsx48(MoreHorizontalIcon, { "aria-hidden": "true" })
27439
28002
  }
27440
- )
28003
+ ) })
27441
28004
  }
27442
- ) }) }),
28005
+ ) }),
27443
28006
  /* @__PURE__ */ jsx48(
27444
- TooltipContent7,
28007
+ TooltipContent6,
27445
28008
  {
27446
28009
  side: "right",
27447
28010
  sideOffset: 6,
@@ -27596,15 +28159,15 @@ var AgentGUIConversationRailPane = memo7(
27596
28159
  const [pendingProjectAction, setPendingProjectAction] = useState27(null);
27597
28160
  const [isRequestingBatchDeletion, setIsRequestingBatchDeletion] = useState27(false);
27598
28161
  const { railSearch } = railQuery;
27599
- const railElementRef = useRef33(null);
27600
- const conversationListRef = useRef33(null);
27601
- const conversationItemElementsRef = useRef33(
28162
+ const railElementRef = useRef34(null);
28163
+ const conversationListRef = useRef34(null);
28164
+ const conversationItemElementsRef = useRef34(
27602
28165
  /* @__PURE__ */ new Map()
27603
28166
  );
27604
- const activeConversationScrollCompletedRef = useRef33(null);
27605
- const previousActiveConversationIdRef = useRef33(null);
27606
- const railActiveConversationRef = useRef33([]);
27607
- const groupedConversationsRef = useRef33(null);
28167
+ const activeConversationScrollCompletedRef = useRef34(null);
28168
+ const previousActiveConversationIdRef = useRef34(null);
28169
+ const railActiveConversationRef = useRef34([]);
28170
+ const groupedConversationsRef = useRef34(null);
27608
28171
  const {
27609
28172
  loadMoreSectionConversations,
27610
28173
  isInteractionLocked,
@@ -27627,7 +28190,7 @@ var AgentGUIConversationRailPane = memo7(
27627
28190
  const railConversationEntities = [...railConversationEntitiesById.values()];
27628
28191
  const hasConversationQuery = conversationQuery.trim().length > 0;
27629
28192
  const backendSearchActive = hasConversationQuery && railSearch.enabled;
27630
- const railInteractionsLocked = runtimeRailSectionsPending && !backendSearchActive;
28193
+ const railInteractionsLocked = isInteractionLocked();
27631
28194
  const backendSearchConversations = backendSearchActive ? railSearch.sessionIds.flatMap((id) => {
27632
28195
  const conversation = railConversationEntitiesById.get(id);
27633
28196
  return conversation ? [conversation] : [];
@@ -27659,7 +28222,11 @@ var AgentGUIConversationRailPane = memo7(
27659
28222
  labels,
27660
28223
  sections: runtimeSectionsWithTransientConversations
27661
28224
  });
27662
- const runtimeDisplaySections = runtimeDisplayProjection.sections;
28225
+ const runtimeDisplaySections = preserveConversationRailSectionTemplates({
28226
+ labels,
28227
+ sections: runtimeDisplayProjection.sections,
28228
+ userProjects
28229
+ });
27663
28230
  const railActiveOverlay = runtimeDisplayProjection.activeOverlay;
27664
28231
  useEffect30(() => {
27665
28232
  const timer = window.setInterval(() => {
@@ -27711,8 +28278,10 @@ var AgentGUIConversationRailPane = memo7(
27711
28278
  const groupedConversationResult = useMemo32(() => {
27712
28279
  const startedAtMs = agentGuiPerfNowMs();
27713
28280
  const query = conversationQuery.trim();
27714
- const rawGroups = backendSearchActive ? groupConversations(filteredConversations, labels, userProjects, {
27715
- includeEmptyConversations: false
28281
+ const rawGroups = backendSearchActive ? projectConversationRailSearchSections({
28282
+ conversations: filteredConversations,
28283
+ labels,
28284
+ sections: runtimeDisplaySections
27716
28285
  }) : runtimeSectionsEnabled || runtimeRailSections ? runtimeDisplaySections.length > 0 ? !query ? runtimeDisplaySections : runtimeDisplaySections.map((section) => ({
27717
28286
  ...section,
27718
28287
  items: section.items.filter(
@@ -27724,8 +28293,11 @@ var AgentGUIConversationRailPane = memo7(
27724
28293
  (section) => section.items.length > 0 || section.id === railActiveOverlay?.sectionId && filteredConversations.some(
27725
28294
  (conversation) => conversation.id === railActiveOverlay.conversation.id
27726
28295
  )
27727
- ) : [] : groupConversations(filteredConversations, labels, userProjects, {
27728
- includeEmptyConversations: !query
28296
+ ) : [] : projectConversationRailSectionsByExactKey({
28297
+ conversations: filteredConversations,
28298
+ labels,
28299
+ userProjects,
28300
+ includeEmptySections: !query
27729
28301
  });
27730
28302
  const groups = stabilizeConversationSections(
27731
28303
  groupedConversationsRef.current,
@@ -27796,7 +28368,11 @@ var AgentGUIConversationRailPane = memo7(
27796
28368
  sectionAgentTargetId
27797
28369
  ]
27798
28370
  );
27799
- const isRuntimeRailLoading = runtimeSectionsEnabled && (runtimeRailSections === null || runtimeRailSectionsPending);
28371
+ const isRuntimeRailLoading = isConversationRailInitialLoadPending({
28372
+ pending: runtimeRailSectionsPending,
28373
+ runtimeSectionsEnabled,
28374
+ sections: runtimeRailMemberships
28375
+ });
27800
28376
  const isConversationRailListLoading = backendSearchActive ? railSearch.pending : isRuntimeRailLoading || isLoadingConversations && conversations.length === 0;
27801
28377
  const shouldShowConversationSkeleton = useDelayedBoolean(
27802
28378
  isConversationRailListLoading,
@@ -27892,96 +28468,89 @@ var AgentGUIConversationRailPane = memo7(
27892
28468
  children: labels.retrySearch
27893
28469
  }
27894
28470
  )
27895
- ] }) : shouldShowConversationEmptyState ? /* @__PURE__ */ jsx49("div", { className: AgentGUINode_styles_default.emptyState, children: /* @__PURE__ */ jsx49("span", { children: conversationQuery.trim() ? labels.searchNoConversations : conversations.length === 0 ? labels.noConversations : labels.conversationUnavailable }) }) : /* @__PURE__ */ jsx49(
27896
- "fieldset",
27897
- {
27898
- className: "contents",
27899
- disabled: runtimeRailSectionsPending && !backendSearchActive,
27900
- children: groupedConversations.map((section, sectionIndex) => {
27901
- const projectPath = section.kind === "project" ? section.project?.path ?? "" : "";
27902
- const projectLabel = section.kind === "project" ? section.label : "";
27903
- const isProjectSection = section.kind === "project";
27904
- const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
27905
- const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
27906
- const sectionPageState = sectionPageStates.get(section.id);
27907
- const searchSectionHasMore = backendSearchActive && sectionIndex === groupedConversations.length - 1 && railSearch.hasMore;
27908
- const activeOverlayConversation = !backendSearchActive && railActiveOverlay?.sectionId === section.id && (!conversationQuery.trim() || filteredConversations.some(
27909
- (conversation) => conversation.id === railActiveOverlay.conversation.id
27910
- )) ? railActiveOverlay.conversation : null;
27911
- const activeOverlayIsCanonical = Boolean(
27912
- activeOverlayConversation && section.items.some(
27913
- (item) => item.projectionSource !== "pending_activation" && item.id === activeOverlayConversation.id
27914
- )
27915
- );
27916
- const activeOverlayCountsTowardTotal = Boolean(
27917
- activeOverlayConversation && activeOverlayConversation.projectionSource !== "pending_activation" && matchesAgentGUIConversationSummaryFilter(
27918
- activeOverlayConversation,
27919
- conversationFilter
27920
- )
27921
- );
27922
- const sectionTotalCount = backendSearchActive ? section.items.length + (searchSectionHasMore ? 1 : 0) : sectionPageState?.totalCount ?? section.items.filter(
27923
- (item) => item.projectionSource !== "pending_activation"
27924
- ).length + (activeOverlayCountsTowardTotal && !activeOverlayIsCanonical ? 1 : 0);
27925
- const sectionHasMore = searchSectionHasMore || !conversationQuery.trim() && sectionPageState?.hasMore === true;
27926
- return /* @__PURE__ */ jsxs35(Fragment13, { children: [
27927
- showProjectRailHeader ? /* @__PURE__ */ jsx49(
27928
- AgentGUIProjectRailHeader,
27929
- {
27930
- disabled: railInteractionsLocked,
27931
- labels,
27932
- selectProjectDirectory,
27933
- workspaceUserProjectI18n
27934
- }
27935
- ) : null,
27936
- /* @__PURE__ */ jsx49(
27937
- AgentGUIConversationRailSection,
27938
- {
27939
- activeConversation: activeOverlayConversation,
27940
- activeConversationCountsTowardTotal: activeOverlayCountsTowardTotal,
27941
- activeConversationId,
27942
- createConversationDisabled,
27943
- currentTimeMs,
27944
- isDeletingConversation,
27945
- isDeletingProjectConversations,
27946
- isRequestingBatchDeletion,
27947
- isConversationSearchActive: Boolean(
27948
- conversationQuery.trim()
27949
- ),
27950
- isLoadingMoreConversations: backendSearchActive ? railSearch.loadingMore : sectionPageState?.isLoading ?? false,
27951
- isRailInteractionLocked: isInteractionLocked,
27952
- isSectionCollapsed,
27953
- labels,
27954
- pendingDeleteConversationId,
27955
- paginationScopeKey: sectionPaginationScopeKey,
27956
- previewMode,
27957
- projectLabel,
27958
- projectPath,
27959
- registerItemElement: registerConversationItemElement,
27960
- section,
27961
- sectionHasMore,
27962
- sectionTotalCount,
27963
- uiLanguage,
27964
- workspaceId,
27965
- onCancelDeleteConversation,
27966
- onConfirmDeleteConversation,
27967
- onCreateConversation,
27968
- onLoadMoreConversations: backendSearchActive ? railSearch.loadMore : loadMoreSectionConversations,
27969
- onRequestDeleteConversation,
27970
- onRequestRenameConversation,
27971
- onSelectConversation,
27972
- onRequestSectionBatchDeletion: requestSectionBatchDeletion,
27973
- setPendingProjectAction,
27974
- onToggleConversationPinned,
27975
- onMarkConversationUnread,
27976
- onOpenProjectFiles,
27977
- onOpenConversationWindow,
27978
- onToggleProjectSectionCollapsed: toggleProjectSectionCollapsed
27979
- }
27980
- )
27981
- ] }, section.id);
27982
- })
27983
- }
27984
- )
28471
+ ] }) : shouldShowConversationEmptyState ? /* @__PURE__ */ jsx49("div", { className: AgentGUINode_styles_default.emptyState, children: /* @__PURE__ */ jsx49("span", { children: conversationQuery.trim() ? labels.searchNoConversations : conversations.length === 0 ? labels.noConversations : labels.conversationUnavailable }) }) : /* @__PURE__ */ jsx49("fieldset", { className: "contents", disabled: railInteractionsLocked, children: groupedConversations.map((section, sectionIndex) => {
28472
+ const projectPath = section.kind === "project" ? section.project?.path ?? "" : "";
28473
+ const projectLabel = section.kind === "project" ? section.label : "";
28474
+ const isProjectSection = section.kind === "project";
28475
+ const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
28476
+ const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
28477
+ const sectionPageState = sectionPageStates.get(section.id);
28478
+ const searchSectionHasMore = backendSearchActive && sectionIndex === groupedConversations.length - 1 && railSearch.hasMore;
28479
+ const activeOverlayConversation = !backendSearchActive && railActiveOverlay?.sectionId === section.id && (!conversationQuery.trim() || filteredConversations.some(
28480
+ (conversation) => conversation.id === railActiveOverlay.conversation.id
28481
+ )) ? railActiveOverlay.conversation : null;
28482
+ const activeOverlayIsCanonical = Boolean(
28483
+ activeOverlayConversation && section.items.some(
28484
+ (item) => item.projectionSource !== "pending_activation" && item.id === activeOverlayConversation.id
28485
+ )
28486
+ );
28487
+ const activeOverlayCountsTowardTotal = Boolean(
28488
+ activeOverlayConversation && activeOverlayConversation.projectionSource !== "pending_activation" && matchesAgentGUIConversationSummaryFilter(
28489
+ activeOverlayConversation,
28490
+ conversationFilter
28491
+ )
28492
+ );
28493
+ const sectionTotalCount = backendSearchActive ? section.items.length + (searchSectionHasMore ? 1 : 0) : sectionPageState?.totalCount ?? section.items.filter(
28494
+ (item) => item.projectionSource !== "pending_activation"
28495
+ ).length + (activeOverlayCountsTowardTotal && !activeOverlayIsCanonical ? 1 : 0);
28496
+ const sectionHasMore = searchSectionHasMore || !conversationQuery.trim() && sectionPageState?.hasMore === true;
28497
+ return /* @__PURE__ */ jsxs35(Fragment13, { children: [
28498
+ showProjectRailHeader ? /* @__PURE__ */ jsx49(
28499
+ AgentGUIProjectRailHeader,
28500
+ {
28501
+ disabled: railInteractionsLocked,
28502
+ labels,
28503
+ selectProjectDirectory,
28504
+ workspaceUserProjectI18n
28505
+ }
28506
+ ) : null,
28507
+ /* @__PURE__ */ jsx49(
28508
+ AgentGUIConversationRailSection,
28509
+ {
28510
+ activeConversation: activeOverlayConversation,
28511
+ activeConversationCountsTowardTotal: activeOverlayCountsTowardTotal,
28512
+ activeConversationId,
28513
+ createConversationDisabled,
28514
+ currentTimeMs,
28515
+ isDeletingConversation,
28516
+ isDeletingProjectConversations,
28517
+ isRequestingBatchDeletion,
28518
+ isConversationSearchActive: Boolean(
28519
+ conversationQuery.trim()
28520
+ ),
28521
+ isLoadingMoreConversations: backendSearchActive ? railSearch.loadingMore : sectionPageState?.isLoading ?? false,
28522
+ isRailInteractionLocked: isInteractionLocked,
28523
+ isSectionCollapsed,
28524
+ labels,
28525
+ pendingDeleteConversationId,
28526
+ paginationScopeKey: sectionPaginationScopeKey,
28527
+ previewMode,
28528
+ projectLabel,
28529
+ projectPath,
28530
+ registerItemElement: registerConversationItemElement,
28531
+ section,
28532
+ sectionHasMore,
28533
+ sectionTotalCount,
28534
+ uiLanguage,
28535
+ workspaceId,
28536
+ onCancelDeleteConversation,
28537
+ onConfirmDeleteConversation,
28538
+ onCreateConversation,
28539
+ onLoadMoreConversations: backendSearchActive ? railSearch.loadMore : loadMoreSectionConversations,
28540
+ onRequestDeleteConversation,
28541
+ onRequestRenameConversation,
28542
+ onSelectConversation,
28543
+ onRequestSectionBatchDeletion: requestSectionBatchDeletion,
28544
+ setPendingProjectAction,
28545
+ onToggleConversationPinned,
28546
+ onMarkConversationUnread,
28547
+ onOpenProjectFiles,
28548
+ onOpenConversationWindow,
28549
+ onToggleProjectSectionCollapsed: toggleProjectSectionCollapsed
28550
+ }
28551
+ )
28552
+ ] }, section.id);
28553
+ }) })
27985
28554
  }
27986
28555
  ),
27987
28556
  footer ? /* @__PURE__ */ jsx49("div", { className: "shrink-0 pb-2", children: footer }) : null,
@@ -28040,13 +28609,73 @@ var AgentGUIConversationRailPane = memo7(
28040
28609
  import {
28041
28610
  selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions4
28042
28611
  } from "@tutti-os/agent-activity-core";
28043
- import { useEffect as useEffect31, useMemo as useMemo33, useRef as useRef34 } from "react";
28612
+ import { useEffect as useEffect31, useMemo as useMemo33, useRef as useRef35 } from "react";
28044
28613
 
28045
28614
  // agent-gui/agentGuiNode/controller/AgentGUIConversationRailQueryController.ts
28046
28615
  import {
28047
28616
  selectPendingActivations as selectPendingActivations3,
28048
28617
  selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions3
28049
28618
  } from "@tutti-os/agent-activity-core";
28619
+
28620
+ // agent-gui/agentGuiNode/controller/agentGuiConversationRailDiagnostics.ts
28621
+ var CONVERSATION_RAIL_SLOW_DIAGNOSTIC_THRESHOLD_MS = 250;
28622
+ function emitConversationRailFirstPagesDiagnostic(input) {
28623
+ if (input.status === "ready" && input.durationMs < input.diagnosticSlowThresholdMs) {
28624
+ return;
28625
+ }
28626
+ const payload = {
28627
+ agentTargetId: input.agentTargetId,
28628
+ controllerApplyMs: input.controllerApplyMs,
28629
+ durationMs: input.durationMs,
28630
+ ...input.status === "error" ? { errorKind: conversationRailErrorKind(input.error) } : {},
28631
+ event: input.status === "error" ? "agent_gui.conversation_rail.first_pages_failed" : "agent_gui.conversation_rail.first_pages_slow",
28632
+ requestId: input.requestId,
28633
+ requestMs: input.requestMs,
28634
+ refreshReason: input.refreshReason,
28635
+ returnedSessionCount: input.returnedSessionCount,
28636
+ sectionCount: input.sectionCount,
28637
+ status: input.status,
28638
+ workspaceId: input.workspaceId
28639
+ };
28640
+ try {
28641
+ input.diagnosticLogger(payload);
28642
+ } catch (error) {
28643
+ ignoreConversationRailDiagnosticFailure(error);
28644
+ }
28645
+ }
28646
+ function createConversationRailDiagnosticLogger(runtime) {
28647
+ return (payload) => {
28648
+ const reportDiagnostic = runtime.reportDiagnostic;
28649
+ if (!reportDiagnostic) return;
28650
+ try {
28651
+ void Promise.resolve(
28652
+ reportDiagnostic.call(runtime, {
28653
+ details: { ...payload },
28654
+ event: payload.event,
28655
+ level: payload.status === "error" ? "warn" : "info",
28656
+ source: "agent-gui",
28657
+ workspaceId: payload.workspaceId
28658
+ })
28659
+ ).catch(ignoreConversationRailDiagnosticFailure);
28660
+ } catch (error) {
28661
+ ignoreConversationRailDiagnosticFailure(error);
28662
+ }
28663
+ };
28664
+ }
28665
+ function ignoreConversationRailDiagnosticFailure(error) {
28666
+ void error;
28667
+ }
28668
+ function conversationRailErrorKind(error) {
28669
+ if (error instanceof Error) {
28670
+ return error.name || "Error";
28671
+ }
28672
+ if (typeof error === "string") {
28673
+ return "string";
28674
+ }
28675
+ return error === null ? "null" : typeof error;
28676
+ }
28677
+
28678
+ // agent-gui/agentGuiNode/controller/AgentGUIConversationRailQueryController.ts
28050
28679
  var SECTION_PAGE_SIZE = 5;
28051
28680
  var SEARCH_PAGE_SIZE = 100;
28052
28681
  var CONVERSATION_SEARCH_DEBOUNCE_MS = 300;
@@ -28069,12 +28698,15 @@ var EMPTY_QUERY_STATE = {
28069
28698
  };
28070
28699
  var AgentGUIConversationRailQueryController = class {
28071
28700
  getSnapshot = () => this.snapshot;
28072
- isInteractionLocked = () => this.snapshot.runtimeRailSectionsPending && !(this.searchQuery && this.snapshot.railSearch.enabled);
28701
+ isInteractionLocked = () => this.queryState.pending && this.queryState.resolvedScopeKey !== this.railSectionQueryKey && !(this.searchQuery && this.snapshot.railSearch.enabled);
28073
28702
  subscribe = (listener) => {
28074
28703
  this.listeners.add(listener);
28075
28704
  return () => this.listeners.delete(listener);
28076
28705
  };
28077
28706
  engine;
28707
+ diagnosticLogger;
28708
+ diagnosticNow;
28709
+ diagnosticSlowThresholdMs;
28078
28710
  getActiveConversationId;
28079
28711
  listeners = /* @__PURE__ */ new Set();
28080
28712
  runtime;
@@ -28098,6 +28730,9 @@ var AgentGUIConversationRailQueryController = class {
28098
28730
  previousMembershipRecords;
28099
28731
  unsubscribeEngine = null;
28100
28732
  constructor(input) {
28733
+ this.diagnosticLogger = input.diagnosticLogger ?? createConversationRailDiagnosticLogger(input.runtime);
28734
+ this.diagnosticNow = input.diagnosticNow ?? Date.now;
28735
+ this.diagnosticSlowThresholdMs = input.diagnosticSlowThresholdMs ?? CONVERSATION_RAIL_SLOW_DIAGNOSTIC_THRESHOLD_MS;
28101
28736
  this.engine = input.engine;
28102
28737
  this.getActiveConversationId = input.getActiveConversationId;
28103
28738
  this.runtime = input.runtime;
@@ -28115,7 +28750,7 @@ var AgentGUIConversationRailQueryController = class {
28115
28750
  this.unsubscribeEngine = this.engine.subscribe((state) => {
28116
28751
  this.handleEngineState(state);
28117
28752
  });
28118
- if (this.scope) this.refreshFirstPages();
28753
+ if (this.scope) this.refreshFirstPages("attach");
28119
28754
  if (this.searchQuery) this.requestSearch();
28120
28755
  return () => this.detach();
28121
28756
  }
@@ -28143,7 +28778,7 @@ var AgentGUIConversationRailQueryController = class {
28143
28778
  reconcilingSessionIds: []
28144
28779
  };
28145
28780
  this.emit();
28146
- if (this.attached) this.refreshFirstPages();
28781
+ if (this.attached) this.refreshFirstPages("scope_change");
28147
28782
  if (this.searchQuery) this.requestSearch();
28148
28783
  }
28149
28784
  setSearchQuery(value) {
@@ -28313,9 +28948,9 @@ var AgentGUIConversationRailQueryController = class {
28313
28948
  )
28314
28949
  };
28315
28950
  this.emit();
28316
- this.refreshFirstPages();
28951
+ this.refreshFirstPages("membership_change");
28317
28952
  }
28318
- refreshFirstPages() {
28953
+ refreshFirstPages(refreshReason) {
28319
28954
  const listSections = this.runtime.listSessionSections;
28320
28955
  const scopeKey = this.railSectionQueryKey;
28321
28956
  if (!this.runtimeSectionsEnabled() || !listSections || !scopeKey) {
@@ -28325,6 +28960,7 @@ var AgentGUIConversationRailQueryController = class {
28325
28960
  }
28326
28961
  this.pagingRequestSequence += 1;
28327
28962
  const requestSequence = this.pagingRequestSequence;
28963
+ const requestStartedAt = this.diagnosticNow();
28328
28964
  const wasResolvedForScope = this.queryState.resolvedScopeKey === scopeKey && this.queryState.sections !== null;
28329
28965
  this.cancelPagingRequests(false);
28330
28966
  const abortController = new AbortController();
@@ -28343,6 +28979,7 @@ var AgentGUIConversationRailQueryController = class {
28343
28979
  if (abortController.signal.aborted || requestSequence !== this.pagingRequestSequence || scopeKey !== this.railSectionQueryKey) {
28344
28980
  return;
28345
28981
  }
28982
+ const requestResolvedAt = this.diagnosticNow();
28346
28983
  const sections = projectRuntimeSectionsToConversationRailMemberships({
28347
28984
  pinned: page.pinned,
28348
28985
  sections: page.sections
@@ -28366,10 +29003,44 @@ var AgentGUIConversationRailQueryController = class {
28366
29003
  sections
28367
29004
  };
28368
29005
  this.emit();
28369
- }).catch(() => {
29006
+ const completedAt = this.diagnosticNow();
29007
+ emitConversationRailFirstPagesDiagnostic({
29008
+ agentTargetId: this.sectionAgentTargetId || null,
29009
+ controllerApplyMs: Math.max(0, completedAt - requestResolvedAt),
29010
+ diagnosticLogger: this.diagnosticLogger,
29011
+ diagnosticSlowThresholdMs: this.diagnosticSlowThresholdMs,
29012
+ durationMs: Math.max(0, completedAt - requestStartedAt),
29013
+ requestId: requestSequence,
29014
+ requestMs: Math.max(0, requestResolvedAt - requestStartedAt),
29015
+ refreshReason,
29016
+ returnedSessionCount: (page.pinned?.sessions.length ?? 0) + page.sections.reduce(
29017
+ (count, section) => count + section.sessions.length,
29018
+ 0
29019
+ ),
29020
+ sectionCount: page.sections.length + (page.pinned ? 1 : 0),
29021
+ status: "ready",
29022
+ workspaceId: this.workspaceId
29023
+ });
29024
+ }).catch((error) => {
28370
29025
  if (abortController.signal.aborted || requestSequence !== this.pagingRequestSequence || scopeKey !== this.railSectionQueryKey) {
28371
29026
  return;
28372
29027
  }
29028
+ const failedAt = this.diagnosticNow();
29029
+ emitConversationRailFirstPagesDiagnostic({
29030
+ agentTargetId: this.sectionAgentTargetId || null,
29031
+ controllerApplyMs: 0,
29032
+ diagnosticLogger: this.diagnosticLogger,
29033
+ diagnosticSlowThresholdMs: this.diagnosticSlowThresholdMs,
29034
+ durationMs: Math.max(0, failedAt - requestStartedAt),
29035
+ error,
29036
+ requestId: requestSequence,
29037
+ requestMs: Math.max(0, failedAt - requestStartedAt),
29038
+ refreshReason,
29039
+ returnedSessionCount: 0,
29040
+ sectionCount: 0,
29041
+ status: "error",
29042
+ workspaceId: this.workspaceId
29043
+ });
28373
29044
  this.queryState = wasResolvedForScope ? {
28374
29045
  ...this.queryState,
28375
29046
  pending: false,
@@ -28584,7 +29255,7 @@ function useAgentGUIConversationRailQuery({
28584
29255
  () => runtime.getSessionEngine(workspaceId),
28585
29256
  [runtime, workspaceId]
28586
29257
  );
28587
- const activeConversationIdRef = useRef34(activeConversationId);
29258
+ const activeConversationIdRef = useRef35(activeConversationId);
28588
29259
  activeConversationIdRef.current = activeConversationId;
28589
29260
  const controller = useMemo33(
28590
29261
  () => new AgentGUIConversationRailQueryController({
@@ -28617,6 +29288,12 @@ function useAgentGUIConversationRailQuery({
28617
29288
  identitySnapshot,
28618
29289
  Object.is
28619
29290
  );
29291
+ const selectRuntimeRailConversations = useMemo33(
29292
+ () => createRuntimeRailConversationsSelector(
29293
+ createAgentGUIConversationRailTitlePromptSelector()
29294
+ ),
29295
+ []
29296
+ );
28620
29297
  const runtimeRailConversations = useEngineSelector(
28621
29298
  engine,
28622
29299
  selectRuntimeRailConversations,
@@ -28637,9 +29314,10 @@ function useAgentGUIConversationRailQuery({
28637
29314
  [controller, querySnapshot, runtimeRailConversations]
28638
29315
  );
28639
29316
  }
28640
- function selectRuntimeRailConversations(state) {
28641
- return projectCanonicalAgentGUIConversationSummaries(
28642
- selectWorkspaceAgentConsumerSessions4(state)
29317
+ function createRuntimeRailConversationsSelector(selectTitlePrompts) {
29318
+ return (state) => projectCanonicalAgentGUIConversationSummaries(
29319
+ selectWorkspaceAgentConsumerSessions4(state),
29320
+ selectTitlePrompts(state)
28643
29321
  );
28644
29322
  }
28645
29323
  function conversationSummaryListsRenderEqual(left, right) {
@@ -28684,13 +29362,13 @@ import {
28684
29362
  useCallback as useCallback45,
28685
29363
  useEffect as useEffect34,
28686
29364
  useMemo as useMemo35,
28687
- useRef as useRef37,
29365
+ useRef as useRef38,
28688
29366
  useState as useState33
28689
29367
  } from "react";
28690
29368
  import { ScrollArea as ScrollArea2 } from "@tutti-os/ui-system/components";
28691
29369
 
28692
29370
  // agent-gui/agentGuiNode/view/agentGUIDetailModelHelpers.ts
28693
- import { useRef as useRef35 } from "react";
29371
+ import { useRef as useRef36 } from "react";
28694
29372
  function commandAppSource(command) {
28695
29373
  if (!command || typeof command !== "object" || !("source" in command)) {
28696
29374
  return null;
@@ -28770,7 +29448,7 @@ function slashStatusesEqual(left, right) {
28770
29448
  return (left.agentSessionId ?? null) === (right.agentSessionId ?? null) && (left.baseUrl ?? null) === (right.baseUrl ?? null) && (left.contextWindow?.usedTokens ?? null) === (right.contextWindow?.usedTokens ?? null) && (left.contextWindow?.totalTokens ?? null) === (right.contextWindow?.totalTokens ?? null) && slashStatusLimitsEqual(left.limits, right.limits) && Boolean(left.limitsLoading) === Boolean(right.limitsLoading) && Boolean(left.limitsUnavailable) === Boolean(right.limitsUnavailable);
28771
29449
  }
28772
29450
  function useStableSlashStatus(status) {
28773
- const statusRef = useRef35(null);
29451
+ const statusRef = useRef36(null);
28774
29452
  if (statusRef.current === null || !slashStatusesEqual(statusRef.current, status)) {
28775
29453
  statusRef.current = status;
28776
29454
  }
@@ -29100,8 +29778,8 @@ var AgentGUIBottomDockPane = memo9(function AgentGUIBottomDockPane2({
29100
29778
  "use memo";
29101
29779
  const previewMode = composerProps.previewMode === true;
29102
29780
  const goal = objectRecord(sessionChrome.rawState?.goal);
29103
- const goalObjective = goal ? stringValue2(goal.objective) : "";
29104
- const goalStatus = goal ? stringValue2(goal.status) : "";
29781
+ const goalObjective = goal ? stringValue3(goal.objective) : "";
29782
+ const goalStatus = goal ? stringValue3(goal.status) : "";
29105
29783
  const goalTokenBudget = goal ? numberValue(goal.tokenBudget) : null;
29106
29784
  const goalTokensUsed = goal ? numberValue(goal.tokensUsed) : null;
29107
29785
  const goalTimeUsedSeconds = goal ? numberValue(goal.timeUsedSeconds) : null;
@@ -29215,7 +29893,7 @@ var AgentGUIBottomDockPane = memo9(function AgentGUIBottomDockPane2({
29215
29893
  // agent-gui/agentGuiNode/view/AgentGUIDetailHeader.tsx
29216
29894
  import { memo as memo10 } from "react";
29217
29895
  import { Info as Info2 } from "lucide-react";
29218
- import { Tooltip as Tooltip8, TooltipContent as TooltipContent8, TooltipTrigger as TooltipTrigger8 } from "@tutti-os/ui-system";
29896
+ import { Tooltip as Tooltip7, TooltipContent as TooltipContent7, TooltipTrigger as TooltipTrigger7 } from "@tutti-os/ui-system";
29219
29897
  import { jsx as jsx53, jsxs as jsxs38 } from "react/jsx-runtime";
29220
29898
  var AgentGUIDetailHeader = memo10(function AgentGUIDetailHeader2({
29221
29899
  activeConversation,
@@ -29251,10 +29929,10 @@ function AgentRunPathInfo({
29251
29929
  if (previewMode) {
29252
29930
  return trigger;
29253
29931
  }
29254
- return /* @__PURE__ */ jsxs38(Tooltip8, { children: [
29255
- /* @__PURE__ */ jsx53(TooltipTrigger8, { asChild: true, children: trigger }),
29932
+ return /* @__PURE__ */ jsxs38(Tooltip7, { children: [
29933
+ /* @__PURE__ */ jsx53(TooltipTrigger7, { asChild: true, children: trigger }),
29256
29934
  /* @__PURE__ */ jsx53(
29257
- TooltipContent8,
29935
+ TooltipContent7,
29258
29936
  {
29259
29937
  side: "top",
29260
29938
  align: "start",
@@ -29369,7 +30047,7 @@ import {
29369
30047
  useCallback as useCallback44,
29370
30048
  useEffect as useEffect33,
29371
30049
  useLayoutEffect as useLayoutEffect7,
29372
- useRef as useRef36,
30050
+ useRef as useRef37,
29373
30051
  useState as useState31
29374
30052
  } from "react";
29375
30053
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
@@ -29391,8 +30069,8 @@ function useAgentGUIDetailScroll(input) {
29391
30069
  } = input;
29392
30070
  const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState31(true);
29393
30071
  const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState31(true);
29394
- const bottomLockOwnerRef = useRef36(null);
29395
- const userScrollAwayIntentConversationRef = useRef36(null);
30072
+ const bottomLockOwnerRef = useRef37(null);
30073
+ const userScrollAwayIntentConversationRef = useRef37(null);
29396
30074
  useLayoutEffect7(() => {
29397
30075
  const timeline = timelineRef.current;
29398
30076
  if (!timeline) {
@@ -30312,8 +30990,8 @@ function mergeWorkspaceAppIconsFromCommands(input) {
30312
30990
  if (!source) {
30313
30991
  continue;
30314
30992
  }
30315
- const appId = stringValue2(source.appId).trim();
30316
- const iconUrl = stringValue2(source.iconUrl).trim();
30993
+ const appId = stringValue3(source.appId).trim();
30994
+ const iconUrl = stringValue3(source.iconUrl).trim();
30317
30995
  if (!appId || !iconUrl) {
30318
30996
  continue;
30319
30997
  }
@@ -30365,11 +31043,11 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30365
31043
  renderProviderUnavailableState
30366
31044
  }) {
30367
31045
  "use memo";
30368
- const timelineRef = useRef37(null);
30369
- const bottomDockRef = useRef37(null);
30370
- const timelineScrollAnchorRef = useRef37(null);
30371
- const submittedPromptScrollConversationRef = useRef37(null);
30372
- const pendingPrependScrollAnchorRef = useRef37(null);
31046
+ const timelineRef = useRef38(null);
31047
+ const bottomDockRef = useRef38(null);
31048
+ const timelineScrollAnchorRef = useRef38(null);
31049
+ const submittedPromptScrollConversationRef = useRef38(null);
31050
+ const pendingPrependScrollAnchorRef = useRef38(null);
30373
31051
  const [
30374
31052
  bottomDockDismissedPromptRequestId,
30375
31053
  setBottomDockDismissedPromptRequestId
@@ -30510,7 +31188,6 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30510
31188
  );
30511
31189
  const stableRequestGitBranches = useOptionalStableEventCallback(onRequestGitBranches);
30512
31190
  const authLogin = useOptionalStableEventCallback(onAgentProviderLogin);
30513
- const backgroundAgentStatusText = viewModel.detail.backgroundAgentCount > 0 ? labels.waitingForBackgroundAgent(viewModel.detail.backgroundAgentCount) : null;
30514
31191
  const submitBottomDockInteractivePrompt = useCallback45(
30515
31192
  (input) => {
30516
31193
  submitInteractivePrompt(input);
@@ -30593,7 +31270,6 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30593
31270
  referenceProvenanceFilter,
30594
31271
  // Plan decisions replace the composer; approval / ask-user embed here.
30595
31272
  activePrompt: composerActivePrompt,
30596
- backgroundAgentStatusText,
30597
31273
  activePromptKeyboardShortcutsEnabled: isActive,
30598
31274
  promptTips: labels.promptTips,
30599
31275
  composerFocusRequestSequence,
@@ -30631,7 +31307,6 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30631
31307
  }),
30632
31308
  [
30633
31309
  canQueueWhileBusy,
30634
- backgroundAgentStatusText,
30635
31310
  capabilityMenuState,
30636
31311
  canSwitchComposerProvider,
30637
31312
  composerDisabled,
@@ -30723,7 +31398,6 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30723
31398
  sessionChrome.auth?.message ?? "",
30724
31399
  sessionChrome.recovery?.kind ?? "",
30725
31400
  sessionChrome.recovery?.message ?? "",
30726
- backgroundAgentStatusText ?? "",
30727
31401
  viewModel.composer.queuedPrompts.map((prompt) => prompt.id).join(","),
30728
31402
  viewModel.composer.queueStatus,
30729
31403
  viewModel.composer.drainingQueuedPromptId ?? "",
@@ -30868,7 +31542,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
30868
31542
  });
30869
31543
 
30870
31544
  // agent-gui/agentGuiNode/view/AgentGUIRenameConversationDialog.tsx
30871
- import { memo as memo13, useCallback as useCallback46, useEffect as useEffect35, useRef as useRef38, useState as useState34 } from "react";
31545
+ import { memo as memo13, useCallback as useCallback46, useEffect as useEffect35, useRef as useRef39, useState as useState34 } from "react";
30872
31546
  import { ConfirmationDialog as ConfirmationDialog2 } from "@tutti-os/ui-system";
30873
31547
  import { jsx as jsx59, jsxs as jsxs43 } from "react/jsx-runtime";
30874
31548
  var AgentGUIRenameConversationDialog = memo13(
@@ -30882,9 +31556,9 @@ var AgentGUIRenameConversationDialog = memo13(
30882
31556
  "use memo";
30883
31557
  const [title, setTitle] = useState34("");
30884
31558
  const [isSaving, setIsSaving] = useState34(false);
30885
- const isSavingRef = useRef38(false);
30886
- const armedPointerActionRef = useRef38(null);
30887
- const inputRef = useRef38(null);
31559
+ const isSavingRef = useRef39(false);
31560
+ const armedPointerActionRef = useRef39(null);
31561
+ const inputRef = useRef39(null);
30888
31562
  const trimmedTitle = title.trim();
30889
31563
  useEffect35(() => {
30890
31564
  if (!open || !conversation) {
@@ -31112,7 +31786,7 @@ function AgentGUIReferencePickerSurface({
31112
31786
  }
31113
31787
 
31114
31788
  // agent-gui/agentGuiNode/view/useAgentGUIWorkspaceReferencePicker.ts
31115
- import { useCallback as useCallback47, useMemo as useMemo36, useRef as useRef39, useState as useState35 } from "react";
31789
+ import { useCallback as useCallback47, useMemo as useMemo36, useRef as useRef40, useState as useState35 } from "react";
31116
31790
  import { createRichTextMentionHref } from "@tutti-os/ui-rich-text/core";
31117
31791
  function useAgentGUIWorkspaceReferencePicker(input) {
31118
31792
  const {
@@ -31127,7 +31801,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
31127
31801
  } = input;
31128
31802
  const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState35(false);
31129
31803
  const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState35(null);
31130
- const workspaceReferencePickerResolverRef = useRef39(null);
31804
+ const workspaceReferencePickerResolverRef = useRef40(null);
31131
31805
  const emptyReferencePickResult = useMemo36(
31132
31806
  () => ({ files: [], mentionItems: [] }),
31133
31807
  []
@@ -31242,7 +31916,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
31242
31916
  }
31243
31917
 
31244
31918
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
31245
- import { useRef as useRef41 } from "react";
31919
+ import { useRef as useRef42 } from "react";
31246
31920
 
31247
31921
  // agent-gui/agentGuiNode/engagement/projectAgentGUIEngagementContext.ts
31248
31922
  function projectAgentGUIEngagementContext(viewModel, composerReady) {
@@ -31274,7 +31948,7 @@ function createAgentGUIEngagementContextKey(input) {
31274
31948
  }
31275
31949
 
31276
31950
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
31277
- import { useEffect as useEffect36, useRef as useRef40 } from "react";
31951
+ import { useEffect as useEffect36, useRef as useRef41 } from "react";
31278
31952
 
31279
31953
  // agent-gui/agentGuiNode/engagement/AgentGUIPanelEngagementController.ts
31280
31954
  var AGENT_GUI_PANEL_EXPOSURE_DWELL_MS = 1e3;
@@ -31428,10 +32102,10 @@ function documentIsVisible() {
31428
32102
 
31429
32103
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
31430
32104
  function useAgentGUIPanelEngagement(input) {
31431
- const inputRef = useRef40(input);
31432
- const controllerRef = useRef40(null);
31433
- const intersectionRatioRef = useRef40(0);
31434
- const engagementRef = useRef40(null);
32105
+ const inputRef = useRef41(input);
32106
+ const controllerRef = useRef41(null);
32107
+ const intersectionRatioRef = useRef41(0);
32108
+ const engagementRef = useRef41(null);
31435
32109
  inputRef.current = input;
31436
32110
  if (!engagementRef.current) {
31437
32111
  engagementRef.current = {
@@ -31471,7 +32145,7 @@ function useAgentGUIPanelEngagement(input) {
31471
32145
 
31472
32146
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
31473
32147
  function useAgentGUINodeEngagement(input) {
31474
- const layoutElementRef = useRef41(null);
32148
+ const layoutElementRef = useRef42(null);
31475
32149
  const projected = projectAgentGUIEngagementContext(
31476
32150
  input.viewModel,
31477
32151
  input.composerReady
@@ -31560,7 +32234,7 @@ function AgentGUINodeView({
31560
32234
  viewModel
31561
32235
  });
31562
32236
  const [providerManagerOpen, setProviderManagerOpen] = useState36(false);
31563
- const railResizeInteractionRef = useRef42(null);
32237
+ const railResizeInteractionRef = useRef43(null);
31564
32238
  const [isRailResizing, setIsRailResizing] = useState36(false);
31565
32239
  const [railResizeWidthPx, setRailResizeWidthPx] = useState36(
31566
32240
  null
@@ -31569,7 +32243,7 @@ function AgentGUINodeView({
31569
32243
  localComposerFocusRequestSequence,
31570
32244
  setLocalComposerFocusRequestSequence
31571
32245
  ] = useState36(0);
31572
- const handledNewConversationRequestSequenceRef = useRef42(
32246
+ const handledNewConversationRequestSequenceRef = useRef43(
31573
32247
  newConversationRequestSequence
31574
32248
  );
31575
32249
  const {
@@ -32136,7 +32810,7 @@ function AgentGUINodeView({
32136
32810
  }
32137
32811
  )
32138
32812
  ] });
32139
- return previewMode ? content : /* @__PURE__ */ jsx61(TooltipProvider5, { children: content });
32813
+ return previewMode ? content : /* @__PURE__ */ jsx61(TooltipProvider4, { children: content });
32140
32814
  }
32141
32815
 
32142
32816
  // agent-gui/workspaceDesktop/view/desktopDockAgentProbeTooltipModel.ts
@@ -32313,7 +32987,7 @@ import {
32313
32987
  useCallback as useCallback49,
32314
32988
  useEffect as useEffect38,
32315
32989
  useLayoutEffect as useLayoutEffect9,
32316
- useRef as useRef43,
32990
+ useRef as useRef44,
32317
32991
  useState as useState37
32318
32992
  } from "react";
32319
32993
  import { createPortal as createPortal5 } from "react-dom";
@@ -32351,8 +33025,8 @@ function AgentProbeInfoPopover({
32351
33025
  onOpen
32352
33026
  }) {
32353
33027
  "use memo";
32354
- const anchorRef = useRef43(null);
32355
- const popoverRef = useRef43(null);
33028
+ const anchorRef = useRef44(null);
33029
+ const popoverRef = useRef44(null);
32356
33030
  const [isOpen, setIsOpen] = useState37(false);
32357
33031
  const [popoverStyle, setPopoverStyle] = useState37(null);
32358
33032
  const openPopover = useCallback49(() => {
@@ -33065,10 +33739,6 @@ function useAgentGUIViewLabels(input) {
33065
33739
  submitAnswers: t("agentHost.agentGui.submitAnswers"),
33066
33740
  answerPlaceholder: t("agentHost.agentGui.answerPlaceholder"),
33067
33741
  waitingForAnswer: t("agentHost.agentGui.waitingForAnswer"),
33068
- waitingForBackgroundAgent: (count) => {
33069
- const pluralKey = count === 1 ? "agentHost.agentGui.waitingForBackgroundAgent_one" : "agentHost.agentGui.waitingForBackgroundAgent_other";
33070
- return t(pluralKey, { count });
33071
- },
33072
33742
  thinkingLabel: t("agentHost.workspaceAgentSessionDetailThinking"),
33073
33743
  toolCallsLabel: (count) => t("agentHost.workspaceAgentSessionDetailToolCalls", { count }),
33074
33744
  openConversationWindow: t("agentHost.agentGui.openConversationWindow"),
@@ -33969,7 +34639,7 @@ var AgentGUI = memo15(function AgentGUI2({
33969
34639
  children: /* @__PURE__ */ jsx64(AgentGUINode, { ...nodeProps })
33970
34640
  }
33971
34641
  ) });
33972
- return props.frame.previewMode ? content : /* @__PURE__ */ jsx64(TooltipProvider6, { delayDuration: 120, skipDelayDuration: 0, children: content });
34642
+ return props.frame.previewMode ? content : /* @__PURE__ */ jsx64(TooltipProvider5, { delayDuration: 120, skipDelayDuration: 0, children: content });
33973
34643
  });
33974
34644
 
33975
34645
  export {
@@ -33982,4 +34652,4 @@ export {
33982
34652
  resolveAgentGUIAgentTarget,
33983
34653
  AgentGUI
33984
34654
  };
33985
- //# sourceMappingURL=chunk-L2MTZMVH.js.map
34655
+ //# sourceMappingURL=chunk-N3HTEYLZ.js.map