@tutti-os/agent-gui 0.0.233 → 0.0.235

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 (87) hide show
  1. package/README.md +49 -0
  2. package/dist/{AgentRichTextReadonly-U3XUJYCW.js → AgentRichTextReadonly-CCELQPHE.js} +5 -5
  3. package/dist/agent-conversation/index.d.ts +17 -4
  4. package/dist/agent-conversation/index.js +13 -9
  5. package/dist/agent-conversation/index.js.map +1 -1
  6. package/dist/agent-gui.d.ts +19 -3
  7. package/dist/agent-gui.js +22 -16
  8. package/dist/agent-message-center/index.d.ts +1 -1
  9. package/dist/agent-message-center/index.js +10 -7
  10. package/dist/agent-message-center/index.js.map +1 -1
  11. package/dist/{agentGuiNodeTypes-DW7T--Y8.d.ts → agentGuiNodeTypes-Dgl7kQHA.d.ts} +2 -2
  12. package/dist/agents.d.ts +1 -1
  13. package/dist/app/renderer/agentactivity.css +17 -0
  14. package/dist/{chunk-M6WEFXPL.js → chunk-2MCNNB2P.js} +2 -24
  15. package/dist/chunk-2MCNNB2P.js.map +1 -0
  16. package/dist/{chunk-CQFT3MI5.js → chunk-3YYI6RXA.js} +7 -5
  17. package/dist/{chunk-CQFT3MI5.js.map → chunk-3YYI6RXA.js.map} +1 -1
  18. package/dist/{chunk-EDP4D42H.js → chunk-45KN5Z5F.js} +877 -871
  19. package/dist/chunk-45KN5Z5F.js.map +1 -0
  20. package/dist/{chunk-T57ZZWTC.js → chunk-4HAG3FOY.js} +2 -2
  21. package/dist/{chunk-ZBI6R46N.js → chunk-5DN5N2XS.js} +2 -2
  22. package/dist/{chunk-BCBB4HOV.js → chunk-634MNSI5.js} +2 -2
  23. package/dist/chunk-A4KKC324.js +4768 -0
  24. package/dist/chunk-A4KKC324.js.map +1 -0
  25. package/dist/chunk-ALAGL6VL.js +48 -0
  26. package/dist/chunk-ALAGL6VL.js.map +1 -0
  27. package/dist/{chunk-2STAUA73.js → chunk-AYTUAZE3.js} +5 -2
  28. package/dist/chunk-AYTUAZE3.js.map +1 -0
  29. package/dist/{chunk-SWO67UWQ.js → chunk-CZOZBUIM.js} +7 -7
  30. package/dist/{chunk-SWO67UWQ.js.map → chunk-CZOZBUIM.js.map} +1 -1
  31. package/dist/{chunk-2L2LVSOD.js → chunk-EHNPHZE4.js} +881 -5812
  32. package/dist/chunk-EHNPHZE4.js.map +1 -0
  33. package/dist/{chunk-N5356722.js → chunk-EKQ7UX2B.js} +13 -319
  34. package/dist/chunk-EKQ7UX2B.js.map +1 -0
  35. package/dist/{chunk-ZXEICU6J.js → chunk-KK7YXPTS.js} +3 -1
  36. package/dist/chunk-KK7YXPTS.js.map +1 -0
  37. package/dist/{chunk-WGCDSA7P.js → chunk-MBM7PJIF.js} +27 -506
  38. package/dist/chunk-MBM7PJIF.js.map +1 -0
  39. package/dist/chunk-RMC2MGL4.js +557 -0
  40. package/dist/chunk-RMC2MGL4.js.map +1 -0
  41. package/dist/{chunk-JA6XAKKE.js → chunk-TWF6JXPC.js} +2 -2
  42. package/dist/{chunk-7AYFKNLD.js → chunk-TWMV6YTX.js} +4 -4
  43. package/dist/chunk-VV3YIU5W.js +25 -0
  44. package/dist/chunk-VV3YIU5W.js.map +1 -0
  45. package/dist/{chunk-GLVENTN6.js → chunk-WXLO33YP.js} +2 -2
  46. package/dist/chunk-XWPHTXEM.js +529 -0
  47. package/dist/chunk-XWPHTXEM.js.map +1 -0
  48. package/dist/chunk-YEXRTXTE.js +315 -0
  49. package/dist/chunk-YEXRTXTE.js.map +1 -0
  50. package/dist/{chunk-WMJDOMG6.js → chunk-ZELGKLW5.js} +4 -4
  51. package/dist/composer-projection.d.ts +37 -0
  52. package/dist/composer-projection.js +21 -0
  53. package/dist/composer-projection.js.map +1 -0
  54. package/dist/context-mention-palette/index.js +9 -7
  55. package/dist/conversation-projection.d.ts +551 -0
  56. package/dist/conversation-projection.js +42 -0
  57. package/dist/conversation-projection.js.map +1 -0
  58. package/dist/conversation-rail-projection.js +3 -3
  59. package/dist/i18n/index.d.ts +2 -0
  60. package/dist/i18n/index.js +2 -2
  61. package/dist/index.d.ts +32 -13
  62. package/dist/index.js +22 -16
  63. package/dist/index.js.map +1 -1
  64. package/dist/mention-search.js +7 -5
  65. package/dist/{types-CHAMK2g7.d.ts → types-DtXXsISB.d.ts} +1 -1
  66. package/dist/workbench/contribution.js +4 -4
  67. package/dist/workbench/index.js +4 -4
  68. package/dist/workbench/sessionTitle.js +3 -3
  69. package/dist/workspace-agent-generated-files.d.ts +1 -12
  70. package/dist/workspaceAgentActivityListTypes-BUKNyMbh.d.ts +48 -0
  71. package/dist/{workspaceLinkActions-CzsbvGmC.d.ts → workspaceLinkActions-DxyzMy10.d.ts} +13 -12
  72. package/package.json +29 -15
  73. package/dist/chunk-2L2LVSOD.js.map +0 -1
  74. package/dist/chunk-2STAUA73.js.map +0 -1
  75. package/dist/chunk-EDP4D42H.js.map +0 -1
  76. package/dist/chunk-M6WEFXPL.js.map +0 -1
  77. package/dist/chunk-N5356722.js.map +0 -1
  78. package/dist/chunk-WGCDSA7P.js.map +0 -1
  79. package/dist/chunk-ZXEICU6J.js.map +0 -1
  80. /package/dist/{AgentRichTextReadonly-U3XUJYCW.js.map → AgentRichTextReadonly-CCELQPHE.js.map} +0 -0
  81. /package/dist/{chunk-T57ZZWTC.js.map → chunk-4HAG3FOY.js.map} +0 -0
  82. /package/dist/{chunk-ZBI6R46N.js.map → chunk-5DN5N2XS.js.map} +0 -0
  83. /package/dist/{chunk-BCBB4HOV.js.map → chunk-634MNSI5.js.map} +0 -0
  84. /package/dist/{chunk-JA6XAKKE.js.map → chunk-TWF6JXPC.js.map} +0 -0
  85. /package/dist/{chunk-7AYFKNLD.js.map → chunk-TWMV6YTX.js.map} +0 -0
  86. /package/dist/{chunk-GLVENTN6.js.map → chunk-WXLO33YP.js.map} +0 -0
  87. /package/dist/{chunk-WMJDOMG6.js.map → chunk-ZELGKLW5.js.map} +0 -0
@@ -1,6 +1,14 @@
1
1
  import {
2
2
  projectCanonicalAgentGUIConversationSummaries
3
- } from "./chunk-ZBI6R46N.js";
3
+ } from "./chunk-5DN5N2XS.js";
4
+ import {
5
+ projectAgentApprovalPromptFromInteraction,
6
+ projectAgentInteractivePromptFromInteraction,
7
+ projectWorkspaceAgentMessagesToTimelineItems
8
+ } from "./chunk-RMC2MGL4.js";
9
+ import {
10
+ composerSettingsSupportFromOptions
11
+ } from "./chunk-ALAGL6VL.js";
4
12
  import {
5
13
  inspectAgentConversationBatchDeletionCapability
6
14
  } from "./chunk-LB4AGT7B.js";
@@ -10,7 +18,7 @@ import {
10
18
  import {
11
19
  AGENT_GUI_WORKBENCH_OPEN_EXTERNAL_IMPORT_EVENT,
12
20
  resolveAgentGuiSessionProviderFlatIconUrl
13
- } from "./chunk-7AYFKNLD.js";
21
+ } from "./chunk-TWMV6YTX.js";
14
22
  import {
15
23
  AGENT_PROVIDERS,
16
24
  AGENT_PROVIDER_LABEL,
@@ -26,7 +34,7 @@ import {
26
34
  resolveAgentGUIFirstUserMessageDisplayPrompt,
27
35
  resolveAgentGUIProviderDisplayLabel,
28
36
  resolveAgentGUIProviderIdentity
29
- } from "./chunk-JA6XAKKE.js";
37
+ } from "./chunk-TWF6JXPC.js";
30
38
  import {
31
39
  resolveAgentGuiWorkbenchProviderLabel
32
40
  } from "./chunk-MGSRWYRN.js";
@@ -41,7 +49,7 @@ import {
41
49
  normalizePlanIssueBudgetPreset,
42
50
  planImplementationPromptFromPlanTurn,
43
51
  planIssueBudgetPresetsEqual
44
- } from "./chunk-CQFT3MI5.js";
52
+ } from "./chunk-3YYI6RXA.js";
45
53
  import {
46
54
  useEngineSelector
47
55
  } from "./chunk-EVQ4JY3N.js";
@@ -49,38 +57,20 @@ import {
49
57
  AgentConversationFlow,
50
58
  AgentVisibleErrorPresentationProvider,
51
59
  Button,
52
- MAX_AGENT_COMPOSER_DRAFT_IMAGES,
53
- agentComposerDraftAttachmentProjection,
54
- agentComposerDraftFiles,
55
- agentComposerDraftHasContent,
56
- agentComposerDraftImages,
57
- agentComposerDraftLargeTexts,
58
- agentComposerDraftPrompt,
59
- agentPromptContentDisplayText,
60
- agentPromptContentHasImage,
61
- agentPromptContentImageBlocks,
62
- agentPromptContentToComposerDraft,
63
- buildAgentComposerDraft,
64
60
  buildWorkspaceAgentSessionDetailViewModel,
65
- emptyAgentComposerDraft,
66
61
  getAppErrorCode,
67
- isWorkspaceAgentToolCallItem,
68
- latestAssistantMessageText,
69
62
  loadCompleteAgentConversationMessages,
70
- materializePastedTextInstructions,
71
- normalizeAgentPromptContentBlocks,
72
- pastedTextPreview,
73
- projectAgentComposerDraftSubmission,
74
- projectAgentConversationVM,
75
- resolveWorkspaceAgentNoticeCommandSemantics,
76
- resolveWorkspaceAgentToolName,
77
63
  serializeAgentConversationForClipboard,
78
- snapshotAgentComposerDraft,
79
- textPromptContent,
80
64
  toLocalShortDateTime,
81
- updateAgentComposerDraft,
82
65
  useProjectedAgentConversation
83
- } from "./chunk-2L2LVSOD.js";
66
+ } from "./chunk-EHNPHZE4.js";
67
+ import {
68
+ isWorkspaceAgentToolCallItem,
69
+ latestAssistantMessageText,
70
+ pastedTextDraftDisplayName,
71
+ projectAgentConversationVM,
72
+ resolveWorkspaceAgentToolName
73
+ } from "./chunk-A4KKC324.js";
84
74
  import {
85
75
  agentRichTextContentToPromptText,
86
76
  createAgentRichTextInputExtensions,
@@ -88,16 +78,16 @@ import {
88
78
  labelForProviderSkill,
89
79
  plainTextToAgentRichTextDoc,
90
80
  plainTextToAgentRichTextInlineContent,
81
+ promptForProviderSkills,
91
82
  skillDescriptionForDisplay,
92
83
  skillTriggerForPrefix
93
- } from "./chunk-2STAUA73.js";
84
+ } from "./chunk-AYTUAZE3.js";
94
85
  import {
95
86
  AgentMessageMarkdown,
96
87
  ZoomableImage,
97
88
  blobToBase64,
98
- normalizeAgentApprovalPurpose,
99
89
  resolveWorkspaceLinkAction
100
- } from "./chunk-WGCDSA7P.js";
90
+ } from "./chunk-MBM7PJIF.js";
101
91
  import {
102
92
  AgentTargetPresentationProvider,
103
93
  cn,
@@ -118,7 +108,7 @@ import {
118
108
  AgentFileMentionPalette,
119
109
  agentMentionItemKey,
120
110
  isAgentMentionItemDisabled
121
- } from "./chunk-WMJDOMG6.js";
111
+ } from "./chunk-ZELGKLW5.js";
122
112
  import {
123
113
  normalizeAgentGUIAgents,
124
114
  projectAgentGUIAgentsToTargets
@@ -137,9 +127,11 @@ import {
137
127
  AGENT_MENTION_FILTER_TAB_ORDER,
138
128
  AgentMentionSearchController,
139
129
  DEFAULT_AGENT_MENTION_FILTER,
140
- agentGuiScheduler,
130
+ agentGuiScheduler
131
+ } from "./chunk-EKQ7UX2B.js";
132
+ import {
141
133
  buildWorkspaceAgentActivityListViewModel
142
- } from "./chunk-N5356722.js";
134
+ } from "./chunk-YEXRTXTE.js";
143
135
  import {
144
136
  resolveWorkspaceAgentSessionSortTimeUnixMs
145
137
  } from "./chunk-YMXYBG7U.js";
@@ -147,19 +139,24 @@ import {
147
139
  AGENT_RICH_TEXT_CARET_ANCHOR,
148
140
  agentComposerFileMentionReferences,
149
141
  agentExternalPromptFileErrorI18nKey,
142
+ agentPreparedPromptFileToDraftFile,
143
+ agentPromptContentToComposerPrompt,
144
+ agentPromptFileBlocks,
145
+ agentPromptPastedTextBlocks,
150
146
  createAgentExternalPromptFilePreparation,
151
147
  createAgentSessionHandoffPrompt,
152
148
  createAgentSessionMarkdownLink,
153
149
  createAgentSessionMentionHref,
154
150
  exitAgentFileMentionSuggestion,
155
151
  formatAgentMentionMarkdown,
152
+ materializeAgentComposerFileMentions,
156
153
  materializeAgentCustomMentionPromptText,
157
154
  mentionItemToAttrs,
158
155
  normalizeAgentSessionMentionTitle,
159
156
  parseMentionItemFromHref,
160
157
  remainingAgentComposerPromptAssetSlots,
161
158
  updateAgentComposerFileMentions
162
- } from "./chunk-SWO67UWQ.js";
159
+ } from "./chunk-CZOZBUIM.js";
163
160
  import {
164
161
  AgentActivityHostProvider,
165
162
  getOptionalAgentHostApi,
@@ -168,7 +165,7 @@ import {
168
165
  useAgentHostApi,
169
166
  useOptionalAgentActivityRuntime,
170
167
  useOptionalAgentHostApi
171
- } from "./chunk-M6WEFXPL.js";
168
+ } from "./chunk-2MCNNB2P.js";
172
169
  import {
173
170
  MANAGED_AGENT_ICON_FALLBACK_URL,
174
171
  MANAGED_AGENT_ICON_URLS,
@@ -178,11 +175,15 @@ import {
178
175
  AgentGuiI18nProvider,
179
176
  translate,
180
177
  useTranslation
181
- } from "./chunk-GLVENTN6.js";
178
+ } from "./chunk-WXLO33YP.js";
182
179
  import {
183
180
  isBetaAgentProvider,
184
181
  normalizeManagedAgentProvider
185
182
  } from "./chunk-AFUVWWQY.js";
183
+ import {
184
+ AGENT_PASTED_TEXT_BLOCK_KIND,
185
+ AGENT_PASTED_TEXT_MENTION_KIND
186
+ } from "./chunk-FGLQZ6I4.js";
186
187
  import {
187
188
  agentColorfulUrl,
188
189
  resolveProviderIconAsset
@@ -199,7 +200,7 @@ import { memo as memo15, useMemo as useMemo52 } from "react";
199
200
  import { TooltipProvider as TooltipProvider8 } from "@tutti-os/ui-system";
200
201
 
201
202
  // agent-gui/agentGuiNode/AgentGUINode.tsx
202
- import { memo as memo14, useCallback as useCallback68, useMemo as useMemo51, useRef as useRef62 } from "react";
203
+ import { memo as memo14, useCallback as useCallback68, useMemo as useMemo51, useRef as useRef63 } from "react";
203
204
  import { createWorkspaceUserProjectI18nRuntime } from "@tutti-os/workspace-user-project/i18n";
204
205
  import { createWorkspaceFileManagerI18nRuntime } from "@tutti-os/workspace-file-manager";
205
206
 
@@ -2171,440 +2172,6 @@ function mergeProfilesIntoSnapshot(snapshot, users) {
2171
2172
  };
2172
2173
  }
2173
2174
 
2174
- // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
2175
- var tuttiPlanIssueDispatchTriggerPrefix = "issue:tutti-mode-plan-";
2176
- function isTuttiPlanIssueDispatchCollaboration(message) {
2177
- if (message.kind?.trim() !== "collaboration") {
2178
- return false;
2179
- }
2180
- const triggerReason = message.payload?.triggerReason;
2181
- return typeof triggerReason === "string" && triggerReason.startsWith(tuttiPlanIssueDispatchTriggerPrefix);
2182
- }
2183
- function projectWorkspaceAgentMessagesToTimelineItems(messages) {
2184
- const sortedMessages = latestMessageSnapshots(messages).filter((message) => !isTuttiPlanIssueDispatchCollaboration(message)).sort(compareMessagesByDisplayOrder);
2185
- const mergedToolPayloadByKey = /* @__PURE__ */ new Map();
2186
- return sortedMessages.map((message, index) => {
2187
- const kind = normalizeToken(message.kind);
2188
- const role = normalizeToken(message.role);
2189
- const payload = normalizedPayload(message.payload);
2190
- const goalControlAudit = isGoalControlAudit(message);
2191
- const id = normalizedMessageId(message.version, index);
2192
- const seq = index + 1;
2193
- const eventId = goalControlAudit ? firstNonEmptyString(
2194
- stringValue(payload.messageId),
2195
- message.messageId,
2196
- `message:${id}`
2197
- ) : message.messageId.trim() || `message:${id}`;
2198
- const turnId = message.turnId?.trim() || void 0;
2199
- const occurredAtUnixMs = messageDisplayOrderTime(message);
2200
- if (goalControlAudit) {
2201
- return messageTimelineItem({
2202
- message,
2203
- id,
2204
- seq,
2205
- eventId,
2206
- actorType: "user",
2207
- itemType: "goal.control",
2208
- role: "user",
2209
- content: messageText(message),
2210
- occurredAtUnixMs
2211
- });
2212
- }
2213
- if (kind === "tool_call") {
2214
- const callId = firstNonEmptyString(
2215
- messagePayloadString(message, "callId"),
2216
- message.messageId
2217
- );
2218
- const title = messagePayloadString(message, "title");
2219
- const toolKey = callId || eventId;
2220
- const payloadToolName = displayToolNameCandidate(
2221
- stringValue(payload.toolName),
2222
- callId
2223
- );
2224
- const titleToolName = displayToolNameCandidate(title, callId);
2225
- const toolName = firstNonEmptyString(payloadToolName, titleToolName);
2226
- const toolPayload = sanitizedToolPayload(payload, callId);
2227
- const mergedPayload = mergePayload(mergedToolPayloadByKey.get(toolKey), {
2228
- ...toolPayload,
2229
- ...toolName ? { toolName } : {},
2230
- ...message.status?.trim() ? { status: message.status.trim() } : {}
2231
- });
2232
- mergedToolPayloadByKey.set(toolKey, mergedPayload);
2233
- const callType = firstNonEmptyString(stringValue(mergedPayload.callType)) || "tool";
2234
- const workspaceId = workspaceIdFromMessage(message);
2235
- return {
2236
- id,
2237
- ...workspaceTimelineFields(workspaceId),
2238
- agentSessionId: message.agentSessionId,
2239
- seq,
2240
- ...turnId ? { turnId } : {},
2241
- eventId,
2242
- actorType: "agent",
2243
- actorId: message.agentSessionId,
2244
- itemType: toolCallItemType(message.status ?? void 0),
2245
- role: "assistant",
2246
- callType,
2247
- callId,
2248
- name: firstNonEmptyString(toolName, titleToolName) || "Tool",
2249
- ...message.status !== void 0 ? { status: message.status } : {},
2250
- payload: mergedPayload,
2251
- ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
2252
- ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
2253
- };
2254
- }
2255
- if (kind === "collaboration") {
2256
- return messageTimelineItem({
2257
- message,
2258
- id,
2259
- seq,
2260
- eventId,
2261
- turnId,
2262
- actorType: "agent",
2263
- itemType: "collaboration",
2264
- role: "assistant",
2265
- content: messagePayloadString(message, "resultText") ?? "",
2266
- occurredAtUnixMs
2267
- });
2268
- }
2269
- if (kind === "reasoning") {
2270
- return messageTimelineItem({
2271
- message,
2272
- id,
2273
- seq,
2274
- eventId,
2275
- turnId,
2276
- actorType: "agent",
2277
- itemType: "message.assistant_thinking",
2278
- role: "assistant_thinking",
2279
- content: messageText(message),
2280
- occurredAtUnixMs
2281
- });
2282
- }
2283
- if ((kind === "text" || kind === "session_audit") && role === "user") {
2284
- return messageTimelineItem({
2285
- message,
2286
- id,
2287
- seq,
2288
- eventId,
2289
- turnId,
2290
- actorType: "user",
2291
- itemType: "message.user",
2292
- role: "user",
2293
- content: messageText(message),
2294
- occurredAtUnixMs
2295
- });
2296
- }
2297
- if (kind === "text" && (role === "assistant" || role === "agent")) {
2298
- const projectedMessage = normalizeLegacyCompactNotice(message, payload);
2299
- return messageTimelineItem({
2300
- message: projectedMessage,
2301
- id,
2302
- seq,
2303
- eventId,
2304
- turnId,
2305
- actorType: "agent",
2306
- itemType: "message.assistant",
2307
- role: "assistant",
2308
- content: messageText(projectedMessage),
2309
- occurredAtUnixMs
2310
- });
2311
- }
2312
- const statusTurnId = turnId ?? `session-status:${kind === "error" ? "error" : "notice"}`;
2313
- const statusMessage = {
2314
- ...message,
2315
- payload: kind === "error" ? {
2316
- ...payload,
2317
- detail: messageText(message),
2318
- kind: "agent_visible_error"
2319
- } : {
2320
- ...payload,
2321
- detail: messageText(message),
2322
- kind: "agent_system_notice",
2323
- noticeKind: kind,
2324
- severity: "info"
2325
- }
2326
- };
2327
- return messageTimelineItem({
2328
- message: statusMessage,
2329
- id,
2330
- seq,
2331
- eventId,
2332
- turnId: statusTurnId,
2333
- actorType: role === "user" ? "user" : "agent",
2334
- itemType: role === "user" ? "message.user" : "message.assistant",
2335
- role: role === "user" ? "user" : "assistant",
2336
- content: statusMessageText(statusMessage),
2337
- occurredAtUnixMs
2338
- });
2339
- });
2340
- }
2341
- function isGoalControlAudit(message) {
2342
- return normalizeToken(message.kind) === "session_audit" && normalizedPayload(message.payload).goalControl === true;
2343
- }
2344
- function normalizeLegacyCompactNotice(message, payload) {
2345
- const commandSemantics = resolveWorkspaceAgentNoticeCommandSemantics({
2346
- eventId: message.messageId,
2347
- messageSemantics: message.semantics,
2348
- payload,
2349
- status: message.status
2350
- });
2351
- if (commandSemantics?.command !== "compact") {
2352
- return message;
2353
- }
2354
- const commandStatus = commandSemantics.commandStatus;
2355
- const title = stringValue(payload.title) || (commandStatus === "completed" ? "Context compacted." : commandStatus === "running" ? "Compacting context." : "Context compaction interrupted.");
2356
- const originalText = messageText(message);
2357
- const detail = stringValue(payload.detail) || (commandStatus === "failed" || commandStatus === "canceled" ? originalText.replace(/^Compacting failed:\s*/iu, "").trim() : "");
2358
- return {
2359
- ...message,
2360
- semantics: {
2361
- ...message.semantics,
2362
- noticeCommand: "compact",
2363
- noticeCommandStatus: commandStatus
2364
- },
2365
- payload: {
2366
- ...payload,
2367
- kind: "agent_system_notice",
2368
- noticeKind: stringValue(payload.noticeKind) || "system_notice",
2369
- noticeCommand: "compact",
2370
- noticeCommandStatus: commandStatus,
2371
- title,
2372
- text: title,
2373
- content: title,
2374
- ...detail ? { detail } : {}
2375
- }
2376
- };
2377
- }
2378
- function latestMessageSnapshots(messages) {
2379
- const latestByKey = /* @__PURE__ */ new Map();
2380
- const unkeyedMessages = [];
2381
- for (const message of messages) {
2382
- const key = messageSnapshotKey(message);
2383
- if (!key) {
2384
- unkeyedMessages.push(message);
2385
- continue;
2386
- }
2387
- const previous = latestByKey.get(key);
2388
- if (!previous || (message.version ?? 0) >= (previous.version ?? 0)) {
2389
- latestByKey.set(key, mergeMessageSnapshot(previous, message));
2390
- } else {
2391
- latestByKey.set(key, mergeMessageSnapshot(message, previous));
2392
- }
2393
- }
2394
- return [...unkeyedMessages, ...latestByKey.values()];
2395
- }
2396
- function mergeMessageSnapshot(previous, next) {
2397
- const semantics = previous?.semantics || next.semantics ? { ...previous?.semantics, ...next.semantics } : void 0;
2398
- return {
2399
- ...previous,
2400
- ...next,
2401
- sequence: next.sequence ?? previous?.sequence,
2402
- createdAtUnixMs: next.createdAtUnixMs ?? previous?.createdAtUnixMs,
2403
- ...semantics ? { semantics } : {},
2404
- payload: {
2405
- ...previous?.payload ?? {},
2406
- ...next.payload ?? {}
2407
- }
2408
- };
2409
- }
2410
- function messageSnapshotKey(message) {
2411
- const messageId = message.messageId.trim();
2412
- if (!messageId) {
2413
- return null;
2414
- }
2415
- return `${message.agentSessionId.trim()}\0${messageId}`;
2416
- }
2417
- function messageTimelineItem({
2418
- message,
2419
- id,
2420
- seq,
2421
- eventId,
2422
- turnId,
2423
- actorType,
2424
- itemType,
2425
- role,
2426
- content,
2427
- occurredAtUnixMs
2428
- }) {
2429
- const workspaceId = workspaceIdFromMessage(message);
2430
- return {
2431
- id,
2432
- ...workspaceTimelineFields(workspaceId),
2433
- agentSessionId: message.agentSessionId,
2434
- seq,
2435
- ...turnId ? { turnId } : {},
2436
- eventId,
2437
- actorType,
2438
- actorId: actorType === "user" ? "user" : message.agentSessionId,
2439
- itemType,
2440
- role,
2441
- status: message.status,
2442
- ...message.semantics ? { messageSemantics: message.semantics } : {},
2443
- content,
2444
- payload: normalizedPayload(message.payload),
2445
- ...occurredAtUnixMs !== void 0 ? { occurredAtUnixMs } : {},
2446
- ...message.startedAtUnixMs !== void 0 ? { createdAtUnixMs: message.startedAtUnixMs } : {}
2447
- };
2448
- }
2449
- function workspaceIdFromMessage(message) {
2450
- return message.workspaceId?.trim() || "";
2451
- }
2452
- function workspaceTimelineFields(workspaceId) {
2453
- return {
2454
- workspaceId
2455
- };
2456
- }
2457
- function compareMessagesByDisplayOrder(left, right) {
2458
- const leftSequence = normalizedPositiveNumber(left.sequence);
2459
- const rightSequence = normalizedPositiveNumber(right.sequence);
2460
- if (leftSequence > 0 && rightSequence > 0 && leftSequence !== rightSequence) {
2461
- return leftSequence - rightSequence;
2462
- }
2463
- const leftTime = messageDisplayOrderTime(left);
2464
- const rightTime = messageDisplayOrderTime(right);
2465
- if (leftTime > 0 && rightTime > 0 && leftTime !== rightTime) {
2466
- return leftTime - rightTime;
2467
- }
2468
- const leftVersion = normalizedPositiveNumber(left.version);
2469
- const rightVersion = normalizedPositiveNumber(right.version);
2470
- if (leftVersion > 0 && rightVersion > 0 && leftVersion !== rightVersion) {
2471
- return leftVersion - rightVersion;
2472
- }
2473
- return 0;
2474
- }
2475
- function normalizedMessageId(id, index) {
2476
- const normalizedId = typeof id === "number" ? id : 0;
2477
- return Number.isFinite(normalizedId) && normalizedId > 0 ? normalizedId : index + 1;
2478
- }
2479
- function normalizedPositiveNumber(value) {
2480
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
2481
- }
2482
- function messageDisplayOrderTime(message) {
2483
- return normalizedPositiveNumber(message.startedAtUnixMs) || normalizedPositiveNumber(message.createdAtUnixMs) || normalizedPositiveNumber(message.occurredAtUnixMs) || normalizedPositiveNumber(message.completedAtUnixMs);
2484
- }
2485
- function toolCallItemType(status) {
2486
- switch (normalizeToken(status)) {
2487
- case "running":
2488
- case "working":
2489
- case "active":
2490
- return "call.started";
2491
- case "completed":
2492
- case "complete":
2493
- case "done":
2494
- case "success":
2495
- case "succeeded":
2496
- return "call.completed";
2497
- case "failed":
2498
- case "error":
2499
- return "call.failed";
2500
- case "canceled":
2501
- return "call.canceled";
2502
- default:
2503
- return "call";
2504
- }
2505
- }
2506
- function messageText(message) {
2507
- const payload = normalizedPayload(message.payload);
2508
- const title = messagePayloadString(message, "title");
2509
- return firstNonEmptyString(
2510
- stringValue(payload.displayPrompt),
2511
- stringValue(payload.text),
2512
- stringValue(payload.content),
2513
- stringValue(payload.message),
2514
- stringValue(payload.body),
2515
- title
2516
- );
2517
- }
2518
- function statusMessageText(message) {
2519
- const title = messagePayloadString(message, "title") ?? "";
2520
- const text = messageText(message);
2521
- if (title && text && title !== text) {
2522
- return `${title}
2523
-
2524
- ${text}`;
2525
- }
2526
- return title || text;
2527
- }
2528
- function messagePayloadString(message, key) {
2529
- return stringValue(normalizedPayload(message.payload)[key]);
2530
- }
2531
- function mergePayload(previous, next) {
2532
- if (!previous) {
2533
- return next;
2534
- }
2535
- const merged = { ...previous, ...next };
2536
- for (const key of [
2537
- "input",
2538
- "output",
2539
- "error",
2540
- "metadata",
2541
- "toolState",
2542
- "tool_state"
2543
- ]) {
2544
- if (isRecord(previous[key]) || isRecord(next[key])) {
2545
- merged[key] = {
2546
- ...isRecord(previous[key]) ? previous[key] : {},
2547
- ...isRecord(next[key]) ? next[key] : {}
2548
- };
2549
- }
2550
- }
2551
- return merged;
2552
- }
2553
- function normalizedPayload(payload) {
2554
- return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2555
- }
2556
- function sanitizedToolPayload(payload, callId) {
2557
- if (!isOpaqueCallIdentifierString(stringValue(payload.toolName), callId)) {
2558
- return payload;
2559
- }
2560
- const { toolName: _toolName, ...rest } = payload;
2561
- return rest;
2562
- }
2563
- function isRecord(value) {
2564
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2565
- }
2566
- function stringValue(value) {
2567
- return typeof value === "string" && value.trim() ? value.trim() : "";
2568
- }
2569
- function firstNonEmptyString(...values) {
2570
- for (const value of values) {
2571
- if (typeof value === "string" && value.trim()) {
2572
- return value.trim();
2573
- }
2574
- }
2575
- return "";
2576
- }
2577
- function displayToolNameCandidate(value, callId) {
2578
- const trimmed = value?.trim() ?? "";
2579
- if (!trimmed || isOpaqueCallIdentifierString(trimmed, callId)) {
2580
- return "";
2581
- }
2582
- return trimmed;
2583
- }
2584
- function isOpaqueCallIdentifierString(value, callId) {
2585
- const trimmed = value.trim();
2586
- if (!trimmed) {
2587
- return false;
2588
- }
2589
- if (callId?.trim() && trimmed === callId.trim()) {
2590
- return true;
2591
- }
2592
- const lower = trimmed.toLowerCase();
2593
- if (lower.startsWith("call_")) {
2594
- return isOpaqueIdentifierTail(trimmed.slice("call_".length));
2595
- }
2596
- if (lower.startsWith("ws_")) {
2597
- return isOpaqueIdentifierTail(trimmed.slice("ws_".length));
2598
- }
2599
- return false;
2600
- }
2601
- function isOpaqueIdentifierTail(value) {
2602
- return value.length >= 12 && /^[a-z0-9]+$/i.test(value);
2603
- }
2604
- function normalizeToken(value) {
2605
- return value?.trim().toLowerCase() ?? "";
2606
- }
2607
-
2608
2175
  // shared/agentConversation/projection/childSessionLanes.ts
2609
2176
  function buildChildSessionLanesByParentToolCallId(input) {
2610
2177
  const rootSessionId = input.rootSession.agentSessionId.trim();
@@ -2764,14 +2331,14 @@ function parentToolCall(timelineItems, parentToolCallId) {
2764
2331
  if (!parentToolCallId) return null;
2765
2332
  for (const item of timelineItems) {
2766
2333
  if (!isWorkspaceAgentToolCallItem(item)) continue;
2767
- const callId = firstString(item.callId, stringValue2(item.payload?.callId));
2334
+ const callId = firstString(item.callId, stringValue(item.payload?.callId));
2768
2335
  if (callId !== parentToolCallId) continue;
2769
2336
  const input = recordValue(item.payload?.input);
2770
2337
  return {
2771
2338
  task: firstString(
2772
- stringValue2(input?.task),
2773
- stringValue2(input?.prompt),
2774
- stringValue2(input?.description)
2339
+ stringValue(input?.task),
2340
+ stringValue(input?.prompt),
2341
+ stringValue(input?.description)
2775
2342
  )
2776
2343
  };
2777
2344
  }
@@ -2814,7 +2381,7 @@ function displayableActivityEntry(item) {
2814
2381
  const name = firstString(
2815
2382
  resolveWorkspaceAgentToolName(item),
2816
2383
  item.name,
2817
- stringValue2(item.payload?.name)
2384
+ stringValue(item.payload?.name)
2818
2385
  );
2819
2386
  return name ? { kind: "tool", text: name, atUnixMs } : null;
2820
2387
  }
@@ -2825,7 +2392,7 @@ function displayableActivityEntry(item) {
2825
2392
  return itemType === "message.assistant_thinking" || role === "assistant_thinking" ? { kind: "reasoning", text, atUnixMs } : { kind: "message", text, atUnixMs };
2826
2393
  }
2827
2394
  function timelineItemText(item) {
2828
- return (stringValue2(item.payload?.text) ?? stringValue2(item.payload?.content) ?? stringValue2(item.content) ?? "").replace(/\s+/g, " ").trim();
2395
+ return (stringValue(item.payload?.text) ?? stringValue(item.payload?.content) ?? stringValue(item.content) ?? "").replace(/\s+/g, " ").trim();
2829
2396
  }
2830
2397
  function snippet(text) {
2831
2398
  return text.length <= 140 ? text : String.fromCodePoint(8230) + text.slice(-140);
@@ -2856,7 +2423,7 @@ function timelineItemTime(item) {
2856
2423
  function normalizedString(value) {
2857
2424
  return typeof value === "string" && value.trim() ? value.trim() : null;
2858
2425
  }
2859
- function stringValue2(value) {
2426
+ function stringValue(value) {
2860
2427
  return typeof value === "string" && value.trim() ? value.trim() : null;
2861
2428
  }
2862
2429
  function recordValue(value) {
@@ -4061,6 +3628,372 @@ function agentGUIProviderTargetsEqual(left, right) {
4061
3628
  return left.provider === right.provider && left.targetId === right.targetId && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && agentGUIAgentTargetRefsEqual(left.ref, right.ref);
4062
3629
  }
4063
3630
 
3631
+ // agent-gui/agentGuiNode/model/agentComposerDraft.ts
3632
+ import { createRichTextMentionMarkdown } from "@tutti-os/ui-rich-text/core";
3633
+ var PASTED_TEXT_MENTION_PREVIEW_MAX_CHARS = 10;
3634
+ function pastedTextPreview(text) {
3635
+ const collapsed = text.replace(/\s+/g, " ").trim().replace(/[[\]()]/g, "");
3636
+ if (collapsed.length <= PASTED_TEXT_MENTION_PREVIEW_MAX_CHARS) {
3637
+ return collapsed;
3638
+ }
3639
+ return `${collapsed.slice(0, PASTED_TEXT_MENTION_PREVIEW_MAX_CHARS)}\u2026`;
3640
+ }
3641
+ function pastedTextPreviewLabel(item, index) {
3642
+ return pastedTextPreview(item.text) || item.name.trim() || pastedTextDraftDisplayName(index);
3643
+ }
3644
+ function pastedTextMentionMarkdown(item, index) {
3645
+ const path = item.path?.trim();
3646
+ if (!path) {
3647
+ return "";
3648
+ }
3649
+ return createRichTextMentionMarkdown({
3650
+ providerId: AGENT_PASTED_TEXT_MENTION_KIND,
3651
+ entityId: item.id,
3652
+ label: pastedTextPreviewLabel(item, index),
3653
+ scope: {
3654
+ path,
3655
+ ...typeof item.sizeBytes === "number" && Number.isFinite(item.sizeBytes) ? { size: String(item.sizeBytes) } : {}
3656
+ }
3657
+ });
3658
+ }
3659
+ var MAX_AGENT_COMPOSER_DRAFT_IMAGES = 8;
3660
+ function emptyAgentComposerDraft() {
3661
+ return [{ type: "text", text: "" }];
3662
+ }
3663
+ function snapshotAgentComposerDraft(draft) {
3664
+ const [textBlock, ...attachmentBlocks] = draft;
3665
+ return [{ ...textBlock }, ...attachmentBlocks.map((block) => ({ ...block }))];
3666
+ }
3667
+ function agentComposerDraftPrompt(draft) {
3668
+ return draft[0].text;
3669
+ }
3670
+ function agentComposerDraftImages(draft) {
3671
+ return draft.filter(
3672
+ (block) => block.type === "image"
3673
+ ).map(({ type: _type, ...image }) => image);
3674
+ }
3675
+ function agentComposerDraftFiles(draft) {
3676
+ return draft.filter(
3677
+ (block) => block.type === "file" && block.kind === "file"
3678
+ ).map(({ type: _type, kind: _kind, text: _text, ...file }) => file);
3679
+ }
3680
+ function agentComposerDraftLargeTexts(draft) {
3681
+ return draft.filter(
3682
+ (block) => block.type === "file" && block.kind === AGENT_PASTED_TEXT_BLOCK_KIND
3683
+ ).map(({ type: _type, kind: _kind, ...item }) => item);
3684
+ }
3685
+ var attachmentProjectionByDraft = /* @__PURE__ */ new WeakMap();
3686
+ function agentComposerDraftAttachmentProjection(draft) {
3687
+ const cached = attachmentProjectionByDraft.get(draft);
3688
+ if (cached) return cached;
3689
+ const projection = {
3690
+ images: agentComposerDraftImages(draft),
3691
+ files: agentComposerDraftFiles(draft),
3692
+ largeTexts: agentComposerDraftLargeTexts(draft)
3693
+ };
3694
+ attachmentProjectionByDraft.set(draft, projection);
3695
+ return projection;
3696
+ }
3697
+ function buildAgentComposerDraft(input) {
3698
+ return [
3699
+ { type: "text", text: input.prompt },
3700
+ ...(input.images ?? []).map((image) => ({
3701
+ type: "image",
3702
+ ...image
3703
+ })),
3704
+ ...(input.files ?? []).map((file) => ({
3705
+ type: "file",
3706
+ kind: "file",
3707
+ ...file
3708
+ })),
3709
+ ...(input.largeTexts ?? []).map(
3710
+ (item) => ({
3711
+ type: "file",
3712
+ kind: AGENT_PASTED_TEXT_BLOCK_KIND,
3713
+ ...item
3714
+ })
3715
+ )
3716
+ ];
3717
+ }
3718
+ function updateAgentComposerDraft(draft, update) {
3719
+ return buildAgentComposerDraft({
3720
+ prompt: update.prompt ?? agentComposerDraftPrompt(draft),
3721
+ images: update.images ?? agentComposerDraftImages(draft),
3722
+ files: update.files ?? agentComposerDraftFiles(draft),
3723
+ largeTexts: update.largeTexts ?? agentComposerDraftLargeTexts(draft)
3724
+ });
3725
+ }
3726
+ function agentComposerDraftHasContent(draft) {
3727
+ const prompt = agentComposerDraftPrompt(draft);
3728
+ const references = agentComposerFileMentionReferences(prompt);
3729
+ let cursor = 0;
3730
+ let textWithoutComposerFiles = "";
3731
+ for (const reference of references) {
3732
+ textWithoutComposerFiles += prompt.slice(cursor, reference.start);
3733
+ cursor = reference.end;
3734
+ }
3735
+ textWithoutComposerFiles += prompt.slice(cursor);
3736
+ const referencedFileIds = new Set(
3737
+ references.map((reference) => reference.id)
3738
+ );
3739
+ if (textWithoutComposerFiles.trim() || agentComposerDraftFiles(draft).some(
3740
+ (file) => referencedFileIds.has(file.id)
3741
+ )) {
3742
+ return true;
3743
+ }
3744
+ return draft.some((block) => {
3745
+ if (block.type === "text") return false;
3746
+ if (block.type === "image") return true;
3747
+ return block.kind === "file" ? false : block.text.trim() !== "" || Boolean(block.path);
3748
+ });
3749
+ }
3750
+ function normalizeAgentPromptContentBlocks(content) {
3751
+ const result = [];
3752
+ for (const block of content) {
3753
+ if (block.type === "text") {
3754
+ const text = block.text?.trim() ?? "";
3755
+ if (text) {
3756
+ result.push({ type: "text", text });
3757
+ }
3758
+ continue;
3759
+ }
3760
+ if (block.type === "image") {
3761
+ const mimeType = block.mimeType?.trim();
3762
+ const attachmentId = block.attachmentId?.trim();
3763
+ const data = block.data?.trim();
3764
+ const url = block.url?.trim();
3765
+ const imagePath = block.path?.trim();
3766
+ if (!attachmentId && !data && !url && !imagePath || data && url || url && !isSafePromptImageUrl(url) || mimeType !== "image/png" && mimeType !== "image/jpeg" && mimeType !== "image/webp") {
3767
+ continue;
3768
+ }
3769
+ result.push({
3770
+ type: "image",
3771
+ mimeType,
3772
+ ...attachmentId ? { attachmentId } : {},
3773
+ ...url ? { url } : data ? { data } : imagePath ? { path: imagePath } : {},
3774
+ ...block.name?.trim() ? { name: block.name.trim() } : {}
3775
+ });
3776
+ continue;
3777
+ }
3778
+ if (block.type === "file") {
3779
+ const filePath = block.path?.trim();
3780
+ const hostPath = block.hostPath?.trim();
3781
+ const url = block.url?.trim();
3782
+ const uri = block.uri?.trim();
3783
+ const assetId = block.assetId?.trim();
3784
+ if (!filePath && !hostPath && !url && !uri && !assetId) {
3785
+ continue;
3786
+ }
3787
+ result.push({
3788
+ type: "file",
3789
+ ...block.mimeType?.trim() ? { mimeType: block.mimeType.trim() } : {},
3790
+ ...filePath ? { path: filePath } : {},
3791
+ ...hostPath ? { hostPath } : {},
3792
+ ...url ? { url } : {},
3793
+ ...block.name?.trim() ? { name: block.name.trim() } : {},
3794
+ ...uri ? { uri } : {},
3795
+ ...block.uploadStatus?.trim() ? { uploadStatus: block.uploadStatus.trim() } : {},
3796
+ ...assetId ? { assetId } : {},
3797
+ ...typeof block.sizeBytes === "number" ? { sizeBytes: block.sizeBytes } : {},
3798
+ kind: block.kind === AGENT_PASTED_TEXT_BLOCK_KIND ? AGENT_PASTED_TEXT_BLOCK_KIND : "file"
3799
+ });
3800
+ continue;
3801
+ }
3802
+ if (block.type === "skill" || block.type === "mention") {
3803
+ const name = block.name?.trim();
3804
+ const path = block.path?.trim();
3805
+ if (name && path) {
3806
+ result.push({ type: block.type, name, path });
3807
+ }
3808
+ }
3809
+ }
3810
+ return result;
3811
+ }
3812
+ function isSafePromptImageUrl(value) {
3813
+ try {
3814
+ const url = new URL(value);
3815
+ return url.protocol === "https:" && Boolean(url.hostname) && !url.username && !url.password;
3816
+ } catch {
3817
+ return false;
3818
+ }
3819
+ }
3820
+ function agentPromptContentDisplayText(content) {
3821
+ return content.filter((block) => block.type === "text").map((block) => block.text?.trim() ?? "").filter(Boolean).join("\n");
3822
+ }
3823
+ function agentPromptContentHasImage(content) {
3824
+ return content.some((block) => block.type === "image");
3825
+ }
3826
+ function agentPromptContentImageBlocks(content) {
3827
+ return normalizeAgentPromptContentBlocks(content).filter(
3828
+ (block) => block.type === "image" && (typeof block.attachmentId === "string" || typeof block.data === "string" || typeof block.url === "string" || typeof block.path === "string") && typeof block.mimeType === "string"
3829
+ );
3830
+ }
3831
+ function agentPromptContentToComposerDraft(content, idPrefix) {
3832
+ const normalizedContent = normalizeAgentPromptContentBlocks(content);
3833
+ const largeTexts = agentPromptPastedTextBlocks(normalizedContent).map(
3834
+ (block) => agentPromptPastedTextBlockToDraftLargeText(block)
3835
+ );
3836
+ const files = agentPromptFileBlocks(normalizedContent).map(
3837
+ (file, index) => agentPreparedPromptFileToDraftFile(file, idPrefix, index)
3838
+ );
3839
+ return buildAgentComposerDraft({
3840
+ prompt: agentPromptContentToComposerPrompt(normalizedContent, files),
3841
+ images: agentPromptContentImageBlocks(normalizedContent).slice(0, MAX_AGENT_COMPOSER_DRAFT_IMAGES).map(
3842
+ (image, index) => agentPromptImageBlockToDraftImage(image, idPrefix, index)
3843
+ ),
3844
+ files,
3845
+ largeTexts
3846
+ });
3847
+ }
3848
+ function agentPromptPastedTextBlockToDraftLargeText(block) {
3849
+ return {
3850
+ id: crypto.randomUUID(),
3851
+ name: block.name?.trim() || "pasted-text.txt",
3852
+ text: "",
3853
+ ...block.path ? { path: block.path } : {},
3854
+ ...typeof block.sizeBytes === "number" ? { sizeBytes: block.sizeBytes } : {}
3855
+ };
3856
+ }
3857
+ function agentComposerDraftToPromptContent(input) {
3858
+ const providerPrompt = materializeAgentComposerFileMentions(
3859
+ agentComposerDraftPrompt(input.draft),
3860
+ agentComposerDraftFiles(input.draft)
3861
+ );
3862
+ const prompt = promptForProviderSkills({
3863
+ prompt: providerPrompt,
3864
+ skills: input.skills
3865
+ });
3866
+ return normalizeAgentPromptContentBlocks([
3867
+ ...textPromptContent(prompt),
3868
+ ...promptItemBlocksForProviderSkills({
3869
+ prompt,
3870
+ skills: input.skills
3871
+ }),
3872
+ ...agentComposerDraftImages(input.draft).slice(0, MAX_AGENT_COMPOSER_DRAFT_IMAGES).filter((image) => !image.uploading && !image.uploadError).map((image) => ({
3873
+ type: "image",
3874
+ mimeType: image.mimeType,
3875
+ ...image.attachmentId ? { attachmentId: image.attachmentId } : {},
3876
+ ...image.url ? { url: image.url } : image.path ? { path: image.path } : { data: image.data },
3877
+ name: image.name
3878
+ })),
3879
+ ...largeTextPromptContent(agentComposerDraftLargeTexts(input.draft))
3880
+ ]);
3881
+ }
3882
+ function agentComposerDraftSubmittedText(draft) {
3883
+ return agentPromptContentDisplayText(
3884
+ normalizeAgentPromptContentBlocks([
3885
+ ...textPromptContent(agentComposerDraftPrompt(draft)),
3886
+ ...largeTextPromptContent(agentComposerDraftLargeTexts(draft))
3887
+ ])
3888
+ );
3889
+ }
3890
+ function agentComposerDraftDisplayPrompt(draft) {
3891
+ const prompt = agentComposerDraftPrompt(draft).trim();
3892
+ const largeTexts = agentComposerDraftLargeTexts(draft).filter(
3893
+ (item) => Boolean(item.path) && !item.uploading && !item.uploadError
3894
+ );
3895
+ if (!largeTexts.length) {
3896
+ return prompt.includes("](mention://") ? prompt : void 0;
3897
+ }
3898
+ const parts = [prompt].filter(Boolean);
3899
+ parts.push(
3900
+ ...largeTexts.map((item, index) => pastedTextMentionMarkdown(item, index)).filter(Boolean)
3901
+ );
3902
+ return parts.join("\n");
3903
+ }
3904
+ function projectAgentComposerDraftSubmission(input) {
3905
+ const content = agentComposerDraftToPromptContent(input);
3906
+ const explicitDisplayPrompt = agentComposerDraftDisplayPrompt(input.draft);
3907
+ const visibleText = agentComposerDraftSubmittedText(input.draft);
3908
+ const runtimeText = agentPromptContentDisplayText(content);
3909
+ const displayPrompt = explicitDisplayPrompt ?? (visibleText !== runtimeText ? visibleText : void 0);
3910
+ return {
3911
+ content,
3912
+ ...displayPrompt ? { displayPrompt } : {}
3913
+ };
3914
+ }
3915
+ function promptItemBlocksForProviderSkills(input) {
3916
+ const result = [];
3917
+ for (const skill of input.skills) {
3918
+ if (skill.invocation !== "promptItem") {
3919
+ continue;
3920
+ }
3921
+ const path = skill.path?.trim();
3922
+ if (!path) {
3923
+ continue;
3924
+ }
3925
+ const trigger = skillTriggerForPrefix(skill, "$");
3926
+ if (!trigger || !promptHasTrigger(input.prompt, trigger)) {
3927
+ continue;
3928
+ }
3929
+ result.push({
3930
+ type: skill.kind === "connector" ? "mention" : "skill",
3931
+ name: skill.name,
3932
+ path
3933
+ });
3934
+ }
3935
+ return result;
3936
+ }
3937
+ function promptHasTrigger(prompt, trigger) {
3938
+ return new RegExp(`(^|\\s)${escapeRegExp(trigger)}(?=$|\\s)`).test(prompt);
3939
+ }
3940
+ function escapeRegExp(value) {
3941
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3942
+ }
3943
+ function textPromptContent(prompt) {
3944
+ const text = prompt.trim();
3945
+ return text ? [{ type: "text", text }] : [];
3946
+ }
3947
+ function largeTextPromptContent(largeTexts) {
3948
+ return largeTexts.filter((item) => {
3949
+ const path = item.path?.trim();
3950
+ return Boolean(path) && !item.uploading && !item.uploadError;
3951
+ }).map((item, index) => ({
3952
+ type: "file",
3953
+ kind: AGENT_PASTED_TEXT_BLOCK_KIND,
3954
+ path: item.path,
3955
+ // The preview (first chars of the pasted body) is the chip label; carry it
3956
+ // as the block name so the send-time instruction persists it in content.
3957
+ name: pastedTextPreviewLabel(item, index),
3958
+ ...typeof item.sizeBytes === "number" ? { sizeBytes: item.sizeBytes } : {}
3959
+ }));
3960
+ }
3961
+ function isPastedTextPromptBlock(block) {
3962
+ return block.type === "file" && block.kind === AGENT_PASTED_TEXT_BLOCK_KIND;
3963
+ }
3964
+ function materializePastedTextInstructions(content, format) {
3965
+ const pastedRefs = content.filter(isPastedTextPromptBlock).map((block) => ({
3966
+ preview: sanitizePastedTextPreviewForContent(block.name),
3967
+ path: block.path?.trim() ?? ""
3968
+ })).filter((ref) => ref.path !== "");
3969
+ if (pastedRefs.length === 0) {
3970
+ return [...content];
3971
+ }
3972
+ const withoutPastedText = content.filter(
3973
+ (block) => !isPastedTextPromptBlock(block)
3974
+ );
3975
+ const instruction = [
3976
+ format.header(),
3977
+ ...pastedRefs.map((ref) => format.line(ref.preview, ref.path))
3978
+ ].join("\n");
3979
+ return [...withoutPastedText, { type: "text", text: instruction }];
3980
+ }
3981
+ function sanitizePastedTextPreviewForContent(name) {
3982
+ return (name ?? "").replace(/["\n\r]/g, " ").trim();
3983
+ }
3984
+ function agentPromptImageBlockToDraftImage(image, idPrefix, index) {
3985
+ return {
3986
+ id: `${idPrefix}:image:${index}`,
3987
+ name: image.name?.trim() || `image-${index + 1}`,
3988
+ mimeType: image.mimeType,
3989
+ ...image.attachmentId ? { attachmentId: image.attachmentId } : {},
3990
+ ...image.data ? { data: image.data } : {},
3991
+ ...image.url ? { url: image.url } : {},
3992
+ ...image.path ? { path: image.path } : {},
3993
+ previewUrl: typeof image.data === "string" && image.data ? image.data.startsWith("data:") ? image.data : `data:${image.mimeType};base64,${image.data}` : image.url ?? ""
3994
+ };
3995
+ }
3996
+
4064
3997
  // agent-gui/agentGuiNode/controller/agentGuiController.composerHelpers.ts
4065
3998
  function normalizeConfigOptionValue(value) {
4066
3999
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -4479,6 +4412,7 @@ var AGENT_PROVIDER_SESSION_NOT_FOUND_ERROR = "agent.provider_session_not_found";
4479
4412
  var AGENT_RESUME_SESSION_NOT_LOCAL_ERROR = "agent.resume_session_not_local";
4480
4413
  var AGENT_SETTINGS_REQUIRE_NEW_SESSION_ERROR = "agent.settings_require_new_session";
4481
4414
  var AGENT_SESSION_TITLE_TOO_LONG_REASON = "workspace_agent_session_title_too_long";
4415
+ var AGENT_SESSION_NOT_FOUND_ERROR = "session.not_found";
4482
4416
  var AGENT_PROVIDER_SESSION_NOT_FOUND_FALLBACK_MESSAGE = "The previous agent session can no longer be restored.";
4483
4417
  var AGENT_RESUME_SESSION_NOT_LOCAL_FALLBACK_MESSAGE = "The previous agent session is not available on this machine.";
4484
4418
  var AGENT_GUI_CAUGHT_ERROR_STACK_LIMIT = 4e3;
@@ -4722,7 +4656,7 @@ function maxFiniteMessageVersion(messages) {
4722
4656
  }
4723
4657
  return result;
4724
4658
  }
4725
- function messageText2(message) {
4659
+ function messageText(message) {
4726
4660
  const payload = message.payload;
4727
4661
  for (const key of ["displayPrompt", "text"]) {
4728
4662
  const value = payload[key];
@@ -4739,7 +4673,7 @@ function messageText2(message) {
4739
4673
  }).filter(Boolean).join("\n");
4740
4674
  }
4741
4675
  function isUserTextMessage(message) {
4742
- return message.kind.trim().toLowerCase() === "text" && message.role.trim().toLowerCase() === "user" && messageText2(message).trim() !== "";
4676
+ return message.kind.trim().toLowerCase() === "text" && message.role.trim().toLowerCase() === "user" && messageText(message).trim() !== "";
4743
4677
  }
4744
4678
  function windowHasTurnMissingUserPrompt(messages, newestPagedVersion) {
4745
4679
  if (newestPagedVersion === null) {
@@ -5110,69 +5044,6 @@ function omitConversationLocalState(current, conversationIds) {
5110
5044
  }
5111
5045
  return changed ? next : current;
5112
5046
  }
5113
- function interactiveApprovalFromInteraction(interaction) {
5114
- if (!interaction || interaction.kind !== "approval") return null;
5115
- const callId = typeof interaction.input?.callId === "string" && interaction.input.callId.trim() ? interaction.input.callId.trim() : interaction.requestId.trim();
5116
- const options = Array.isArray(interaction.input?.options) ? interaction.input.options : [];
5117
- const normalizedOptions = options.map((option) => {
5118
- if (!option || typeof option !== "object") return null;
5119
- const candidate = option;
5120
- const id = typeof candidate.id === "string" && candidate.id.trim() ? candidate.id.trim() : typeof candidate.optionId === "string" && candidate.optionId.trim() ? candidate.optionId.trim() : "";
5121
- if (!id) return null;
5122
- return {
5123
- id,
5124
- label: typeof candidate.name === "string" && candidate.name.trim() ? candidate.name.trim() : typeof candidate.label === "string" && candidate.label.trim() ? candidate.label.trim() : id,
5125
- kind: typeof candidate.kind === "string" && candidate.kind.trim() ? candidate.kind.trim() : id,
5126
- ...typeof candidate.description === "string" && candidate.description.trim() ? { description: candidate.description.trim() } : {}
5127
- };
5128
- }).filter((option) => option !== null);
5129
- if (!callId || normalizedOptions.length === 0) return null;
5130
- const approvalPurpose = normalizeAgentApprovalPurpose(
5131
- interaction.metadata?.approvalPurpose
5132
- );
5133
- return {
5134
- kind: "approval",
5135
- id: `approval:${callId}`,
5136
- turnId: interaction.turnId,
5137
- requestId: interaction.requestId,
5138
- callId,
5139
- ...approvalPurpose ? { approvalPurpose } : {},
5140
- title: interaction.toolName?.trim() || "Approval required",
5141
- status: "waiting_approval",
5142
- toolName: interaction.toolName?.trim() || null,
5143
- input: interaction.input ?? null,
5144
- options: normalizedOptions,
5145
- output: interaction.output ?? null,
5146
- occurredAtUnixMs: interaction.createdAtUnixMs
5147
- };
5148
- }
5149
- function interactivePromptFromInteraction(interaction) {
5150
- if (!interaction || interaction.kind === "approval") return null;
5151
- const toolName = normalizeInteractiveToolName(
5152
- interaction.toolName ?? void 0
5153
- );
5154
- if (interaction.kind === "plan" || toolName === "exitplanmode") {
5155
- return {
5156
- kind: "exit-plan",
5157
- requestId: interaction.requestId,
5158
- title: interaction.toolName?.trim() || "Exit plan mode",
5159
- options: []
5160
- };
5161
- }
5162
- if (interaction.kind !== "question" || toolName !== "askuserquestion") {
5163
- return null;
5164
- }
5165
- const questions = normalizeInteractiveQuestions(interaction.input?.questions);
5166
- return questions.length > 0 ? {
5167
- kind: "ask-user",
5168
- requestId: interaction.requestId,
5169
- title: interaction.toolName?.trim() || "Questions for you",
5170
- questions
5171
- } : null;
5172
- }
5173
- function normalizeInteractiveToolName(toolName) {
5174
- return (toolName?.trim() ?? "").replace(/[_\s-]+/g, "").toLowerCase();
5175
- }
5176
5047
  function areAgentGUIUserProjectsEqual(left, right) {
5177
5048
  return left.length === right.length && left.every((project, index) => {
5178
5049
  const candidate = right[index];
@@ -5216,47 +5087,6 @@ function readAgentGUIUserProjectSnapshot(api) {
5216
5087
  function readAgentGUIUserProjectMutationPending(api) {
5217
5088
  return api?.service?.getSnapshot?.().isMutationPending === true;
5218
5089
  }
5219
- function normalizeInteractiveQuestions(value) {
5220
- if (!Array.isArray(value)) {
5221
- return [];
5222
- }
5223
- return value.flatMap((item, index) => {
5224
- if (!item || typeof item !== "object" || Array.isArray(item)) {
5225
- return [];
5226
- }
5227
- const record = item;
5228
- const options = Array.isArray(record.options) ? record.options.flatMap((option) => {
5229
- if (!option || typeof option !== "object" || Array.isArray(option)) {
5230
- return [];
5231
- }
5232
- const candidate = option;
5233
- const label = typeof candidate.label === "string" && candidate.label.trim() ? candidate.label.trim() : typeof candidate.name === "string" && candidate.name.trim() ? candidate.name.trim() : "";
5234
- if (!label) {
5235
- return [];
5236
- }
5237
- return [
5238
- {
5239
- label,
5240
- description: typeof candidate.description === "string" ? candidate.description.trim() : ""
5241
- }
5242
- ];
5243
- }) : [];
5244
- const question = typeof record.question === "string" && record.question.trim() ? record.question.trim() : typeof record.header === "string" && record.header.trim() ? record.header.trim() : "";
5245
- if (!question) {
5246
- return [];
5247
- }
5248
- return [
5249
- {
5250
- id: typeof record.id === "string" && record.id.trim() ? record.id.trim() : `question-${index + 1}`,
5251
- header: typeof record.header === "string" && record.header.trim() ? record.header.trim() : `Question ${index + 1}`,
5252
- question,
5253
- options,
5254
- multiSelect: Boolean(record.multiSelect),
5255
- isOther: Boolean(record.isOther)
5256
- }
5257
- ];
5258
- });
5259
- }
5260
5090
 
5261
5091
  // agent-gui/agentGuiNode/controller/agentGuiController.reporting.ts
5262
5092
  import { toast } from "@tutti-os/ui-system";
@@ -6407,8 +6237,8 @@ import {
6407
6237
  selectLatestActivationForSession as selectLatestActivationForSession3
6408
6238
  } from "@tutti-os/agent-activity-core";
6409
6239
  import { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef7 } from "react";
6410
- function clearFailedAgentGUIActivationSelection(current, failedAgentSessionId) {
6411
- const normalized = failedAgentSessionId.trim();
6240
+ function clearRolledBackAgentGUISelection(current, rolledBackAgentSessionId) {
6241
+ const normalized = rolledBackAgentSessionId.trim();
6412
6242
  return normalized ? forgetAgentGUISessionMemories(current, /* @__PURE__ */ new Set([normalized])) : current;
6413
6243
  }
6414
6244
  function shouldMarkActiveConversationRead(input) {
@@ -6416,12 +6246,17 @@ function shouldMarkActiveConversationRead(input) {
6416
6246
  if (!record?.isUnread) return false;
6417
6247
  return !record.markedUnreadByUser || previousActiveConversationId !== activeConversationId;
6418
6248
  }
6249
+ function shouldClearMissingAgentGUISelection(input) {
6250
+ const activeConversationId = input.activeConversationId?.trim() ?? "";
6251
+ return activeConversationId !== "" && activeConversationId === (input.currentActiveConversationId?.trim() ?? "") && input.reconcileErrorCode?.trim() === AGENT_SESSION_NOT_FOUND_ERROR;
6252
+ }
6419
6253
  function useAgentGUIConversationSelectionController(input) {
6420
6254
  const {
6421
6255
  activation,
6422
6256
  activeConversationId,
6423
6257
  activeConversationIdRef,
6424
6258
  activePendingActivation,
6259
+ activeSessionReconcileErrorCode,
6425
6260
  agentActivityRuntime,
6426
6261
  attentionReadRecordsBySessionId,
6427
6262
  conversationIdsRef,
@@ -6449,7 +6284,8 @@ function useAgentGUIConversationSelectionController(input) {
6449
6284
  workspaceId
6450
6285
  } = input;
6451
6286
  const previousAttentionActiveConversationIdRef = useRef7(null);
6452
- const failedActivationRollbackSessionIdRef = useRef7(null);
6287
+ const rolledBackSelectionSessionIdRef = useRef7(null);
6288
+ const persistedConfirmedActivationRequestIdRef = useRef7(null);
6453
6289
  useEffect4(() => {
6454
6290
  const userId = currentUserId?.trim() ?? "";
6455
6291
  const normalizedWorkspaceId = workspaceId.trim();
@@ -6462,8 +6298,8 @@ function useAgentGUIConversationSelectionController(input) {
6462
6298
  });
6463
6299
  }, [currentUserId, sessionEngine, workspaceId]);
6464
6300
  useEffect4(() => {
6465
- if (activePendingActivation?.mode === "new" && !isPendingActivationViable3(activePendingActivation) && activeConversationIdRef.current === activePendingActivation.agentSessionId) {
6466
- failedActivationRollbackSessionIdRef.current = activePendingActivation.agentSessionId;
6301
+ const rollbackSelection = (agentSessionId, errorMessage) => {
6302
+ rolledBackSelectionSessionIdRef.current = agentSessionId;
6467
6303
  activeConversationIdRef.current = null;
6468
6304
  setActiveConversationId(null);
6469
6305
  isComposerHomeRef.current = true;
@@ -6471,20 +6307,45 @@ function useAgentGUIConversationSelectionController(input) {
6471
6307
  setIntent({ tag: "home" });
6472
6308
  clearRailRevealRequest();
6473
6309
  onDataChangeRef.current(
6474
- (current) => clearFailedAgentGUIActivationSelection(
6310
+ (current) => clearRolledBackAgentGUISelection(current, agentSessionId)
6311
+ );
6312
+ if (errorMessage) setDetailError(errorMessage);
6313
+ previousAttentionActiveConversationIdRef.current = null;
6314
+ };
6315
+ if (activePendingActivation?.mode === "new" && !isPendingActivationViable3(activePendingActivation) && activeConversationIdRef.current === activePendingActivation.agentSessionId) {
6316
+ rollbackSelection(
6317
+ activePendingActivation.agentSessionId,
6318
+ activePendingActivation.status === "failed" ? activePendingActivation.errorMessage || translate("agentHost.agentGui.sessionActivationFailed") : null
6319
+ );
6320
+ return;
6321
+ }
6322
+ if (shouldClearMissingAgentGUISelection({
6323
+ activeConversationId,
6324
+ currentActiveConversationId: activeConversationIdRef.current,
6325
+ reconcileErrorCode: activeSessionReconcileErrorCode
6326
+ })) {
6327
+ rollbackSelection(
6328
+ activeConversationId.trim(),
6329
+ translate("agentHost.agentGui.sessionNoLongerAvailable")
6330
+ );
6331
+ setIsLoadingMessages(false);
6332
+ return;
6333
+ }
6334
+ if (activePendingActivation?.mode === "new" && activePendingActivation.status === "confirmed" && activeConversationIdRef.current === activePendingActivation.agentSessionId && persistedConfirmedActivationRequestIdRef.current !== activePendingActivation.requestId) {
6335
+ persistedConfirmedActivationRequestIdRef.current = activePendingActivation.requestId;
6336
+ onDataChangeRef.current(
6337
+ (current) => rememberAgentGUIActiveConversation(
6475
6338
  current,
6476
- activePendingActivation.agentSessionId
6339
+ activePendingActivation.agentSessionId,
6340
+ activePendingActivation.agentTargetId
6477
6341
  )
6478
6342
  );
6479
- if (activePendingActivation.status === "failed") {
6480
- setDetailError(
6481
- activePendingActivation.errorMessage || translate("agentHost.agentGui.sessionActivationFailed")
6482
- );
6483
- }
6343
+ }
6344
+ if (!activeConversationId) {
6484
6345
  previousAttentionActiveConversationIdRef.current = null;
6485
6346
  return;
6486
6347
  }
6487
- if (!activeConversationId) {
6348
+ if (activeConversationIdRef.current !== activeConversationId) {
6488
6349
  previousAttentionActiveConversationIdRef.current = null;
6489
6350
  return;
6490
6351
  }
@@ -6504,6 +6365,7 @@ function useAgentGUIConversationSelectionController(input) {
6504
6365
  }, [
6505
6366
  activeConversationId,
6506
6367
  activePendingActivation,
6368
+ activeSessionReconcileErrorCode,
6507
6369
  attentionReadRecordsBySessionId,
6508
6370
  clearRailRevealRequest,
6509
6371
  currentUserId,
@@ -6511,12 +6373,12 @@ function useAgentGUIConversationSelectionController(input) {
6511
6373
  ]);
6512
6374
  useEffect4(() => {
6513
6375
  const externalId = data.lastActiveAgentSessionId?.trim() ?? "";
6514
- const failedActivationRollbackSessionId = failedActivationRollbackSessionIdRef.current;
6515
- if (failedActivationRollbackSessionId) {
6516
- if (externalId === failedActivationRollbackSessionId) {
6376
+ const rolledBackSelectionSessionId = rolledBackSelectionSessionIdRef.current;
6377
+ if (rolledBackSelectionSessionId) {
6378
+ if (externalId === rolledBackSelectionSessionId) {
6517
6379
  return;
6518
6380
  }
6519
- failedActivationRollbackSessionIdRef.current = null;
6381
+ rolledBackSelectionSessionIdRef.current = null;
6520
6382
  }
6521
6383
  if (externalId === (activeConversationIdRef.current ?? "")) return;
6522
6384
  if (!externalId) {
@@ -6963,55 +6825,11 @@ function useAgentGUIConversationListState({
6963
6825
 
6964
6826
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerCapabilities.ts
6965
6827
  import {
6966
- resolveAgentActivityCapability as resolveAgentActivityCapability2,
6828
+ resolveAgentActivityCapability,
6967
6829
  resolveAgentActivityUsage
6968
6830
  } from "@tutti-os/agent-activity-core";
6969
6831
  import { useMemo as useMemo7, useRef as useRef9 } from "react";
6970
6832
 
6971
- // agent-gui/agentGuiNode/model/composerSettingsSupport.ts
6972
- import {
6973
- resolveAgentActivityCapability
6974
- } from "@tutti-os/agent-activity-core";
6975
- function composerSettingsSupportFromOptions(composerOptions, sessionCapabilities) {
6976
- const hasModelReasoningOptions = Object.values(
6977
- composerOptions?.reasoningOptionsByModel ?? {}
6978
- ).some((profile) => profile.options.length > 0);
6979
- return {
6980
- model: composerOptions?.modelConfigurable ?? false,
6981
- reasoning: (composerOptions?.reasoningConfigurable ?? false) || hasModelReasoningOptions,
6982
- speed: composerOptions?.speedConfigurable ?? false,
6983
- permission: composerOptions?.permissionConfig?.configurable ?? false,
6984
- plan: resolveAgentActivityCapability("planMode", {
6985
- composerOptions,
6986
- sessionCapabilities
6987
- }) === true,
6988
- browser: resolveAgentActivityCapability("browserUse", {
6989
- composerOptions,
6990
- sessionCapabilities
6991
- }) === true,
6992
- computer: resolveAgentActivityCapability("computerUse", {
6993
- composerOptions,
6994
- sessionCapabilities
6995
- }) === true,
6996
- planImplementation: resolveAgentActivityCapability("planImplementation", {
6997
- composerOptions,
6998
- sessionCapabilities
6999
- }) === true,
7000
- permissionModeChangeDuringTurn: resolveAgentActivityCapability("permissionModeChangeDuringTurn", {
7001
- composerOptions,
7002
- sessionCapabilities
7003
- }) === true,
7004
- permissionModeChangeDeferred: resolveAgentActivityCapability("permissionModeChangeDeferred", {
7005
- composerOptions,
7006
- sessionCapabilities
7007
- }) === true,
7008
- modelSwitch: resolveAgentActivityCapability("modelSwitch", {
7009
- composerOptions,
7010
- sessionCapabilities
7011
- }) === true
7012
- };
7013
- }
7014
-
7015
6833
  // agent-gui/agentGuiNode/controller/agentGuiController.composerPresentation.ts
7016
6834
  function composerTargetDataFromNodeData(data) {
7017
6835
  const agentTargetId = normalizeOptionalText(data.agentTargetId);
@@ -7183,7 +7001,7 @@ function useAgentGUIComposerCapabilities(input) {
7183
7001
  });
7184
7002
  const defaultReasoningEffort = "high";
7185
7003
  const sessionCapabilities = input.activeEngineSession?.capabilities ?? null;
7186
- const resolvedPromptImagesSupported = sessionCapabilities?.imageInput ?? resolveAgentActivityCapability2("imageInput", {
7004
+ const resolvedPromptImagesSupported = sessionCapabilities?.imageInput ?? resolveAgentActivityCapability("imageInput", {
7187
7005
  composerOptions: providerComposerOptions,
7188
7006
  sessionCapabilities
7189
7007
  });
@@ -7199,7 +7017,7 @@ function useAgentGUIComposerCapabilities(input) {
7199
7017
  selectedComposerTargetData: input.selectedComposerTargetData
7200
7018
  }) ?? normalizeOptionalText(providerComposerOptions?.effectiveSettings?.model);
7201
7019
  const modelImageInputRequired = Boolean(
7202
- resolveAgentActivityCapability2("modelImageInputRequired", {
7020
+ resolveAgentActivityCapability("modelImageInputRequired", {
7203
7021
  composerOptions: providerComposerOptions,
7204
7022
  sessionCapabilities
7205
7023
  })
@@ -7238,7 +7056,7 @@ function useAgentGUIComposerCapabilities(input) {
7238
7056
  return retainedUsageBySessionIdRef.current.get(agentSessionId) ?? null;
7239
7057
  }, [input.activeEngineSession?.agentSessionId, usageSource]);
7240
7058
  return {
7241
- compactSupported: sessionCapabilities?.compact ?? resolveAgentActivityCapability2("compact", {
7059
+ compactSupported: sessionCapabilities?.compact ?? resolveAgentActivityCapability("compact", {
7242
7060
  composerOptions: providerComposerOptions,
7243
7061
  sessionCapabilities
7244
7062
  }),
@@ -7246,7 +7064,7 @@ function useAgentGUIComposerCapabilities(input) {
7246
7064
  composerOptionsLoading,
7247
7065
  composerTargetData,
7248
7066
  defaultReasoningEffort,
7249
- goalPauseSupported: sessionCapabilities?.goalPause ?? resolveAgentActivityCapability2("goalPause", {
7067
+ goalPauseSupported: sessionCapabilities?.goalPause ?? resolveAgentActivityCapability("goalPause", {
7250
7068
  composerOptions: providerComposerOptions,
7251
7069
  sessionCapabilities
7252
7070
  }) ?? false,
@@ -9249,7 +9067,6 @@ function useAgentGUINewConversationActivation(input) {
9249
9067
  loadSelectedConversationMessages,
9250
9068
  loadSessionState,
9251
9069
  refreshMessagesFromSnapshot,
9252
- persistActiveConversation,
9253
9070
  requestRailReveal,
9254
9071
  setActiveConversationId,
9255
9072
  setIntent,
@@ -9380,7 +9197,6 @@ function useAgentGUINewConversationActivation(input) {
9380
9197
  setIsComposerHome(false);
9381
9198
  setIntent({ tag: "active", id: agentSessionId });
9382
9199
  setIsLoadingMessages(false);
9383
- persistActiveConversation(agentSessionId, agentTargetId);
9384
9200
  return { agentSessionId, requestId };
9385
9201
  },
9386
9202
  [
@@ -9392,7 +9208,6 @@ function useAgentGUINewConversationActivation(input) {
9392
9208
  loadSelectedConversationMessages,
9393
9209
  loadSessionState,
9394
9210
  refreshMessagesFromSnapshot,
9395
- persistActiveConversation,
9396
9211
  requestRailReveal,
9397
9212
  activation,
9398
9213
  conversationListQuery,
@@ -11724,11 +11539,11 @@ function useAgentGUIConversationDetail(input) {
11724
11539
  const hasProviderSessionNotFoundError = isNonRetryableResumeErrorCode(activationErrorCode);
11725
11540
  const rawPendingApproval = useMemo11(() => {
11726
11541
  const interaction = [...input.activePendingInteractions].reverse().find((candidate) => candidate.kind === "approval") ?? null;
11727
- return interactiveApprovalFromInteraction(interaction);
11542
+ return projectAgentApprovalPromptFromInteraction(interaction);
11728
11543
  }, [input.activePendingInteractions]);
11729
11544
  const rawPendingInteractivePrompt = useMemo11(() => {
11730
11545
  const interaction = [...input.activePendingInteractions].reverse().find((candidate) => candidate.kind !== "approval") ?? null;
11731
- return interactivePromptFromInteraction(interaction);
11546
+ return projectAgentInteractivePromptFromInteraction(interaction);
11732
11547
  }, [input.activePendingInteractions]);
11733
11548
  const queuedPrompts = useMemo11(
11734
11549
  () => input.activeConversationId ? input.activeQueuedPrompts.map((prompt) => ({
@@ -13151,6 +12966,7 @@ function useAgentGUISessionEngineState(input) {
13151
12966
  ),
13152
12967
  activeSessionState,
13153
12968
  activeSessionDetailLoading,
12969
+ activeSessionReconcileErrorCode: activeSessionReconcile?.errorCode ?? null,
13154
12970
  activeSessionReconcileError: activeSessionDetailHydrated ? null : activeSessionReconcile?.errorMessage ?? null,
13155
12971
  isCreatingConversation,
13156
12972
  hasUnconfirmedSubmit,
@@ -14084,6 +13900,7 @@ function useAgentGUINodeController({
14084
13900
  activeConversationId,
14085
13901
  activeConversationIdRef,
14086
13902
  activePendingActivation,
13903
+ activeSessionReconcileErrorCode: sessionEngineState.activeSessionReconcileErrorCode,
14087
13904
  agentActivityRuntime,
14088
13905
  attentionReadRecordsBySessionId: attentionReadState.recordsBySessionId,
14089
13906
  conversationIdsRef,
@@ -15009,7 +14826,7 @@ import {
15009
14826
  useCallback as useCallback66,
15010
14827
  useEffect as useEffect38,
15011
14828
  useMemo as useMemo47,
15012
- useRef as useRef60,
14829
+ useRef as useRef61,
15013
14830
  useState as useState53
15014
14831
  } from "react";
15015
14832
  import { TooltipProvider as TooltipProvider7 } from "@tutti-os/ui-system";
@@ -15242,7 +15059,7 @@ function numberValue(value) {
15242
15059
  }
15243
15060
  return null;
15244
15061
  }
15245
- function stringValue3(value) {
15062
+ function stringValue2(value) {
15246
15063
  return typeof value === "string" ? value : "";
15247
15064
  }
15248
15065
  function useStableEventCallback(callback) {
@@ -15452,6 +15269,7 @@ function SettingsLinedIcon(props) {
15452
15269
  // agent-gui/agentGuiNode/view/AgentGUIAccountConfig.tsx
15453
15270
  import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
15454
15271
  function AgentGUIConfigMenu({
15272
+ accountContent,
15455
15273
  environmentSetupVisible,
15456
15274
  labels,
15457
15275
  providerScopedActionsVisible,
@@ -15475,6 +15293,7 @@ function AgentGUIConfigMenu({
15475
15293
  );
15476
15294
  const providerDisplayTitle = provider?.trim() ? labels.slashStatusProviderAccount(provider.trim()) : null;
15477
15295
  const accountTitle = providerDisplayTitle ?? labels.slashStatusAccount;
15296
+ const hasAccountContent = Boolean(accountContent) && typeof accountContent !== "boolean";
15478
15297
  return /* @__PURE__ */ jsxs7(
15479
15298
  Popover,
15480
15299
  {
@@ -15506,7 +15325,11 @@ function AgentGUIConfigMenu({
15506
15325
  className: "w-[300px] max-w-[calc(100vw-32px)] gap-3 p-1 text-xs",
15507
15326
  "data-testid": "agent-gui-config-menu",
15508
15327
  children: /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-col gap-1", children: [
15509
- providerScopedActionsVisible && providerAuthAccountLabel ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
15328
+ hasAccountContent ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
15329
+ accountContent,
15330
+ /* @__PURE__ */ jsx14("div", { className: "px-2", children: /* @__PURE__ */ jsx14("span", { className: "block h-px bg-[var(--border-1)]" }) })
15331
+ ] }) : null,
15332
+ !hasAccountContent && providerScopedActionsVisible && providerAuthAccountLabel ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
15510
15333
  /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-col gap-2 p-2", children: [
15511
15334
  /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 items-center gap-2", children: [
15512
15335
  providerFlatIconUrl ? /* @__PURE__ */ jsx14(
@@ -15526,7 +15349,7 @@ function AgentGUIConfigMenu({
15526
15349
  ] }),
15527
15350
  slashStatusLimits.length > 0 || slashStatusUsageAttempted || slashStatusLimitsLoading ? /* @__PURE__ */ jsx14("div", { className: "px-2", children: /* @__PURE__ */ jsx14("span", { className: "block h-px bg-[var(--border-1)]" }) }) : null
15528
15351
  ] }) : null,
15529
- providerScopedActionsVisible && (slashStatusLimits.length > 0 || slashStatusUsageAttempted || slashStatusLimitsLoading) ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
15352
+ !hasAccountContent && providerScopedActionsVisible && (slashStatusLimits.length > 0 || slashStatusUsageAttempted || slashStatusLimitsLoading) ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
15530
15353
  /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-col gap-2 p-2", children: [
15531
15354
  /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 items-center justify-between gap-2", children: [
15532
15355
  /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 items-center gap-2", children: [
@@ -16047,7 +15870,6 @@ var BADGE_CORNER_RADIUS = 0.5;
16047
15870
  var BADGE_DIAMETER = 0.36;
16048
15871
  var BADGE_OFFSET = 0.48;
16049
15872
  var MAX_PIXEL_RATIO = 2;
16050
- var RECORD_SPIN_SECONDS = 10;
16051
15873
  var RECORD_MODEL_SCALE = 1.3;
16052
15874
  var RECORD_MODEL_RADIUS = 0.45;
16053
15875
  var RECORD_MODEL_THICKNESS = 0.03;
@@ -16098,10 +15920,8 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16098
15920
  velocity = 0;
16099
15921
  renderFrameHandle = null;
16100
15922
  springFrameHandle = null;
16101
- recordSpinFrameHandle = null;
16102
15923
  lastFrameAt = null;
16103
- lastRecordSpinFrameAt = null;
16104
- hoveredTile = null;
15924
+ visible = true;
16105
15925
  disposed = false;
16106
15926
  constructor(options) {
16107
15927
  this.agentCount = options.items.length;
@@ -16191,8 +16011,6 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16191
16011
  faceMesh,
16192
16012
  poseGroup,
16193
16013
  ready: false,
16194
- recordGroup,
16195
- rotation: 0,
16196
16014
  vinylTexture: null
16197
16015
  });
16198
16016
  }
@@ -16211,7 +16029,6 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16211
16029
  }
16212
16030
  });
16213
16031
  this.applyPoses();
16214
- this.startRecordSpin();
16215
16032
  }
16216
16033
  setSize(width, height) {
16217
16034
  if (this.disposed || width <= 0 || height <= 0) {
@@ -16223,7 +16040,35 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16223
16040
  this.renderer.setSize(width, height, false);
16224
16041
  this.camera.aspect = width / height;
16225
16042
  this.camera.updateProjectionMatrix();
16226
- this.renderer.render(this.scene, this.camera);
16043
+ if (this.visible) {
16044
+ this.renderer.render(this.scene, this.camera);
16045
+ }
16046
+ }
16047
+ setVisible(visible) {
16048
+ if (this.disposed || this.visible === visible) {
16049
+ return;
16050
+ }
16051
+ this.visible = visible;
16052
+ this.cancelScheduledFrames();
16053
+ if (!visible) {
16054
+ return;
16055
+ }
16056
+ const hasPendingMotion = Math.abs(this.target - this.scroll) > SPRING_SETTLE_EPSILON || Math.abs(this.velocity) > SPRING_SETTLE_VELOCITY;
16057
+ if (this.prefersReducedMotion()) {
16058
+ this.scroll = this.target;
16059
+ this.velocity = 0;
16060
+ this.applyPoses();
16061
+ this.requestRender();
16062
+ if (hasPendingMotion) {
16063
+ this.onSettle(this.targetIndex());
16064
+ }
16065
+ return;
16066
+ }
16067
+ if (hasPendingMotion) {
16068
+ this.animate();
16069
+ return;
16070
+ }
16071
+ this.requestRender();
16227
16072
  }
16228
16073
  // Agent index of the tile slot the wheel is heading to.
16229
16074
  targetIndex() {
@@ -16278,21 +16123,11 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16278
16123
  const index = tile?.poseGroup.userData.agentIndex;
16279
16124
  return typeof index === "number" ? index : null;
16280
16125
  }
16281
- // Gives playback to the record beneath the pointer. When no record is
16282
- // hovered, playback returns to the record nearest the center.
16283
16126
  hover(x, y, width, height) {
16284
16127
  const tile = this.pickTile(x, y, width, height);
16285
- if (tile !== this.hoveredTile) {
16286
- this.hoveredTile = tile;
16287
- this.startRecordSpin();
16288
- }
16289
16128
  const index = tile?.poseGroup.userData.agentIndex;
16290
16129
  return typeof index === "number" ? index : null;
16291
16130
  }
16292
- clearHover() {
16293
- this.hoveredTile = null;
16294
- this.startRecordSpin();
16295
- }
16296
16131
  pickTile(x, y, width, height) {
16297
16132
  if (this.disposed || width <= 0 || height <= 0) {
16298
16133
  return null;
@@ -16317,18 +16152,7 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16317
16152
  }
16318
16153
  dispose() {
16319
16154
  this.disposed = true;
16320
- if (this.renderFrameHandle !== null) {
16321
- cancelAnimationFrame(this.renderFrameHandle);
16322
- this.renderFrameHandle = null;
16323
- }
16324
- if (this.springFrameHandle !== null) {
16325
- cancelAnimationFrame(this.springFrameHandle);
16326
- this.springFrameHandle = null;
16327
- }
16328
- if (this.recordSpinFrameHandle !== null) {
16329
- cancelAnimationFrame(this.recordSpinFrameHandle);
16330
- this.recordSpinFrameHandle = null;
16331
- }
16155
+ this.cancelScheduledFrames();
16332
16156
  for (const tile of this.tiles) {
16333
16157
  tile.badgeMesh.geometry.dispose();
16334
16158
  tile.badgeMesh.material.dispose();
@@ -16343,11 +16167,22 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16343
16167
  this.edgeGeometry.dispose();
16344
16168
  this.renderer.dispose();
16345
16169
  }
16170
+ cancelScheduledFrames() {
16171
+ if (this.renderFrameHandle !== null) {
16172
+ cancelAnimationFrame(this.renderFrameHandle);
16173
+ this.renderFrameHandle = null;
16174
+ }
16175
+ if (this.springFrameHandle !== null) {
16176
+ cancelAnimationFrame(this.springFrameHandle);
16177
+ this.springFrameHandle = null;
16178
+ }
16179
+ this.lastFrameAt = null;
16180
+ }
16346
16181
  prefersReducedMotion() {
16347
16182
  return typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
16348
16183
  }
16349
16184
  animate() {
16350
- if (this.disposed) {
16185
+ if (this.disposed || !this.visible) {
16351
16186
  return;
16352
16187
  }
16353
16188
  if (this.prefersReducedMotion()) {
@@ -16379,7 +16214,7 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16379
16214
  }
16380
16215
  frame = (now) => {
16381
16216
  this.springFrameHandle = null;
16382
- if (this.disposed) {
16217
+ if (this.disposed || !this.visible) {
16383
16218
  return;
16384
16219
  }
16385
16220
  const dt = this.lastFrameAt === null ? 1 / 60 : Math.min((now - this.lastFrameAt) / 1e3, MAX_FRAME_DELTA_SECONDS);
@@ -16400,53 +16235,13 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16400
16235
  this.renderer.render(this.scene, this.camera);
16401
16236
  this.springFrameHandle = requestAnimationFrame(this.frame);
16402
16237
  };
16403
- startRecordSpin() {
16404
- if (this.disposed || this.prefersReducedMotion() || this.recordSpinFrameHandle !== null) {
16405
- return;
16406
- }
16407
- this.lastRecordSpinFrameAt = null;
16408
- this.recordSpinFrameHandle = requestAnimationFrame(this.recordSpinFrame);
16409
- }
16410
- recordSpinFrame = (now) => {
16411
- this.recordSpinFrameHandle = null;
16412
- const spinningTile = this.centerTile();
16413
- if (this.disposed || !spinningTile || this.prefersReducedMotion()) {
16414
- return;
16415
- }
16416
- const dt = this.lastRecordSpinFrameAt === null ? 1 / 60 : Math.min(
16417
- (now - this.lastRecordSpinFrameAt) / 1e3,
16418
- MAX_FRAME_DELTA_SECONDS
16419
- );
16420
- this.lastRecordSpinFrameAt = now;
16421
- spinningTile.rotation = (spinningTile.rotation + Math.PI * 2 * dt / RECORD_SPIN_SECONDS) % (Math.PI * 2);
16422
- if (this.springFrameHandle === null) {
16423
- this.applyPoses();
16424
- this.renderer.render(this.scene, this.camera);
16425
- }
16426
- this.recordSpinFrameHandle = requestAnimationFrame(this.recordSpinFrame);
16427
- };
16428
- centerTile() {
16429
- let centeredTile = null;
16430
- let centeredOffset = Number.POSITIVE_INFINITY;
16431
- this.tiles.forEach((tile, index) => {
16432
- if (!tile.ready) {
16433
- return;
16434
- }
16435
- const offset = Math.abs(ringOffset(index, this.scroll, this.tileCount));
16436
- if (offset < centeredOffset) {
16437
- centeredTile = tile;
16438
- centeredOffset = offset;
16439
- }
16440
- });
16441
- return centeredTile;
16442
- }
16443
16238
  requestRender() {
16444
- if (this.disposed || this.renderFrameHandle !== null || this.springFrameHandle !== null) {
16239
+ if (this.disposed || !this.visible || this.renderFrameHandle !== null || this.springFrameHandle !== null) {
16445
16240
  return;
16446
16241
  }
16447
16242
  this.renderFrameHandle = requestAnimationFrame(() => {
16448
16243
  this.renderFrameHandle = null;
16449
- if (!this.disposed) {
16244
+ if (!this.disposed && this.visible) {
16450
16245
  this.renderer.render(this.scene, this.camera);
16451
16246
  }
16452
16247
  });
@@ -16467,7 +16262,6 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16467
16262
  }
16468
16263
  }
16469
16264
  this.applyPoses();
16470
- this.startRecordSpin();
16471
16265
  }
16472
16266
  applyCoverImageTexture(image, agentIndex) {
16473
16267
  if (this.disposed) {
@@ -16546,7 +16340,6 @@ var AgentGuiHeroCarouselScene = class _AgentGuiHeroCarouselScene {
16546
16340
  ),
16547
16341
  -angle * VISIBLE_ARC_CURVATURE
16548
16342
  );
16549
- tile.recordGroup.rotation.z = isCenterTile ? -tile.rotation : 0;
16550
16343
  const edgeKill = 1 - THREE2.MathUtils.smoothstep(
16551
16344
  Math.abs(offset),
16552
16345
  RECORD_EDGE_KILL_START_SLOTS,
@@ -16609,11 +16402,9 @@ function AgentGUIVinylPlayer({
16609
16402
  }
16610
16403
  ) }),
16611
16404
  /* @__PURE__ */ jsx15("div", { className: "agent-gui-vinyl-player__platter", children: /* @__PURE__ */ jsx15("div", { className: "agent-gui-vinyl-player__platter-inner", children: /* @__PURE__ */ jsxs8(
16612
- motion.div,
16405
+ "div",
16613
16406
  {
16614
- className: "agent-gui-vinyl-player__record",
16615
- animate: { rotate: isPlaying ? 360 : 0 },
16616
- transition: { duration: 4, repeat: Infinity, ease: "linear" },
16407
+ className: `agent-gui-vinyl-player__record${isPlaying ? " agent-gui-vinyl-player__record--playing" : ""}`,
16617
16408
  children: [
16618
16409
  Array.from({ length: 18 }, (_, index) => /* @__PURE__ */ jsx15(
16619
16410
  "span",
@@ -16851,7 +16642,9 @@ var AgentGUIHeroAgentCarousel = class extends Component {
16851
16642
  if (previousProps.isVisible !== this.props.isVisible) {
16852
16643
  if (this.props.isVisible === false) {
16853
16644
  this.cancelScheduledSceneMount();
16645
+ this.scene?.setVisible(false);
16854
16646
  } else {
16647
+ this.scene?.setVisible(true);
16855
16648
  this.scheduleSceneMount();
16856
16649
  }
16857
16650
  }
@@ -16994,7 +16787,9 @@ var AgentGUIHeroAgentCarousel = class extends Component {
16994
16787
  }
16995
16788
  syncWheelListener() {
16996
16789
  const stage = this.stageRef.current;
16997
- const shouldAttach = Boolean(stage && this.interactive());
16790
+ const shouldAttach = Boolean(
16791
+ stage && this.props.isVisible !== false && this.interactive()
16792
+ );
16998
16793
  if (shouldAttach && !this.wheelListenerAttached) {
16999
16794
  stage.addEventListener("wheel", this.handleWheel, { passive: false });
17000
16795
  this.wheelListenerAttached = true;
@@ -17155,7 +16950,6 @@ var AgentGUIHeroAgentCarousel = class extends Component {
17155
16950
  canvas.style.cursor = hoveredIndex !== null ? "pointer" : "";
17156
16951
  };
17157
16952
  handleCanvasLeave = () => {
17158
- this.scene?.clearHover();
17159
16953
  if (this.canvasRef.current) {
17160
16954
  this.canvasRef.current.style.cursor = "";
17161
16955
  }
@@ -17182,7 +16976,7 @@ var AgentGUIHeroAgentCarousel = class extends Component {
17182
16976
  AgentGUIVinylPlayer,
17183
16977
  {
17184
16978
  selectedAgent: this.props.items[this.state.centerIndex] ?? this.props.items[0] ?? null,
17185
- isPlaying: true
16979
+ isPlaying: this.props.isActive !== false && this.props.isVisible !== false
17186
16980
  }
17187
16981
  ),
17188
16982
  /* @__PURE__ */ jsx16(
@@ -19245,11 +19039,6 @@ function resolveComposerProviderTargetIconUrl(target) {
19245
19039
  const identity = resolveAgentGUIProviderCatalogIdentity(target.provider);
19246
19040
  return target.iconUrl ?? (identity ? resolveProviderIconAsset(identity.iconKey, "rounded") : null) ?? resolveComposerProviderIconUrl(target.provider);
19247
19041
  }
19248
- function resolveMentionPalettePortalTarget(anchor) {
19249
- return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? anchor.closest(
19250
- "[data-workbench-window-id], [data-workspace-node-window-root='true']"
19251
- ) ?? document.body;
19252
- }
19253
19042
  function resolveMentionPaletteZIndex(anchor) {
19254
19043
  let current = anchor;
19255
19044
  while (current) {
@@ -19345,6 +19134,17 @@ function AgentComposerHandoffIcon({
19345
19134
  );
19346
19135
  }
19347
19136
 
19137
+ // agent-gui/agentGuiNode/composer/composerPortalTarget.ts
19138
+ var VIEWPORT_MENU_BOUNDARY_SELECTOR = '[data-slot="viewport-menu-boundary"]';
19139
+ var COMPOSER_MENU_WINDOW_FRAME_SELECTOR = "[data-workbench-window-id], [data-workspace-node-window-root='true']";
19140
+ function resolveComposerPortalTarget(anchor) {
19141
+ const boundary = anchor.closest(VIEWPORT_MENU_BOUNDARY_SELECTOR);
19142
+ if (boundary?.getAttribute("data-viewport-menu-portal-target") === "body") {
19143
+ return document.body;
19144
+ }
19145
+ return boundary ?? anchor.closest(COMPOSER_MENU_WINDOW_FRAME_SELECTOR) ?? document.body;
19146
+ }
19147
+
19348
19148
  // agent-gui/agentGuiNode/composer/useMentionPaletteFrame.ts
19349
19149
  function useMentionPaletteFrame(inputShellRef, showFileMentionPalette) {
19350
19150
  const [mentionPaletteFrame, setMentionPaletteFrame] = useState11(null);
@@ -19376,7 +19176,7 @@ function useMentionPaletteFrame(inputShellRef, showFileMentionPalette) {
19376
19176
  setMentionPaletteFrame({
19377
19177
  height,
19378
19178
  left,
19379
- portalTarget: resolveMentionPalettePortalTarget(anchor),
19179
+ portalTarget: resolveComposerPortalTarget(anchor),
19380
19180
  top: Math.max(
19381
19181
  MENTION_PALETTE_VIEWPORT_PADDING_PX,
19382
19182
  Math.min(
@@ -25351,17 +25151,14 @@ var COMPOSER_MENU_GAP_PX = 8;
25351
25151
  var COMPOSER_MENU_VIEWPORT_PADDING_PX = 8;
25352
25152
  var COMPOSER_MENU_TOP_SAFE_AREA_PX = DESKTOP_WINDOW_TOP_MARGIN;
25353
25153
  var COMPOSER_MENU_MIN_HEIGHT_PX = 280;
25354
- var COMPOSER_MENU_WINDOW_FRAME_SELECTOR = "[data-workbench-window-id], [data-workspace-node-window-root='true']";
25154
+ var COMPOSER_MENU_WINDOW_FRAME_SELECTOR2 = "[data-workbench-window-id], [data-workspace-node-window-root='true']";
25355
25155
  function resolveComposerMenuWindowFrame(anchor) {
25356
- return anchor.closest(COMPOSER_MENU_WINDOW_FRAME_SELECTOR);
25357
- }
25358
- function resolveComposerMenuPortalTarget(anchor) {
25359
- return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? resolveComposerMenuWindowFrame(anchor) ?? document.body;
25156
+ return anchor.closest(COMPOSER_MENU_WINDOW_FRAME_SELECTOR2);
25360
25157
  }
25361
25158
  function resolveComposerMenuZIndex(anchor) {
25362
25159
  let current = anchor;
25363
25160
  while (current) {
25364
- if (current.matches(COMPOSER_MENU_WINDOW_FRAME_SELECTOR)) {
25161
+ if (current.matches(COMPOSER_MENU_WINDOW_FRAME_SELECTOR2)) {
25365
25162
  const windowZIndex = Number.parseInt(
25366
25163
  window.getComputedStyle(current).zIndex,
25367
25164
  10
@@ -25415,7 +25212,7 @@ function computeComposerAnchoredMenuFrame(anchor, maxHeight) {
25415
25212
  height,
25416
25213
  left,
25417
25214
  minHeight,
25418
- portalTarget: resolveComposerMenuPortalTarget(anchor),
25215
+ portalTarget: resolveComposerPortalTarget(anchor),
25419
25216
  top: Math.max(
25420
25217
  topSafeArea,
25421
25218
  Math.min(
@@ -25577,7 +25374,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
25577
25374
  if (!open || typeof document === "undefined" || !document.body) {
25578
25375
  return null;
25579
25376
  }
25580
- const portalTarget = frame?.portalTarget ?? (anchorRef.current ? resolveComposerMenuPortalTarget(anchorRef.current) : document.body);
25377
+ const portalTarget = frame?.portalTarget ?? (anchorRef.current ? resolveComposerPortalTarget(anchorRef.current) : document.body);
25581
25378
  return createPortal3(
25582
25379
  /* @__PURE__ */ jsx34(
25583
25380
  "div",
@@ -29267,6 +29064,7 @@ var AgentGUIEmptyHeroCarouselStage = class extends Component3 {
29267
29064
  const {
29268
29065
  activeAgentTargetId,
29269
29066
  children,
29067
+ isActive,
29270
29068
  isVisible,
29271
29069
  items,
29272
29070
  onProviderSelect,
@@ -29278,6 +29076,7 @@ var AgentGUIEmptyHeroCarouselStage = class extends Component3 {
29278
29076
  AgentGUIHeroAgentCarousel,
29279
29077
  {
29280
29078
  activeAgentTargetId,
29079
+ isActive,
29281
29080
  isVisible,
29282
29081
  items,
29283
29082
  onProviderSelect,
@@ -29954,6 +29753,7 @@ function shouldEmphasizeEmptyHeroProvider(label) {
29954
29753
  }
29955
29754
  var EMPTY_HOME_SUGGESTIONS = Object.freeze([]);
29956
29755
  var AgentGUIEmptyHomePane = memo2(function AgentGUIEmptyHomePane2({
29756
+ isActive,
29957
29757
  isVisible,
29958
29758
  provider,
29959
29759
  providerReadinessGate,
@@ -29987,6 +29787,7 @@ var AgentGUIEmptyHomePane = memo2(function AgentGUIEmptyHomePane2({
29987
29787
  AgentGUIEmptyHeroCarouselStage,
29988
29788
  {
29989
29789
  activeAgentTargetId: presentedSelectedAgentTarget?.agentTargetId ?? presentedSelectedAgentTarget?.targetId,
29790
+ isActive,
29990
29791
  isVisible,
29991
29792
  items: avatarPresentations,
29992
29793
  onProviderSelect,
@@ -29998,6 +29799,7 @@ var AgentGUIEmptyHomePane = memo2(function AgentGUIEmptyHomePane2({
29998
29799
  children: providerReadinessGate ? /* @__PURE__ */ jsx50(
29999
29800
  AgentGUIProviderReadinessGatePane,
30000
29801
  {
29802
+ isActive,
30001
29803
  isVisible,
30002
29804
  provider,
30003
29805
  gate: providerReadinessGate,
@@ -30016,6 +29818,7 @@ var AgentGUIEmptyHomePane = memo2(function AgentGUIEmptyHomePane2({
30016
29818
  AgentGUIEmptyHeroPane,
30017
29819
  {
30018
29820
  ...heroProps,
29821
+ isActive,
30019
29822
  isVisible,
30020
29823
  provider,
30021
29824
  emptyLabel,
@@ -30035,6 +29838,7 @@ var AgentGUIEmptyHomePane = memo2(function AgentGUIEmptyHomePane2({
30035
29838
  );
30036
29839
  });
30037
29840
  var AgentGUIEmptyHeroPane = memo2(function AgentGUIEmptyHeroPane2({
29841
+ isActive = true,
30038
29842
  isVisible = true,
30039
29843
  provider,
30040
29844
  emptyLabel,
@@ -30079,6 +29883,7 @@ var AgentGUIEmptyHeroPane = memo2(function AgentGUIEmptyHeroPane2({
30079
29883
  AgentGUIHeroAgentCarousel,
30080
29884
  {
30081
29885
  activeAgentTargetId: selectedAgentTarget?.agentTargetId ?? selectedAgentTarget?.targetId,
29886
+ isActive,
30082
29887
  items: heroAvatarPresentations,
30083
29888
  isVisible,
30084
29889
  onProviderSelect,
@@ -30132,6 +29937,7 @@ var AgentGUIEmptyHeroPane = memo2(function AgentGUIEmptyHeroPane2({
30132
29937
  });
30133
29938
  var AgentGUIProviderReadinessGatePane = memo2(
30134
29939
  function AgentGUIProviderReadinessGatePane2({
29940
+ isActive = true,
30135
29941
  isVisible = true,
30136
29942
  provider,
30137
29943
  gate,
@@ -30183,6 +29989,7 @@ var AgentGUIProviderReadinessGatePane = memo2(
30183
29989
  AgentGUIHeroAgentCarousel,
30184
29990
  {
30185
29991
  activeAgentTargetId: selectedAgentTarget?.agentTargetId ?? selectedAgentTarget?.targetId,
29992
+ isActive,
30186
29993
  items: heroAvatarPresentations,
30187
29994
  isVisible,
30188
29995
  onProviderSelect,
@@ -36310,7 +36117,7 @@ var AgentGUIConversationRailController = memo8(
36310
36117
  );
36311
36118
 
36312
36119
  // agent-gui/agentGuiNode/view/AgentGUIDetailPane.tsx
36313
- import { memo as memo12, useCallback as useCallback60, useEffect as useEffect34, useMemo as useMemo44, useRef as useRef54, useState as useState50 } from "react";
36120
+ import { memo as memo12, useCallback as useCallback60, useEffect as useEffect34, useMemo as useMemo44, useRef as useRef55, useState as useState50 } from "react";
36314
36121
 
36315
36122
  // agent-gui/agentGuiNode/view/agentGUIDetailModelHelpers.ts
36316
36123
  import { useRef as useRef51 } from "react";
@@ -36497,8 +36304,8 @@ function mergeWorkspaceAppIconsFromCommands(input) {
36497
36304
  if (!source) {
36498
36305
  continue;
36499
36306
  }
36500
- const appId = stringValue3(source.appId).trim();
36501
- const iconUrl = stringValue3(source.iconUrl).trim();
36307
+ const appId = stringValue2(source.appId).trim();
36308
+ const iconUrl = stringValue2(source.iconUrl).trim();
36502
36309
  if (!appId || !iconUrl) {
36503
36310
  continue;
36504
36311
  }
@@ -38819,8 +38626,8 @@ var AgentGUIBottomDockPane = memo9(function AgentGUIBottomDockPane2({
38819
38626
  }) {
38820
38627
  "use memo";
38821
38628
  const goal = objectRecord(sessionChrome.rawState?.goal);
38822
- const goalObjective = goal ? stringValue3(goal.objective) : "";
38823
- const goalStatus = goal ? stringValue3(goal.status) : "";
38629
+ const goalObjective = goal ? stringValue2(goal.objective) : "";
38630
+ const goalStatus = goal ? stringValue2(goal.status) : "";
38824
38631
  const goalTokenBudget = goal ? numberValue(goal.tokenBudget) : null;
38825
38632
  const goalTokensUsed = goal ? numberValue(goal.tokens) : null;
38826
38633
  const goalDurationMs = goal ? numberValue(goal.durationMs) : null;
@@ -39011,6 +38818,76 @@ import { ScrollArea as ScrollArea3 } from "@tutti-os/ui-system/components";
39011
38818
 
39012
38819
  // agent-gui/agentGuiNode/view/AgentGUIConversationTimelinePane.tsx
39013
38820
  import { memo as memo10 } from "react";
38821
+
38822
+ // agent-gui/agentGuiNode/view/agentGUIDetailScrollHelpers.ts
38823
+ function readTimelineGeometry(timeline) {
38824
+ const scrollHeight = timeline.scrollHeight;
38825
+ const clientHeight = timeline.clientHeight;
38826
+ return {
38827
+ clientHeight,
38828
+ maxScrollTop: Math.max(0, scrollHeight - clientHeight),
38829
+ scrollHeight
38830
+ };
38831
+ }
38832
+ function matchingVirtualScrollController(controllerRef, agentSessionId) {
38833
+ const controller = controllerRef.current;
38834
+ return controller?.enabled && controller.agentSessionId === agentSessionId ? controller : null;
38835
+ }
38836
+ function hasStaleVirtualScrollController(controllerRef, agentSessionId) {
38837
+ const controller = controllerRef.current;
38838
+ return controller?.enabled === true && controller.agentSessionId !== agentSessionId;
38839
+ }
38840
+ function userScrollBehavior() {
38841
+ return typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth";
38842
+ }
38843
+ function readBottomDockSafeArea(bottomDock) {
38844
+ const bottomDockRect = bottomDock.getBoundingClientRect();
38845
+ let timelineVisualTop = bottomDockRect.top;
38846
+ let floatingVisualTop = bottomDockRect.top;
38847
+ bottomDock.querySelectorAll("*").forEach((element) => {
38848
+ if (element.closest(`.${AgentGUINode_styles_default.bottomDockScrollToBottom}`)) {
38849
+ return;
38850
+ }
38851
+ const rect = element.getBoundingClientRect();
38852
+ if (rect.width <= 0 || rect.height <= 0) {
38853
+ return;
38854
+ }
38855
+ if (element.closest(`.${AgentGUINode_styles_default.composerInputShell}`)) {
38856
+ if (element.matches(".agent-gui-node__composer-prompt-input-area")) {
38857
+ floatingVisualTop = Math.min(floatingVisualTop, rect.top);
38858
+ }
38859
+ return;
38860
+ }
38861
+ if (element.closest(`.${AgentGUINode_styles_default.composerDisclosurePanel}`)) {
38862
+ floatingVisualTop = Math.min(floatingVisualTop, rect.top);
38863
+ return;
38864
+ }
38865
+ floatingVisualTop = Math.min(floatingVisualTop, rect.top);
38866
+ timelineVisualTop = Math.min(timelineVisualTop, rect.top);
38867
+ });
38868
+ return {
38869
+ timelineOverflowHeight: Math.max(
38870
+ 0,
38871
+ Math.ceil(bottomDockRect.top - timelineVisualTop)
38872
+ ),
38873
+ floatingOverflowHeight: Math.max(
38874
+ 0,
38875
+ Math.ceil(bottomDockRect.top - floatingVisualTop)
38876
+ )
38877
+ };
38878
+ }
38879
+ function writeBottomDockSafeArea(timeline, safeArea) {
38880
+ timeline.style.setProperty(
38881
+ "--agent-gui-bottom-dock-safe-area",
38882
+ `${safeArea.timelineOverflowHeight}px`
38883
+ );
38884
+ safeArea.bottomDock.style.setProperty(
38885
+ "--agent-gui-bottom-dock-floating-safe-area",
38886
+ `${safeArea.floatingOverflowHeight}px`
38887
+ );
38888
+ }
38889
+
38890
+ // agent-gui/agentGuiNode/view/AgentGUIConversationTimelinePane.tsx
39014
38891
  import { Fragment as Fragment24, jsx as jsx78, jsxs as jsxs56 } from "react/jsx-runtime";
39015
38892
  var EMPTY_WORKSPACE_APP_ICONS3 = [];
39016
38893
  var AgentGUIConversationTimelinePane = memo10(
@@ -39021,6 +38898,7 @@ var AgentGUIConversationTimelinePane = memo10(
39021
38898
  onTurnAttachmentVisibilityChange,
39022
38899
  isLoading,
39023
38900
  isLoadingOlderMessages,
38901
+ virtualScrollControllerRef,
39024
38902
  loadingLabel,
39025
38903
  empty,
39026
38904
  onLinkAction,
@@ -39054,7 +38932,9 @@ var AgentGUIConversationTimelinePane = memo10(
39054
38932
  onAuthLogin,
39055
38933
  availableSkills,
39056
38934
  workspaceAppIcons,
39057
- labels
38935
+ labels,
38936
+ virtualListLayoutRevision: isLoadingOlderMessages ? 1 : 0,
38937
+ virtualScrollControllerRef
39058
38938
  }
39059
38939
  )
39060
38940
  ] });
@@ -39064,11 +38944,10 @@ function setTimelineScrollTopInstantly(element, top) {
39064
38944
  element.scrollTop = top;
39065
38945
  }
39066
38946
  function setTimelineScrollTopWithUserTransition(element, top) {
39067
- const reducedMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
39068
38947
  if (typeof element.scrollTo === "function") {
39069
38948
  element.scrollTo({
39070
38949
  top,
39071
- behavior: reducedMotion ? "auto" : "smooth"
38950
+ behavior: userScrollBehavior()
39072
38951
  });
39073
38952
  return;
39074
38953
  }
@@ -39100,6 +38979,7 @@ var AgentGUIDetailTimeline = memo11(function AgentGUIDetailTimeline2({
39100
38979
  showUnavailableChatEmpty,
39101
38980
  timelineContentRef,
39102
38981
  timelineRef,
38982
+ virtualScrollControllerRef,
39103
38983
  workspaceAppIcons
39104
38984
  }) {
39105
38985
  "use memo";
@@ -39125,7 +39005,8 @@ var AgentGUIDetailTimeline = memo11(function AgentGUIDetailTimeline2({
39125
39005
  onAuthLogin,
39126
39006
  availableSkills,
39127
39007
  workspaceAppIcons,
39128
- labels: conversationFlowLabels
39008
+ labels: conversationFlowLabels,
39009
+ virtualScrollControllerRef
39129
39010
  }
39130
39011
  ) : homeContent
39131
39012
  }
@@ -39143,61 +39024,6 @@ import {
39143
39024
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
39144
39025
  var AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX = 240;
39145
39026
  var AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX = 1;
39146
- function readTimelineGeometry(timeline) {
39147
- const scrollHeight = timeline.scrollHeight;
39148
- const clientHeight = timeline.clientHeight;
39149
- return {
39150
- clientHeight,
39151
- maxScrollTop: Math.max(0, scrollHeight - clientHeight),
39152
- scrollHeight
39153
- };
39154
- }
39155
- function readBottomDockSafeArea(bottomDock) {
39156
- const bottomDockRect = bottomDock.getBoundingClientRect();
39157
- let timelineVisualTop = bottomDockRect.top;
39158
- let floatingVisualTop = bottomDockRect.top;
39159
- bottomDock.querySelectorAll("*").forEach((element) => {
39160
- if (element.closest(`.${AgentGUINode_styles_default.bottomDockScrollToBottom}`)) {
39161
- return;
39162
- }
39163
- const rect = element.getBoundingClientRect();
39164
- if (rect.width <= 0 || rect.height <= 0) {
39165
- return;
39166
- }
39167
- if (element.closest(`.${AgentGUINode_styles_default.composerInputShell}`)) {
39168
- if (element.matches(".agent-gui-node__composer-prompt-input-area")) {
39169
- floatingVisualTop = Math.min(floatingVisualTop, rect.top);
39170
- }
39171
- return;
39172
- }
39173
- if (element.closest(`.${AgentGUINode_styles_default.composerDisclosurePanel}`)) {
39174
- floatingVisualTop = Math.min(floatingVisualTop, rect.top);
39175
- return;
39176
- }
39177
- floatingVisualTop = Math.min(floatingVisualTop, rect.top);
39178
- timelineVisualTop = Math.min(timelineVisualTop, rect.top);
39179
- });
39180
- return {
39181
- timelineOverflowHeight: Math.max(
39182
- 0,
39183
- Math.ceil(bottomDockRect.top - timelineVisualTop)
39184
- ),
39185
- floatingOverflowHeight: Math.max(
39186
- 0,
39187
- Math.ceil(bottomDockRect.top - floatingVisualTop)
39188
- )
39189
- };
39190
- }
39191
- function writeBottomDockSafeArea(timeline, safeArea) {
39192
- timeline.style.setProperty(
39193
- "--agent-gui-bottom-dock-safe-area",
39194
- `${safeArea.timelineOverflowHeight}px`
39195
- );
39196
- safeArea.bottomDock.style.setProperty(
39197
- "--agent-gui-bottom-dock-floating-safe-area",
39198
- `${safeArea.floatingOverflowHeight}px`
39199
- );
39200
- }
39201
39027
  function useAgentGUIDetailScroll(input) {
39202
39028
  const {
39203
39029
  actions,
@@ -39211,6 +39037,7 @@ function useAgentGUIDetailScroll(input) {
39211
39037
  timelineContentRef,
39212
39038
  timelineRef,
39213
39039
  timelineScrollAnchorRef,
39040
+ virtualScrollControllerRef,
39214
39041
  viewModel
39215
39042
  } = input;
39216
39043
  const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState47(true);
@@ -39243,6 +39070,13 @@ function useAgentGUIDetailScroll(input) {
39243
39070
  bottomLockOwnerRef.current = null;
39244
39071
  return;
39245
39072
  }
39073
+ if (hasStaleVirtualScrollController(
39074
+ virtualScrollControllerRef,
39075
+ activeConversationId
39076
+ )) {
39077
+ bottomLockOwnerRef.current = null;
39078
+ return;
39079
+ }
39246
39080
  const anchor = timelineScrollAnchorRef.current;
39247
39081
  const prependAnchor = pendingPrependScrollAnchorRef.current;
39248
39082
  const shouldScrollSubmittedPromptToBottom = submittedPromptScrollConversationRef.current === activeConversationId;
@@ -39262,6 +39096,45 @@ function useAgentGUIDetailScroll(input) {
39262
39096
  if (!conversationChanged && !shouldScrollSubmittedPromptToBottom && !shouldRestorePrependAnchor && !timelineSkeletonChanged) {
39263
39097
  return;
39264
39098
  }
39099
+ const virtualScrollController = matchingVirtualScrollController(
39100
+ virtualScrollControllerRef,
39101
+ activeConversationId
39102
+ );
39103
+ if (virtualScrollController) {
39104
+ if (conversationChanged || shouldScrollSubmittedPromptToBottom) {
39105
+ bottomLockOwnerRef.current = activeConversationId;
39106
+ pointerScrollConversationRef.current = null;
39107
+ userScrollAwayIntentConversationRef.current = null;
39108
+ virtualScrollController.scrollToEnd({ behavior: "auto" });
39109
+ submittedPromptScrollConversationRef.current = null;
39110
+ if (shouldScrollSubmittedPromptToBottom) {
39111
+ pendingPrependScrollAnchorRef.current = null;
39112
+ }
39113
+ } else if (shouldRestorePrependAnchor && !viewModel.detail.isLoadingOlderMessages) {
39114
+ pendingPrependScrollAnchorRef.current = null;
39115
+ }
39116
+ const atBottom = virtualScrollController.isAtEnd();
39117
+ if (atBottom) {
39118
+ bottomLockOwnerRef.current = activeConversationId;
39119
+ }
39120
+ const virtualAnchor = anchor?.conversationId === activeConversationId ? anchor : {
39121
+ clientHeight: 0,
39122
+ conversationId: activeConversationId,
39123
+ scrollHeight: Number.POSITIVE_INFINITY,
39124
+ scrollTop: 0
39125
+ };
39126
+ timelineScrollAnchorRef.current = {
39127
+ ...virtualAnchor,
39128
+ conversationId: activeConversationId
39129
+ };
39130
+ setIsTimelineScrolledToTop(
39131
+ virtualAnchor.scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
39132
+ );
39133
+ setIsTimelineScrolledToBottom(
39134
+ atBottom || bottomLockOwnerRef.current === activeConversationId
39135
+ );
39136
+ return;
39137
+ }
39265
39138
  const geometry = readTimelineGeometry(timeline);
39266
39139
  const maxScrollTop = geometry.maxScrollTop;
39267
39140
  let nextScrollTop;
@@ -39369,6 +39242,21 @@ function useAgentGUIDetailScroll(input) {
39369
39242
  if (resolveBottomLockConversation() !== scheduledConversationId || timelineRef.current !== timeline) {
39370
39243
  return;
39371
39244
  }
39245
+ if (hasStaleVirtualScrollController(
39246
+ virtualScrollControllerRef,
39247
+ scheduledConversationId
39248
+ )) {
39249
+ return;
39250
+ }
39251
+ const virtualScrollController = matchingVirtualScrollController(
39252
+ virtualScrollControllerRef,
39253
+ scheduledConversationId
39254
+ );
39255
+ if (virtualScrollController) {
39256
+ virtualScrollController.scrollToEnd({ behavior: "auto" });
39257
+ setIsTimelineScrolledToBottom(true);
39258
+ return;
39259
+ }
39372
39260
  const geometry = readTimelineGeometry(timeline);
39373
39261
  const maxScrollTop = geometry.maxScrollTop;
39374
39262
  timeline.scrollTop = maxScrollTop;
@@ -39427,7 +39315,11 @@ function useAgentGUIDetailScroll(input) {
39427
39315
  return;
39428
39316
  }
39429
39317
  const loadOlderMessagesNearTop = (scrollTop, scrollHeight, clientHeight) => {
39430
- const bottomLocked = bottomLockOwnerRef.current === activeConversationId;
39318
+ const virtualScrollController = matchingVirtualScrollController(
39319
+ virtualScrollControllerRef,
39320
+ activeConversationId
39321
+ );
39322
+ const bottomLocked = bottomLockOwnerRef.current === activeConversationId || virtualScrollController?.isAtEnd() === true;
39431
39323
  const needsMoreContentToFillViewport = scrollHeight <= clientHeight;
39432
39324
  if (activeConversationId === viewModel.rail.activeConversationId && viewModel.detail.hasOlderMessages && !viewModel.detail.isLoadingOlderMessages && !showTimelineSkeleton && (!bottomLocked || needsMoreContentToFillViewport) && scrollTop <= AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX) {
39433
39325
  pendingPrependScrollAnchorRef.current = {
@@ -39450,6 +39342,33 @@ function useAgentGUIDetailScroll(input) {
39450
39342
  bottomLockOwnerRef.current = null;
39451
39343
  userScrollAwayIntentConversationRef.current = null;
39452
39344
  }
39345
+ const virtualScrollController = matchingVirtualScrollController(
39346
+ virtualScrollControllerRef,
39347
+ activeConversationId
39348
+ );
39349
+ if (virtualScrollController) {
39350
+ const atBottom2 = virtualScrollController.isAtEnd();
39351
+ if (atBottom2) {
39352
+ bottomLockOwnerRef.current = activeConversationId;
39353
+ }
39354
+ timelineScrollAnchorRef.current = {
39355
+ conversationId: activeConversationId,
39356
+ scrollHeight: previousAnchor.scrollHeight,
39357
+ scrollTop,
39358
+ clientHeight: previousAnchor.clientHeight
39359
+ };
39360
+ const effectiveAtBottom2 = atBottom2 || bottomLockOwnerRef.current === activeConversationId;
39361
+ setIsTimelineScrolledToTop(
39362
+ scrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
39363
+ );
39364
+ setIsTimelineScrolledToBottom(effectiveAtBottom2);
39365
+ loadOlderMessagesNearTop(
39366
+ scrollTop,
39367
+ previousAnchor.scrollHeight,
39368
+ previousAnchor.clientHeight
39369
+ );
39370
+ return;
39371
+ }
39453
39372
  const bottomLocked = bottomLockOwnerRef.current === activeConversationId;
39454
39373
  const anchoredMaxScrollTop = Math.max(
39455
39374
  0,
@@ -39480,11 +39399,44 @@ function useAgentGUIDetailScroll(input) {
39480
39399
  previousAnchor.clientHeight
39481
39400
  );
39482
39401
  };
39483
- const syncObservedTimelineGeometry = () => {
39402
+ const syncObservedTimelineGeometry = (entries) => {
39484
39403
  const anchor = timelineScrollAnchorRef.current;
39485
39404
  if (!anchor || anchor.conversationId !== activeConversationId) {
39486
39405
  return;
39487
39406
  }
39407
+ const virtualScrollController = matchingVirtualScrollController(
39408
+ virtualScrollControllerRef,
39409
+ activeConversationId
39410
+ );
39411
+ if (virtualScrollController) {
39412
+ const scrollTop2 = timeline.scrollTop;
39413
+ const observedClientHeight = entries.find(
39414
+ (entry) => entry.target === timeline
39415
+ )?.contentRect.height;
39416
+ const observedScrollHeight = entries.find(
39417
+ (entry) => entry.target === timelineContent
39418
+ )?.contentRect.height;
39419
+ const clientHeight2 = observedClientHeight ?? anchor.clientHeight;
39420
+ const scrollHeight2 = observedScrollHeight === void 0 ? anchor.scrollHeight : Math.max(clientHeight2, observedScrollHeight);
39421
+ const atBottom2 = virtualScrollController.isAtEnd();
39422
+ if (atBottom2) {
39423
+ bottomLockOwnerRef.current = activeConversationId;
39424
+ }
39425
+ timelineScrollAnchorRef.current = {
39426
+ ...anchor,
39427
+ clientHeight: clientHeight2,
39428
+ scrollHeight: scrollHeight2,
39429
+ scrollTop: scrollTop2
39430
+ };
39431
+ setIsTimelineScrolledToTop(
39432
+ scrollTop2 <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
39433
+ );
39434
+ setIsTimelineScrolledToBottom(
39435
+ atBottom2 || bottomLockOwnerRef.current === activeConversationId
39436
+ );
39437
+ loadOlderMessagesNearTop(scrollTop2, scrollHeight2, clientHeight2);
39438
+ return;
39439
+ }
39488
39440
  const geometry = readTimelineGeometry(timeline);
39489
39441
  const { clientHeight, maxScrollTop, scrollHeight } = geometry;
39490
39442
  const bottomLocked = bottomLockOwnerRef.current === activeConversationId;
@@ -39582,6 +39534,25 @@ function useAgentGUIDetailScroll(input) {
39582
39534
  if (activeConversationId !== viewModel.rail.activeConversationId) {
39583
39535
  return;
39584
39536
  }
39537
+ if (hasStaleVirtualScrollController(
39538
+ virtualScrollControllerRef,
39539
+ activeConversationId
39540
+ )) {
39541
+ return;
39542
+ }
39543
+ const virtualScrollController = matchingVirtualScrollController(
39544
+ virtualScrollControllerRef,
39545
+ activeConversationId
39546
+ );
39547
+ if (virtualScrollController) {
39548
+ bottomLockOwnerRef.current = activeConversationId;
39549
+ userScrollAwayIntentConversationRef.current = null;
39550
+ virtualScrollController.scrollToEnd({
39551
+ behavior: userScrollBehavior()
39552
+ });
39553
+ setIsTimelineScrolledToBottom(true);
39554
+ return;
39555
+ }
39585
39556
  const geometry = readTimelineGeometry(timeline);
39586
39557
  const maxScrollTop = geometry.maxScrollTop;
39587
39558
  bottomLockOwnerRef.current = activeConversationId;
@@ -39597,7 +39568,11 @@ function useAgentGUIDetailScroll(input) {
39597
39568
  maxScrollTop <= AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX
39598
39569
  );
39599
39570
  setIsTimelineScrolledToBottom(true);
39600
- }, [timelineConversationId, viewModel.rail.activeConversationId]);
39571
+ }, [
39572
+ timelineConversationId,
39573
+ viewModel.rail.activeConversationId,
39574
+ virtualScrollControllerRef
39575
+ ]);
39601
39576
  return {
39602
39577
  isTimelineScrolledToBottom,
39603
39578
  isTimelineScrolledToTop,
@@ -39626,36 +39601,37 @@ function UnavailableChatIcon(props) {
39626
39601
  }
39627
39602
 
39628
39603
  // agent-gui/agentGuiNode/view/useAgentGUITimelineTransition.ts
39629
- import { useLayoutEffect as useLayoutEffect8, useState as useState48 } from "react";
39604
+ import { useLayoutEffect as useLayoutEffect8, useRef as useRef54, useState as useState48 } from "react";
39630
39605
  var AGENT_GUI_TIMELINE_SKELETON_DELAY_MS = 300;
39631
39606
  function useAgentGUITimelineTransition(input) {
39632
39607
  const activeConversationId = input.activeConversationId;
39633
- const [committedTimeline, setCommittedTimeline] = useState48(() => ({
39608
+ const committedTimelineRef = useRef54({
39634
39609
  conversation: input.conversation,
39635
39610
  conversationId: activeConversationId
39636
- }));
39611
+ });
39637
39612
  const [revealedSkeletonConversationId, setRevealedSkeletonConversationId] = useState48(null);
39613
+ const revealedSkeletonConversationIdRef = useRef54(null);
39638
39614
  const transitionPending = activeConversationId !== null && input.availability === "loading" && (!input.conversation || input.conversation.rows.length === 0);
39639
39615
  useLayoutEffect8(() => {
39640
39616
  if (!transitionPending || activeConversationId === null) {
39641
- setCommittedTimeline(
39642
- (current) => current?.conversation === input.conversation && current.conversationId === activeConversationId ? current : {
39643
- conversation: input.conversation,
39644
- conversationId: activeConversationId
39645
- }
39646
- );
39647
- setRevealedSkeletonConversationId(
39648
- (current) => current === null ? current : null
39649
- );
39617
+ committedTimelineRef.current = {
39618
+ conversation: input.conversation,
39619
+ conversationId: activeConversationId
39620
+ };
39621
+ if (revealedSkeletonConversationIdRef.current !== null) {
39622
+ revealedSkeletonConversationIdRef.current = null;
39623
+ setRevealedSkeletonConversationId(null);
39624
+ }
39650
39625
  return;
39651
39626
  }
39652
39627
  const timeoutId = window.setTimeout(() => {
39628
+ revealedSkeletonConversationIdRef.current = activeConversationId;
39653
39629
  setRevealedSkeletonConversationId(activeConversationId);
39654
39630
  }, AGENT_GUI_TIMELINE_SKELETON_DELAY_MS);
39655
39631
  return () => window.clearTimeout(timeoutId);
39656
39632
  }, [activeConversationId, input.conversation, transitionPending]);
39657
39633
  const showTimelineSkeleton = transitionPending && revealedSkeletonConversationId === activeConversationId;
39658
- const retainedTimeline = transitionPending ? committedTimeline : null;
39634
+ const retainedTimeline = transitionPending ? committedTimelineRef.current : null;
39659
39635
  const retainsPreviousTimeline = !showTimelineSkeleton && retainedTimeline?.conversation !== null && retainedTimeline?.conversation !== void 0;
39660
39636
  return {
39661
39637
  conversation: transitionPending ? retainedTimeline?.conversation ?? null : input.conversation,
@@ -40595,12 +40571,13 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
40595
40571
  readiness,
40596
40572
  operations
40597
40573
  };
40598
- const timelineRef = useRef54(null);
40599
- const timelineContentRef = useRef54(null);
40600
- const bottomDockRef = useRef54(null);
40601
- const timelineScrollAnchorRef = useRef54(null);
40602
- const submittedPromptScrollConversationRef = useRef54(null);
40603
- const pendingPrependScrollAnchorRef = useRef54(null);
40574
+ const timelineRef = useRef55(null);
40575
+ const timelineContentRef = useRef55(null);
40576
+ const virtualScrollControllerRef = useRef55(null);
40577
+ const bottomDockRef = useRef55(null);
40578
+ const timelineScrollAnchorRef = useRef55(null);
40579
+ const submittedPromptScrollConversationRef = useRef55(null);
40580
+ const pendingPrependScrollAnchorRef = useRef55(null);
40604
40581
  const [
40605
40582
  bottomDockDismissedPromptRequestId,
40606
40583
  setBottomDockDismissedPromptRequestId
@@ -41029,6 +41006,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
41029
41006
  timelineContentRef,
41030
41007
  timelineRef,
41031
41008
  timelineScrollAnchorRef,
41009
+ virtualScrollControllerRef,
41032
41010
  viewModel
41033
41011
  });
41034
41012
  const homeContent = !hasActiveConversation ? shouldRenderProviderUnavailableState && disabledProviderTarget ? /* @__PURE__ */ jsx82(Fragment26, { children: renderProviderUnavailableState?.({
@@ -41044,6 +41022,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
41044
41022
  }) }) : /* @__PURE__ */ jsx82(
41045
41023
  AgentGUIEmptyHomePane,
41046
41024
  {
41025
+ isActive,
41047
41026
  isVisible,
41048
41027
  provider: emptyHeroProvider,
41049
41028
  providerReadinessGate: emptyProviderReadinessGate,
@@ -41099,6 +41078,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
41099
41078
  showUnavailableChatEmpty,
41100
41079
  timelineContentRef,
41101
41080
  timelineRef,
41081
+ virtualScrollControllerRef,
41102
41082
  workspaceAppIcons
41103
41083
  }
41104
41084
  ),
@@ -41139,7 +41119,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
41139
41119
  });
41140
41120
 
41141
41121
  // agent-gui/agentGuiNode/view/AgentGUIRenameConversationDialog.tsx
41142
- import { memo as memo13, useCallback as useCallback61, useEffect as useEffect35, useRef as useRef55, useState as useState51 } from "react";
41122
+ import { memo as memo13, useCallback as useCallback61, useEffect as useEffect35, useRef as useRef56, useState as useState51 } from "react";
41143
41123
  import { ConfirmationDialog as ConfirmationDialog4, Input as Input4 } from "@tutti-os/ui-system";
41144
41124
  import { jsx as jsx83, jsxs as jsxs59 } from "react/jsx-runtime";
41145
41125
  var AgentGUIRenameConversationDialog = memo13(
@@ -41153,9 +41133,9 @@ var AgentGUIRenameConversationDialog = memo13(
41153
41133
  "use memo";
41154
41134
  const [title, setTitle] = useState51("");
41155
41135
  const [isSaving, setIsSaving] = useState51(false);
41156
- const isSavingRef = useRef55(false);
41157
- const armedPointerActionRef = useRef55(null);
41158
- const inputRef = useRef55(null);
41136
+ const isSavingRef = useRef56(false);
41137
+ const armedPointerActionRef = useRef56(null);
41138
+ const inputRef = useRef56(null);
41159
41139
  const trimmedTitle = title.trim();
41160
41140
  useEffect35(() => {
41161
41141
  if (!open || !conversation) {
@@ -41440,7 +41420,7 @@ function AgentTargetSetupRoot({
41440
41420
  }
41441
41421
 
41442
41422
  // agent-gui/agentGuiNode/view/useAgentGUIWorkspaceReferencePicker.ts
41443
- import { useCallback as useCallback63, useMemo as useMemo46, useRef as useRef56, useState as useState52 } from "react";
41423
+ import { useCallback as useCallback63, useMemo as useMemo46, useRef as useRef57, useState as useState52 } from "react";
41444
41424
  import { createRichTextMentionHref } from "@tutti-os/ui-rich-text/core";
41445
41425
  function useAgentGUIWorkspaceReferencePicker(input) {
41446
41426
  const {
@@ -41456,8 +41436,8 @@ function useAgentGUIWorkspaceReferencePicker(input) {
41456
41436
  const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState52(false);
41457
41437
  const [workspaceReferencePickerPurpose, setWorkspaceReferencePickerPurpose] = useState52("reference");
41458
41438
  const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState52(null);
41459
- const workspaceReferencePickerResolverRef = useRef56(null);
41460
- const projectDirectoryPickerResolverRef = useRef56(null);
41439
+ const workspaceReferencePickerResolverRef = useRef57(null);
41440
+ const projectDirectoryPickerResolverRef = useRef57(null);
41461
41441
  const emptyReferencePickResult = useMemo46(
41462
41442
  () => ({ files: [], mentionItems: [] }),
41463
41443
  []
@@ -41609,7 +41589,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
41609
41589
  }
41610
41590
 
41611
41591
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
41612
- import { useRef as useRef58 } from "react";
41592
+ import { useRef as useRef59 } from "react";
41613
41593
 
41614
41594
  // agent-gui/agentGuiNode/engagement/projectAgentGUIEngagementContext.ts
41615
41595
  function projectAgentGUIEngagementContext(viewModel, composerReady) {
@@ -41641,7 +41621,7 @@ function createAgentGUIEngagementContextKey(input) {
41641
41621
  }
41642
41622
 
41643
41623
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
41644
- import { useEffect as useEffect36, useRef as useRef57 } from "react";
41624
+ import { useEffect as useEffect36, useRef as useRef58 } from "react";
41645
41625
 
41646
41626
  // agent-gui/agentGuiNode/engagement/AgentGUIPanelEngagementController.ts
41647
41627
  var AGENT_GUI_PANEL_EXPOSURE_DWELL_MS = 1e3;
@@ -41795,10 +41775,10 @@ function documentIsVisible() {
41795
41775
 
41796
41776
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
41797
41777
  function useAgentGUIPanelEngagement(input) {
41798
- const inputRef = useRef57(input);
41799
- const controllerRef = useRef57(null);
41800
- const intersectionRatioRef = useRef57(0);
41801
- const engagementRef = useRef57(null);
41778
+ const inputRef = useRef58(input);
41779
+ const controllerRef = useRef58(null);
41780
+ const intersectionRatioRef = useRef58(0);
41781
+ const engagementRef = useRef58(null);
41802
41782
  inputRef.current = input;
41803
41783
  if (!engagementRef.current) {
41804
41784
  engagementRef.current = {
@@ -41838,7 +41818,7 @@ function useAgentGUIPanelEngagement(input) {
41838
41818
 
41839
41819
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
41840
41820
  function useAgentGUINodeEngagement(input) {
41841
- const layoutElementRef = useRef58(null);
41821
+ const layoutElementRef = useRef59(null);
41842
41822
  const projected = projectAgentGUIEngagementContext(
41843
41823
  input.viewModel,
41844
41824
  input.composerReady
@@ -41899,7 +41879,7 @@ function useAgentGUIConversationRailResizePointerMove({
41899
41879
  }
41900
41880
 
41901
41881
  // agent-gui/agentGuiNode/view/useAgentGUIExternalRequests.ts
41902
- import { useCallback as useCallback65, useEffect as useEffect37, useRef as useRef59 } from "react";
41882
+ import { useCallback as useCallback65, useEffect as useEffect37, useRef as useRef60 } from "react";
41903
41883
  function resolveSessionActionConversation(viewModel, agentSessionId) {
41904
41884
  const active = viewModel.rail.activeConversation;
41905
41885
  if (!agentSessionId) {
@@ -41924,17 +41904,17 @@ function useAgentGUIExternalRequests(input) {
41924
41904
  viewModel
41925
41905
  } = input;
41926
41906
  const agentHostApi = useOptionalAgentHostApi();
41927
- const railInteractionLockProbeRef = useRef59(null);
41907
+ const railInteractionLockProbeRef = useRef60(null);
41928
41908
  const registerRailInteractionLockProbe = useCallback65(
41929
41909
  (probe) => {
41930
41910
  railInteractionLockProbeRef.current = probe;
41931
41911
  },
41932
41912
  []
41933
41913
  );
41934
- const handledNewConversationRequestSequenceRef = useRef59(
41914
+ const handledNewConversationRequestSequenceRef = useRef60(
41935
41915
  newConversationRequestSequence
41936
41916
  );
41937
- const handledSessionActionRequestSequenceRef = useRef59(
41917
+ const handledSessionActionRequestSequenceRef = useRef60(
41938
41918
  sessionActionRequest?.sequence ?? null
41939
41919
  );
41940
41920
  const copyConversationValue = useAgentGUIConversationCopyAction(labels);
@@ -42011,6 +41991,7 @@ function AgentGUINodeView({
42011
41991
  slashStatusUsageCapturedAtUnixMs = null,
42012
41992
  slashStatusUsageDidFail = false,
42013
41993
  slashStatusUsageAttempted = false,
41994
+ agentConfigAccountContent,
42014
41995
  onAgentConfigMenuClose,
42015
41996
  onAgentConfigMenuOpen,
42016
41997
  onAgentUsageRefresh,
@@ -42061,7 +42042,7 @@ function AgentGUINodeView({
42061
42042
  viewModel
42062
42043
  });
42063
42044
  const [providerManagerOpen, setProviderManagerOpen] = useState53(false);
42064
- const railResizeInteractionRef = useRef60(null);
42045
+ const railResizeInteractionRef = useRef61(null);
42065
42046
  const [isRailResizing, setIsRailResizing] = useState53(false);
42066
42047
  const [railResizeWidthPx, setRailResizeWidthPx] = useState53(
42067
42048
  null
@@ -42458,6 +42439,7 @@ function AgentGUINodeView({
42458
42439
  slashStatusUsageAttempted,
42459
42440
  provider: effectiveRailConfigProvider,
42460
42441
  providerAuthAccountLabel: effectiveProviderAuthAccountLabel,
42442
+ accountContent: agentConfigAccountContent,
42461
42443
  onAgentConfigMenuClose,
42462
42444
  onAgentConfigMenuOpen,
42463
42445
  onAgentUsageRefresh,
@@ -42610,7 +42592,7 @@ import {
42610
42592
  useCallback as useCallback67,
42611
42593
  useEffect as useEffect39,
42612
42594
  useLayoutEffect as useLayoutEffect9,
42613
- useRef as useRef61,
42595
+ useRef as useRef62,
42614
42596
  useState as useState54
42615
42597
  } from "react";
42616
42598
  import { createPortal as createPortal5 } from "react-dom";
@@ -42649,8 +42631,8 @@ function AgentProbeInfoPopover({
42649
42631
  onClose
42650
42632
  }) {
42651
42633
  "use memo";
42652
- const anchorRef = useRef61(null);
42653
- const popoverRef = useRef61(null);
42634
+ const anchorRef = useRef62(null);
42635
+ const popoverRef = useRef62(null);
42654
42636
  const [isOpen, setIsOpen] = useState54(false);
42655
42637
  const [popoverStyle, setPopoverStyle] = useState54(null);
42656
42638
  const openPopover = useCallback67(() => {
@@ -42839,7 +42821,7 @@ function areAgentGUINodePropsEqual(previous, next) {
42839
42821
  const pc = previous.hostCapabilities, nc = next.hostCapabilities;
42840
42822
  const pa = previous.hostActions, na = next.hostActions;
42841
42823
  const ps = previous.renderSlots, ns = next.renderSlots;
42842
- return pi.nodeId === ni.nodeId && pi.workspaceId === ni.workspaceId && pi.currentUserId === ni.currentUserId && pi.title === ni.title && pw.path === nw.path && pw.fileReferenceAdapter === nw.fileReferenceAdapter && pw.onRequestGitBranches === nw.onRequestGitBranches && pw.selectProjectDirectory === nw.selectProjectDirectory && pw.resolveExternalPromptEntries === nw.resolveExternalPromptEntries && pw.prepareExternalPromptFiles === nw.prepareExternalPromptFiles && pw.promptAssetLimit === nw.promptAssetLimit && pw.projectDirectorySourceAggregator === nw.projectDirectorySourceAggregator && pw.referenceSourceAggregator === nw.referenceSourceAggregator && pw.resolveReferenceContentErrorAction === nw.resolveReferenceContentErrorAction && pw.resolveReferenceEntryIconUrl === nw.resolveReferenceEntryIconUrl && pw.resolveMentionReferenceTarget === nw.resolveMentionReferenceTarget && pw.resolveReferenceInitialTarget === nw.resolveReferenceInitialTarget && pw.onFileReferencesAdded === nw.onFileReferencesAdded && pw.agentSettings.avoidGroupingEdits === nw.agentSettings.avoidGroupingEdits && pc.referenceProvenanceFilterCatalog === nc.referenceProvenanceFilterCatalog && pc.referenceProvenanceFilterEnabled === nc.referenceProvenanceFilterEnabled && agentGuiStateEquals(previous.state, next.state) && pf.position.x === nf.position.x && pf.position.y === nf.position.y && pf.width === nf.width && pf.height === nf.height && pf.desktopSize.width === nf.desktopSize.width && pf.desktopSize.height === nf.desktopSize.height && pf.isMaximized === nf.isMaximized && pf.isActive === nf.isActive && pf.isVisible === nf.isVisible && pf.embedded === nf.embedded && pf.conversationRailAutoCollapseMode === nf.conversationRailAutoCollapseMode && pr.composerFocusSequence === nr.composerFocusSequence && pr.composerAppend === nr.composerAppend && pr.newConversationSequence === nr.newConversationSequence && pr.sessionAction === nr.sessionAction && pr.openSession === nr.openSession && pr.prefillPrompt === nr.prefillPrompt && pr.agentStatusController === nr.agentStatusController && pc.capabilityMenuState === nc.capabilityMenuState && pc.capabilityControlsReadOnly === nc.capabilityControlsReadOnly && pc.agentTargets === nc.agentTargets && pc.agentTargetsLoading === nc.agentTargetsLoading && pc.handoffAgentTargets === nc.handoffAgentTargets && pc.handoffAgentTargetsLoading === nc.handoffAgentTargetsLoading && pc.providerRailAllPresentation?.iconUrl === nc.providerRailAllPresentation?.iconUrl && pc.providerRailMode === nc.providerRailMode && pc.comingSoonProviders === nc.comingSoonProviders && pc.providerReadinessGates === nc.providerReadinessGates && pc.targetConnectionSource === nc.targetConnectionSource && pc.defaultAgentTargetId === nc.defaultAgentTargetId && pc.providerAuthAccountLabels === nc.providerAuthAccountLabels && pc.mentionService === nc.mentionService && pc.workspaceAppIcons === nc.workspaceAppIcons && pc.disabledHomeSuggestions === nc.disabledHomeSuggestions && pa.onLinkAction === na.onLinkAction && pa.onHandoffConversation === na.onHandoffConversation && pa.onCapabilitySettingsRequest === na.onCapabilitySettingsRequest && pa.onAgentProviderLogin === na.onAgentProviderLogin && pa.onAgentEnvPanelOpen === na.onAgentEnvPanelOpen && pa.onOpenConversationWindow === na.onOpenConversationWindow && pa.onClose === na.onClose && pa.onResize === na.onResize && pa.onUpdateNode === na.onUpdateNode && pa.onRememberComposerDefaults === na.onRememberComposerDefaults && pa.isMuted === na.isMuted && pa.onMinimize === na.onMinimize && pa.onToggleMaximize === na.onToggleMaximize && pa.onShowMessage === na.onShowMessage && pa.onEngagementEvent === na.onEngagementEvent && pa.onConversationRailLayoutChange === na.onConversationRailLayoutChange && ps.providerRailEmpty === ns.providerRailEmpty && ps.providerUnavailableState === ns.providerUnavailableState && ps.projectDirectoryPickerHeaderActions === ns.projectDirectoryPickerHeaderActions && ps.sidebarFooter === ns.sidebarFooter;
42824
+ return pi.nodeId === ni.nodeId && pi.workspaceId === ni.workspaceId && pi.currentUserId === ni.currentUserId && pi.title === ni.title && pw.path === nw.path && pw.fileReferenceAdapter === nw.fileReferenceAdapter && pw.onRequestGitBranches === nw.onRequestGitBranches && pw.selectProjectDirectory === nw.selectProjectDirectory && pw.resolveExternalPromptEntries === nw.resolveExternalPromptEntries && pw.prepareExternalPromptFiles === nw.prepareExternalPromptFiles && pw.promptAssetLimit === nw.promptAssetLimit && pw.projectDirectorySourceAggregator === nw.projectDirectorySourceAggregator && pw.referenceSourceAggregator === nw.referenceSourceAggregator && pw.resolveReferenceContentErrorAction === nw.resolveReferenceContentErrorAction && pw.resolveReferenceEntryIconUrl === nw.resolveReferenceEntryIconUrl && pw.resolveMentionReferenceTarget === nw.resolveMentionReferenceTarget && pw.resolveReferenceInitialTarget === nw.resolveReferenceInitialTarget && pw.onFileReferencesAdded === nw.onFileReferencesAdded && pw.agentSettings.avoidGroupingEdits === nw.agentSettings.avoidGroupingEdits && pc.referenceProvenanceFilterCatalog === nc.referenceProvenanceFilterCatalog && pc.referenceProvenanceFilterEnabled === nc.referenceProvenanceFilterEnabled && agentGuiStateEquals(previous.state, next.state) && pf.position.x === nf.position.x && pf.position.y === nf.position.y && pf.width === nf.width && pf.height === nf.height && pf.desktopSize.width === nf.desktopSize.width && pf.desktopSize.height === nf.desktopSize.height && pf.isMaximized === nf.isMaximized && pf.isActive === nf.isActive && pf.isVisible === nf.isVisible && pf.embedded === nf.embedded && pf.conversationRailAutoCollapseMode === nf.conversationRailAutoCollapseMode && pr.composerFocusSequence === nr.composerFocusSequence && pr.composerAppend === nr.composerAppend && pr.newConversationSequence === nr.newConversationSequence && pr.sessionAction === nr.sessionAction && pr.openSession === nr.openSession && pr.prefillPrompt === nr.prefillPrompt && pr.agentStatusController === nr.agentStatusController && pc.capabilityMenuState === nc.capabilityMenuState && pc.capabilityControlsReadOnly === nc.capabilityControlsReadOnly && pc.agentTargets === nc.agentTargets && pc.agentTargetsLoading === nc.agentTargetsLoading && pc.handoffAgentTargets === nc.handoffAgentTargets && pc.handoffAgentTargetsLoading === nc.handoffAgentTargetsLoading && pc.providerRailAllPresentation?.iconUrl === nc.providerRailAllPresentation?.iconUrl && pc.providerRailMode === nc.providerRailMode && pc.comingSoonProviders === nc.comingSoonProviders && pc.providerReadinessGates === nc.providerReadinessGates && pc.targetConnectionSource === nc.targetConnectionSource && pc.defaultAgentTargetId === nc.defaultAgentTargetId && pc.providerAuthAccountLabels === nc.providerAuthAccountLabels && pc.mentionService === nc.mentionService && pc.workspaceAppIcons === nc.workspaceAppIcons && pc.disabledHomeSuggestions === nc.disabledHomeSuggestions && pa.onLinkAction === na.onLinkAction && pa.onHandoffConversation === na.onHandoffConversation && pa.onCapabilitySettingsRequest === na.onCapabilitySettingsRequest && pa.onAgentProviderLogin === na.onAgentProviderLogin && pa.onAgentEnvPanelOpen === na.onAgentEnvPanelOpen && pa.onAgentConfigMenuOpen === na.onAgentConfigMenuOpen && pa.onOpenConversationWindow === na.onOpenConversationWindow && pa.onClose === na.onClose && pa.onResize === na.onResize && pa.onUpdateNode === na.onUpdateNode && pa.onRememberComposerDefaults === na.onRememberComposerDefaults && pa.isMuted === na.isMuted && pa.onMinimize === na.onMinimize && pa.onToggleMaximize === na.onToggleMaximize && pa.onShowMessage === na.onShowMessage && pa.onEngagementEvent === na.onEngagementEvent && pa.onConversationRailLayoutChange === na.onConversationRailLayoutChange && ps.agentConfigAccount === ns.agentConfigAccount && ps.providerRailEmpty === ns.providerRailEmpty && ps.providerUnavailableState === ns.providerUnavailableState && ps.projectDirectoryPickerHeaderActions === ns.projectDirectoryPickerHeaderActions && ps.sidebarFooter === ns.sidebarFooter;
42843
42825
  }
42844
42826
 
42845
42827
  // agent-gui/agentGuiNode/AgentGUIMentionServiceBoundary.tsx
@@ -44140,7 +44122,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
44140
44122
  isVisible = true,
44141
44123
  embedded = false
44142
44124
  } = frame;
44143
- const widthRef = useRef62(width);
44125
+ const widthRef = useRef63(width);
44144
44126
  widthRef.current = width;
44145
44127
  const {
44146
44128
  composerAppend: composerAppendRequest = null,
@@ -44182,6 +44164,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
44182
44164
  onCapabilitySettingsRequest,
44183
44165
  onAgentProviderLogin,
44184
44166
  onAgentEnvPanelOpen,
44167
+ onAgentConfigMenuOpen: onHostAgentConfigMenuOpen,
44185
44168
  onOpenConversationWindow,
44186
44169
  onClose,
44187
44170
  onResize,
@@ -44195,6 +44178,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
44195
44178
  onConversationRailLayoutChange
44196
44179
  } = hostActions;
44197
44180
  const {
44181
+ agentConfigAccount: renderAgentConfigAccount,
44198
44182
  projectDirectoryPickerHeaderActions: renderProjectDirectoryPickerHeaderActions,
44199
44183
  providerRailEmpty: renderProviderRailEmpty,
44200
44184
  providerUnavailableState: renderProviderUnavailableState,
@@ -44376,7 +44360,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
44376
44360
  agentProbeLines,
44377
44361
  controllerRailStatus,
44378
44362
  handleAgentConfigMenuClose,
44379
- handleAgentConfigMenuOpen,
44363
+ handleAgentConfigMenuOpen: handleStatusAgentConfigMenuOpen,
44380
44364
  handleAgentProbeInfoClose,
44381
44365
  handleAgentProbeInfoOpen,
44382
44366
  handleAgentUsageRefresh,
@@ -44393,6 +44377,14 @@ var AgentGUINode = memo14(function AgentGUINode2({
44393
44377
  t,
44394
44378
  viewModel
44395
44379
  });
44380
+ const agentConfigMenuContext = viewModel.rail.conversationFilter.kind === "all" ? null : resolveAgentConfigMenuContext(viewModel.rail.selectedAgentTarget);
44381
+ const handleAgentConfigMenuOpen = () => {
44382
+ handleStatusAgentConfigMenuOpen();
44383
+ if (agentConfigMenuContext) {
44384
+ onHostAgentConfigMenuOpen?.(agentConfigMenuContext);
44385
+ }
44386
+ };
44387
+ const agentConfigAccountContent = agentConfigMenuContext ? renderAgentConfigAccount?.(agentConfigMenuContext) ?? null : null;
44396
44388
  return /* @__PURE__ */ jsx89(AgentGUIMentionServiceBoundary, { service: mentionService, children: /* @__PURE__ */ jsx89(
44397
44389
  WorkspaceNodeWindow,
44398
44390
  {
@@ -44483,6 +44475,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
44483
44475
  slashStatusUsageDidFail: controllerRailStatus?.didFail ?? false,
44484
44476
  slashStatusUsageAttempted: controllerRailStatus?.attempted ?? false,
44485
44477
  slashStatusLimitsResolvedEmpty: controllerRailStatus?.resolvedEmpty ?? false,
44478
+ agentConfigAccountContent,
44486
44479
  providerAuthAccountLabels,
44487
44480
  onAgentConfigMenuClose: handleAgentConfigMenuClose,
44488
44481
  onAgentConfigMenuOpen: handleAgentConfigMenuOpen,
@@ -44538,6 +44531,19 @@ var AgentGUINode = memo14(function AgentGUINode2({
44538
44531
  }
44539
44532
  ) });
44540
44533
  }, areAgentGUINodePropsEqual);
44534
+ function resolveAgentConfigMenuContext(target) {
44535
+ const agentTargetId = target.agentTargetId?.trim() || target.targetId.trim();
44536
+ const provider = target.provider.trim();
44537
+ if (!agentTargetId || !provider) {
44538
+ return null;
44539
+ }
44540
+ return {
44541
+ agentTargetId,
44542
+ provider,
44543
+ label: target.label,
44544
+ ...target.ownership ? { ownership: target.ownership } : {}
44545
+ };
44546
+ }
44541
44547
 
44542
44548
  // AgentGUI.tsx
44543
44549
  import { jsx as jsx90 } from "react/jsx-runtime";
@@ -44642,4 +44648,4 @@ export {
44642
44648
  AgentHandoffMenu,
44643
44649
  AgentGUI
44644
44650
  };
44645
- //# sourceMappingURL=chunk-EDP4D42H.js.map
44651
+ //# sourceMappingURL=chunk-45KN5Z5F.js.map