@tutti-os/agent-gui 0.0.88 → 0.0.90

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.
package/dist/index.js CHANGED
@@ -10,10 +10,11 @@ import {
10
10
  projectAgentGUIAgentsToInternalTargets,
11
11
  resolveAgentGUIConversationRailMaxWidthPx,
12
12
  resolveAgentGUIExpandedWindowFrame,
13
+ resolveAgentGUISelectedDirectoryAgent,
13
14
  resolveAgentGuiSessionProviderFlatIconUrl,
14
15
  resolveNextAgentGUIConversationRailWidthPx,
15
16
  shouldAutoCollapseAgentGUIConversationRail
16
- } from "./chunk-A7RA7ORT.js";
17
+ } from "./chunk-P7RX2NSY.js";
17
18
  import "./chunk-45FF4DQU.js";
18
19
  import "./chunk-7LMJXF4R.js";
19
20
  import "./chunk-GAPTLVII.js";
@@ -79,7 +80,7 @@ import {
79
80
  textPromptContent,
80
81
  toLocalShortDateTime,
81
82
  useProjectedAgentConversation
82
- } from "./chunk-DC3HCHA3.js";
83
+ } from "./chunk-KTXWPKGP.js";
83
84
  import {
84
85
  AgentMessageMarkdown,
85
86
  AgentTargetPresentationProvider,
@@ -7054,6 +7055,51 @@ function resolveAgentGUIDirectorySelection(input) {
7054
7055
  const providerTargets = input.provider ? input.targets.filter((target) => target.provider === input.provider) : [];
7055
7056
  return providerTargets.find((target) => target.disabled !== true) ?? providerTargets[0] ?? input.targets.find((target) => target.disabled !== true) ?? input.targets[0] ?? null;
7056
7057
  }
7058
+ function resolveAgentGUIHomeDirectorySelection(input) {
7059
+ const dataAgentTargetId = normalizeOptionalText2(input.data.agentTargetId);
7060
+ const defaultAgentTargetId = normalizeOptionalText2(
7061
+ input.defaultAgentTargetId
7062
+ );
7063
+ const explicitAgentTargetId = dataAgentTargetId ?? defaultAgentTargetId;
7064
+ const source = dataAgentTargetId ? "explicit-data" : defaultAgentTargetId ? "explicit-default" : "implicit";
7065
+ if (explicitAgentTargetId) {
7066
+ const exact = findAgentGUIDirectoryTarget(
7067
+ input.directory,
7068
+ explicitAgentTargetId
7069
+ );
7070
+ if (exact) {
7071
+ return { source, status: "resolved", target: exact };
7072
+ }
7073
+ return {
7074
+ source,
7075
+ status: input.directoryLoading ? "loading" : "missing",
7076
+ target: {
7077
+ targetId: explicitAgentTargetId,
7078
+ agentTargetId: explicitAgentTargetId,
7079
+ provider: input.data.provider,
7080
+ ref: {
7081
+ kind: input.directoryLoading ? "loading" : "missing-agent",
7082
+ provider: input.data.provider,
7083
+ agentTargetId: explicitAgentTargetId
7084
+ },
7085
+ label: input.data.provider,
7086
+ disabled: true
7087
+ }
7088
+ };
7089
+ }
7090
+ const fallback = input.directory.find((target) => target.disabled !== true) ?? input.directory[0];
7091
+ return {
7092
+ source,
7093
+ status: input.directoryLoading ? "loading" : "resolved",
7094
+ target: fallback ?? {
7095
+ targetId: "__loading__",
7096
+ provider: input.data.provider,
7097
+ ref: { kind: "loading", provider: input.data.provider },
7098
+ label: input.data.provider,
7099
+ disabled: true
7100
+ }
7101
+ };
7102
+ }
7057
7103
  function composerTargetDataFromNodeData(data, directory) {
7058
7104
  const foreignKeyAgentTargetId = normalizeOptionalText2(data.agentTargetId);
7059
7105
  const directoryTarget = findAgentGUIDirectoryTarget(
@@ -7230,17 +7276,24 @@ function reportAgentGUIRenderStateDiagnostic(input) {
7230
7276
  activeHasPendingSubmittedTurn: input.activeHasPendingSubmittedTurn,
7231
7277
  activeLiveState: input.activeLiveState,
7232
7278
  activeSubmitBlocked: input.activeSubmitBlocked,
7279
+ activeConversationResumeUnavailable: input.activeConversationResumeUnavailable,
7233
7280
  canQueueWhileBusy: input.canQueueWhileBusy,
7234
7281
  canSubmit: input.canSubmit,
7235
7282
  conversation: agentGUIConversationDiagnosticDetails(input.conversation),
7236
7283
  isCreatingConversation: input.isCreatingConversation,
7284
+ isInterrupting: input.isInterrupting,
7237
7285
  isLoadingMessages: input.isLoadingMessages,
7238
7286
  isSubmitting: input.isSubmitting,
7287
+ providerTargetsLoading: input.providerTargetsLoading,
7239
7288
  pendingApprovalRequestId: input.pendingApproval?.requestId ?? null,
7240
7289
  pendingInteractivePromptKind: input.pendingInteractivePrompt?.kind ?? null,
7241
7290
  pendingInteractivePromptRequestId: promptRequestId(
7242
7291
  input.pendingInteractivePrompt
7243
7292
  ),
7293
+ selectedProviderTargetDisabled: input.selectedProviderTargetDisabled,
7294
+ selectedProviderTargetId: input.selectedProviderTargetId,
7295
+ selectedProviderTargetIsExplicit: input.selectedProviderTargetIsExplicit,
7296
+ sessionAuthBlocked: input.sessionAuthBlocked,
7244
7297
  runtimeSession: agentGUIRuntimeSessionDiagnosticDetails(
7245
7298
  input.activeRuntimeSession
7246
7299
  ),
@@ -7480,7 +7533,7 @@ function toRuntimeSendContent(content) {
7480
7533
  line: (preview, path) => translate("agentHost.agentGui.pastedTextFileLine", { preview, path })
7481
7534
  });
7482
7535
  }
7483
- function shouldClearSubmittedDraft(input) {
7536
+ function promptSubmissionMatchesCurrentDraft(input) {
7484
7537
  const currentDraft = input.currentDraft;
7485
7538
  if (!currentDraft) {
7486
7539
  return false;
@@ -7506,9 +7559,11 @@ function shouldClearSubmittedDraft(input) {
7506
7559
  const submittedPath = submittedImage.path?.trim() ?? "";
7507
7560
  const draftData = image.data?.trim() ?? "";
7508
7561
  const submittedData = submittedImage.data?.trim() ?? "";
7562
+ const draftUrl = image.url?.trim() ?? "";
7563
+ const submittedUrl = submittedImage.url?.trim() ?? "";
7509
7564
  const draftName = image.name.trim();
7510
7565
  const submittedName = submittedImage.name?.trim() ?? "";
7511
- return draftPath === submittedPath && draftData === submittedData && draftName === submittedName;
7566
+ return draftPath === submittedPath && draftData === submittedData && draftUrl === submittedUrl && draftName === submittedName;
7512
7567
  });
7513
7568
  if (!imagesMatch) {
7514
7569
  return false;
@@ -8809,7 +8864,7 @@ function areAgentComposerDraftsEqual(left, right) {
8809
8864
  if (!other) {
8810
8865
  return false;
8811
8866
  }
8812
- return image.id === other.id && image.name === other.name && image.mimeType === other.mimeType && image.data === other.data && image.path === other.path && image.previewUrl === other.previewUrl && image.uploading === other.uploading && image.uploadError === other.uploadError;
8867
+ return image.id === other.id && image.name === other.name && image.mimeType === other.mimeType && image.data === other.data && image.url === other.url && image.path === other.path && image.previewUrl === other.previewUrl && image.uploading === other.uploading && image.uploadError === other.uploadError;
8813
8868
  }) && leftFiles.length === rightFiles.length && leftFiles.every((file, index) => {
8814
8869
  const other = rightFiles[index];
8815
8870
  if (!other) {
@@ -9202,27 +9257,20 @@ function useAgentGUINodeController({
9202
9257
  ),
9203
9258
  [normalizedExplicitProviderTargets, providerTargetsLoading]
9204
9259
  );
9205
- const selectedProviderTarget = useMemo3(() => {
9206
- const selectedAgentTargetId = normalizeOptionalText2(data.agentTargetId) ?? normalizeOptionalText2(defaultAgentTargetId);
9207
- const resolved = normalizedProviderTargets.find(
9208
- (target) => target.agentTargetId === selectedAgentTargetId
9209
- ) ?? normalizedProviderTargets.find((target) => target.disabled !== true) ?? normalizedProviderTargets[0];
9210
- return resolved ?? {
9211
- targetId: data.agentTargetId ?? "__loading__",
9212
- provider: data.provider,
9213
- ref: {
9214
- kind: "loading",
9215
- provider: data.provider
9216
- },
9217
- label: data.provider,
9218
- disabled: true
9219
- };
9260
+ const homeDirectorySelection = useMemo3(() => {
9261
+ return resolveAgentGUIHomeDirectorySelection({
9262
+ data,
9263
+ defaultAgentTargetId,
9264
+ directory: normalizedProviderTargets,
9265
+ directoryLoading: providerTargetsLoading
9266
+ });
9220
9267
  }, [
9221
- data.agentTargetId,
9222
- data.provider,
9268
+ data,
9223
9269
  defaultAgentTargetId,
9224
- normalizedProviderTargets
9270
+ normalizedProviderTargets,
9271
+ providerTargetsLoading
9225
9272
  ]);
9273
+ const selectedProviderTarget = homeDirectorySelection.target;
9226
9274
  const selectedProviderTargetIsExplicit = useMemo3(
9227
9275
  () => normalizedExplicitProviderTargets.some(
9228
9276
  (target) => target.agentTargetId === selectedProviderTarget.agentTargetId
@@ -9237,6 +9285,7 @@ function useAgentGUINodeController({
9237
9285
  [homeComposerTargetOverride, normalizedExplicitProviderTargets]
9238
9286
  );
9239
9287
  const effectiveSelectedProviderTarget = homeComposerTargetOverride ?? selectedProviderTarget;
9288
+ const effectiveSelectedProviderTargetIsExplicit = homeComposerTargetOverride ? homeComposerTargetOverrideIsExplicit : selectedProviderTargetIsExplicit;
9240
9289
  const firstReadyHomeComposerProviderTarget = useMemo3(() => {
9241
9290
  if (!providerReadinessGates) {
9242
9291
  return null;
@@ -9682,9 +9731,9 @@ function useAgentGUINodeController({
9682
9731
  const selectedProviderTargetRef = useRef4(effectiveSelectedProviderTarget);
9683
9732
  selectedProviderTargetRef.current = effectiveSelectedProviderTarget;
9684
9733
  const selectedProviderTargetIsExplicitRef = useRef4(
9685
- homeComposerTargetOverride ? homeComposerTargetOverrideIsExplicit : selectedProviderTargetIsExplicit
9734
+ effectiveSelectedProviderTargetIsExplicit
9686
9735
  );
9687
- selectedProviderTargetIsExplicitRef.current = homeComposerTargetOverride ? homeComposerTargetOverrideIsExplicit : selectedProviderTargetIsExplicit;
9736
+ selectedProviderTargetIsExplicitRef.current = effectiveSelectedProviderTargetIsExplicit;
9688
9737
  const providerTargetsProvidedRef = useRef4(providerTargets !== void 0);
9689
9738
  providerTargetsProvidedRef.current = providerTargets !== void 0;
9690
9739
  const selectedComposerTargetDataRef = useRef4(selectedComposerTargetData);
@@ -13111,7 +13160,7 @@ function useAgentGUINodeController({
13111
13160
  }
13112
13161
  setDraftBySessionId((current) => {
13113
13162
  const currentDraft = current[agentSessionId];
13114
- if (!shouldClearSubmittedDraft({
13163
+ if (!promptSubmissionMatchesCurrentDraft({
13115
13164
  currentDraft,
13116
13165
  submittedContent: normalizedContent
13117
13166
  })) {
@@ -15424,7 +15473,7 @@ function useAgentGUINodeController({
15424
15473
  hasProviderSessionNotFoundError,
15425
15474
  pendingApproval
15426
15475
  ]);
15427
- const canSubmit = !providerTargetsLoading && activeLiveState !== "activating" && activeLiveState !== "failed" && !activeConversationResumeUnavailable && (activeConversationId !== null || effectiveSelectedProviderTarget.disabled !== true && (homeComposerTargetOverride ? homeComposerTargetOverrideIsExplicit : selectedProviderTargetIsExplicit)) && (composerTargetData.provider !== "openclaw" || openclawGateway?.status === "ready") && pendingApproval === null && pendingInteractivePrompt === null && sessionChrome.auth === null && !activeConversationBusy && !isCreatingConversation && !isSubmitting && !isInterrupting;
15476
+ const canSubmit = !providerTargetsLoading && activeLiveState !== "activating" && activeLiveState !== "failed" && !activeConversationResumeUnavailable && (activeConversationId !== null || effectiveSelectedProviderTarget.disabled !== true && effectiveSelectedProviderTargetIsExplicit) && (composerTargetData.provider !== "openclaw" || openclawGateway?.status === "ready") && pendingApproval === null && pendingInteractivePrompt === null && sessionChrome.auth === null && !activeConversationBusy && !isCreatingConversation && !isSubmitting && !isInterrupting;
15428
15477
  const activeConversationCreatePending = Boolean(activeConversationId) && isCreatingConversation && startingConversationIdRef.current === activeConversationId;
15429
15478
  const canQueueWhileBusy = Boolean(activeConversationId) && (activeConversationCreatePending || activeConversationBusy || isSubmitting || Boolean(activeSessionState?.pendingInteractive));
15430
15479
  useEffect4(() => {
@@ -15472,15 +15521,22 @@ function useAgentGUINodeController({
15472
15521
  activeRuntimeSession,
15473
15522
  activeSessionState,
15474
15523
  activeSubmitBlocked,
15524
+ activeConversationResumeUnavailable,
15475
15525
  canQueueWhileBusy,
15476
15526
  canSubmit,
15477
15527
  conversation,
15478
15528
  isCreatingConversation,
15529
+ isInterrupting,
15479
15530
  isLoadingMessages,
15480
15531
  isSubmitting,
15481
15532
  pendingApproval,
15482
15533
  pendingInteractivePrompt,
15534
+ providerTargetsLoading,
15483
15535
  runtime: agentActivityRuntime,
15536
+ selectedProviderTargetDisabled: effectiveSelectedProviderTarget.disabled === true,
15537
+ selectedProviderTargetId: effectiveSelectedProviderTarget.agentTargetId ?? null,
15538
+ selectedProviderTargetIsExplicit: effectiveSelectedProviderTargetIsExplicit,
15539
+ sessionAuthBlocked: sessionChrome.auth !== null,
15484
15540
  workspaceId
15485
15541
  });
15486
15542
  }, [
@@ -15493,16 +15549,22 @@ function useAgentGUINodeController({
15493
15549
  activeRuntimeSession,
15494
15550
  activeSessionState,
15495
15551
  activeSubmitBlocked,
15552
+ activeConversationResumeUnavailable,
15496
15553
  agentActivityRuntime,
15497
15554
  canQueueWhileBusy,
15498
15555
  canSubmit,
15499
15556
  conversation,
15557
+ effectiveSelectedProviderTarget.agentTargetId,
15558
+ effectiveSelectedProviderTarget.disabled,
15559
+ effectiveSelectedProviderTargetIsExplicit,
15500
15560
  isCreatingConversation,
15561
+ isInterrupting,
15501
15562
  isLoadingMessages,
15502
15563
  isSubmitting,
15503
15564
  pendingApproval,
15504
15565
  pendingInteractivePrompt,
15505
15566
  providerTargetsLoading,
15567
+ sessionChrome.auth,
15506
15568
  workspaceId
15507
15569
  ]);
15508
15570
  const activeSessionReasoningSelection = useMemo3(
@@ -15616,10 +15678,13 @@ function useAgentGUINodeController({
15616
15678
  const stableComposerSettings = useStableComposerSettingsVM(composerSettings);
15617
15679
  const resolveDefaultHomeComposerTarget = useCallback4(() => {
15618
15680
  const defaultTargetId = defaultAgentTargetId?.trim() ?? "";
15619
- const explicitDefaultTarget = defaultTargetId ? normalizedProviderTargets.find(
15620
- (target) => target.targetId === defaultTargetId || target.agentTargetId === defaultTargetId
15621
- ) ?? null : null;
15622
- return explicitDefaultTarget ?? normalizedProviderTargets.find((target) => target.disabled !== true) ?? normalizedProviderTargets[0] ?? null;
15681
+ if (defaultTargetId) {
15682
+ return findAgentGUIDirectoryTarget(
15683
+ normalizedProviderTargets,
15684
+ defaultTargetId
15685
+ ) ?? null;
15686
+ }
15687
+ return normalizedProviderTargets.find((target) => target.disabled !== true) ?? normalizedProviderTargets[0] ?? null;
15623
15688
  }, [defaultAgentTargetId, normalizedProviderTargets]);
15624
15689
  const resetHomeComposerAgentTargetToDefault = useCallback4(() => {
15625
15690
  if (previewMode) {
@@ -15787,7 +15852,7 @@ function useAgentGUINodeController({
15787
15852
  ]
15788
15853
  );
15789
15854
  useEffect4(() => {
15790
- if (previewMode || activeConversationId !== null || conversationFilter.kind !== "all" || homeComposerTargetOverride !== null || agentGUINodeDataHasComposerTarget(data) || !providerReadinessGates || !firstReadyHomeComposerProviderTarget) {
15855
+ if (previewMode || activeConversationId !== null || conversationFilter.kind !== "all" || homeComposerTargetOverride !== null || agentGUINodeDataHasComposerTarget(data) || homeDirectorySelection.source !== "implicit" || !providerReadinessGates || !firstReadyHomeComposerProviderTarget) {
15791
15856
  return;
15792
15857
  }
15793
15858
  if (agentGUIProviderTargetsEqual(
@@ -15816,6 +15881,7 @@ function useAgentGUINodeController({
15816
15881
  data,
15817
15882
  effectiveSelectedProviderTarget,
15818
15883
  firstReadyHomeComposerProviderTarget,
15884
+ homeDirectorySelection.source,
15819
15885
  homeComposerTargetOverride,
15820
15886
  previewMode,
15821
15887
  providerReadinessGates,
@@ -15981,7 +16047,8 @@ function useAgentGUINodeController({
15981
16047
  updateConversationFilter
15982
16048
  );
15983
16049
  const viewData = activeConversationId === null ? selectedComposerTargetData.data : data;
15984
- const providerReadinessGate = activeConversationId === null ? providerReadinessGates?.[effectiveSelectedProviderTarget.provider] ?? null : null;
16050
+ const effectiveHomeDirectorySelectionStatus = homeComposerTargetOverride ? "resolved" : homeDirectorySelection.status;
16051
+ const providerReadinessGate = activeConversationId === null ? effectiveHomeDirectorySelectionStatus === "loading" ? { status: "checking" } : effectiveHomeDirectorySelectionStatus === "missing" ? { status: "unavailable" } : providerReadinessGates?.[effectiveSelectedProviderTarget.provider] ?? null : null;
15985
16052
  const controllerActions = useMemo3(
15986
16053
  () => ({
15987
16054
  updateConversationFilter: stableUpdateConversationFilter,
@@ -22717,6 +22784,27 @@ var DOCK_COMPOSER_INPUT_BORDER_HEIGHT = 2;
22717
22784
  var DOCK_COMPOSER_INPUT_PADDING_BLOCK_HEIGHT = 24;
22718
22785
  var AGENT_COMPOSER_PASTED_TEXT_FILE_PREFIX = "pasted-text";
22719
22786
  var AGENT_COMPOSER_PASTED_TEXT_MIME = "text/plain";
22787
+ function reportAgentComposerDiagnostic(runtime, input) {
22788
+ const reportDiagnostic = runtime?.reportDiagnostic;
22789
+ try {
22790
+ if (reportDiagnostic && runtime) {
22791
+ void Promise.resolve(reportDiagnostic.call(runtime, input)).catch(
22792
+ () => {
22793
+ }
22794
+ );
22795
+ }
22796
+ if (!runtime || !agentComposerDevConsoleDiagnosticSinkEnabled(runtime)) {
22797
+ return;
22798
+ }
22799
+ const level = input.level ?? "info";
22800
+ const consoleMethod = level === "error" ? console.error : level === "warn" ? console.warn : level === "debug" ? console.debug : console.info;
22801
+ consoleMethod.call(console, "[agent-gui]", input.event, input);
22802
+ } catch {
22803
+ }
22804
+ }
22805
+ function agentComposerDevConsoleDiagnosticSinkEnabled(runtime) {
22806
+ return runtime.devDiagnosticConsoleSink !== false && typeof process !== "undefined" && (process.env.NODE_ENV === "development" || process.env.AGENT_GUI_DEV_DIAGNOSTIC_CONSOLE === "1");
22807
+ }
22720
22808
  function agentComposerTextByteLength(text) {
22721
22809
  if (typeof TextEncoder !== "undefined") {
22722
22810
  return new TextEncoder().encode(text).byteLength;
@@ -24165,6 +24253,20 @@ function AgentComposer({
24165
24253
  return;
24166
24254
  }
24167
24255
  const uploadPromptContent = canUploadAttachment && agentActivityRuntime?.uploadPromptContent && (agentActivityRuntime.promptContentUploadSupport?.image ?? true) ? agentActivityRuntime.uploadPromptContent : void 0;
24256
+ reportAgentComposerDiagnostic(agentActivityRuntime, {
24257
+ details: {
24258
+ imageCount: Math.min(images.length, remainingSlots),
24259
+ promptImagesSupported,
24260
+ runtimeAvailable: Boolean(agentActivityRuntime),
24261
+ uploadCapabilityEnabled: canUploadAttachment,
24262
+ uploadFunctionAvailable: Boolean(uploadPromptContent),
24263
+ uploadSupportDeclared: agentActivityRuntime?.promptContentUploadSupport?.image ?? null
24264
+ },
24265
+ event: "agent.gui.composer.image_upload.requested",
24266
+ level: "info",
24267
+ source: "agent-gui",
24268
+ workspaceId
24269
+ });
24168
24270
  const nextImages = images.slice(0, remainingSlots).map((image) => ({
24169
24271
  id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,
24170
24272
  name: image.name,
@@ -24199,7 +24301,22 @@ function AgentComposer({
24199
24301
  const uploadedImage = result.content.find(
24200
24302
  (block) => block.type === "image"
24201
24303
  );
24202
- if (!uploadedImage || !uploadedImage.attachmentId && !uploadedImage.path && !uploadedImage.data) {
24304
+ const uploadedUrl = uploadedImage?.url?.trim();
24305
+ reportAgentComposerDiagnostic(agentActivityRuntime, {
24306
+ details: {
24307
+ foundImageBlock: Boolean(uploadedImage),
24308
+ hasAttachmentId: Boolean(uploadedImage?.attachmentId?.trim()),
24309
+ hasData: Boolean(uploadedImage?.data?.trim()),
24310
+ hasPath: Boolean(uploadedImage?.path?.trim()),
24311
+ hasUrl: Boolean(uploadedUrl),
24312
+ imageId: draftImage.id
24313
+ },
24314
+ event: "agent.gui.composer.image_upload.resolved",
24315
+ level: "info",
24316
+ source: "agent-gui",
24317
+ workspaceId
24318
+ });
24319
+ if (!uploadedImage || !uploadedUrl && !uploadedImage.attachmentId && !uploadedImage.path && !uploadedImage.data) {
24203
24320
  throw new Error(
24204
24321
  "Prompt image upload completed without usable image reference."
24205
24322
  );
@@ -24210,7 +24327,7 @@ function AgentComposer({
24210
24327
  name: image.name,
24211
24328
  mimeType: image.mimeType,
24212
24329
  ...uploadedImage.attachmentId ? { attachmentId: uploadedImage.attachmentId } : {},
24213
- ...uploadedImage.data ? { data: uploadedImage.data } : {},
24330
+ ...uploadedUrl ? { url: uploadedUrl } : uploadedImage.data ? { data: uploadedImage.data } : {},
24214
24331
  ...uploadedImage.path ? { path: uploadedImage.path } : {},
24215
24332
  previewUrl: image.previewUrl,
24216
24333
  uploading: false
@@ -24225,6 +24342,16 @@ function AgentComposer({
24225
24342
  });
24226
24343
  }).catch((error) => {
24227
24344
  const message = error instanceof Error ? error.message : String(error);
24345
+ reportAgentComposerDiagnostic(agentActivityRuntime, {
24346
+ details: {
24347
+ error: message.slice(0, 500),
24348
+ imageId: draftImage.id
24349
+ },
24350
+ event: "agent.gui.composer.image_upload.failed",
24351
+ level: "warn",
24352
+ source: "agent-gui",
24353
+ workspaceId
24354
+ });
24228
24355
  const failedDraftImages = draftImagesRef.current.map(
24229
24356
  (image) => image.id === draftImage.id ? {
24230
24357
  ...image,
@@ -25033,6 +25160,67 @@ ${normalizedText}` : normalizedText;
25033
25160
  const shouldShowStopButton = showStopButton && !isQueueMode;
25034
25161
  const sendButtonState = isQueueMode ? "queue" : shouldShowStopButton ? isInterrupting ? "stopping" : "interrupt" : isSendingTurn ? "loading" : "send";
25035
25162
  const sendButtonBusy = isSendingTurn && !isQueueMode;
25163
+ const sendDisabledReasons = [
25164
+ isSelectedProjectMissing ? "project_missing" : null,
25165
+ submitDisabled ? "submit_disabled" : null,
25166
+ !hasDraftContent ? "draft_empty" : null,
25167
+ hasUploadingDraftImages ? "image_uploading" : null,
25168
+ hasFailedDraftImages ? "image_upload_failed" : null,
25169
+ hasUploadingDraftFiles ? "file_uploading" : null,
25170
+ hasFailedDraftFiles ? "file_upload_failed" : null,
25171
+ hasUploadingDraftLargeTexts ? "large_text_uploading" : null,
25172
+ hasFailedDraftLargeTexts ? "large_text_upload_failed" : null,
25173
+ sendButtonBusy ? "send_busy" : null
25174
+ ].filter((reason) => reason !== null);
25175
+ const sendDisabledReasonKey = sendDisabledReasons.join(",");
25176
+ useEffect15(() => {
25177
+ reportAgentComposerDiagnostic(agentActivityRuntime, {
25178
+ details: {
25179
+ canUploadAttachment,
25180
+ draftFileCount: draftFiles.length,
25181
+ draftImageCount: draftImages.length,
25182
+ draftLargeTextCount: draftLargeTexts.length,
25183
+ hasDraftContent,
25184
+ hasFailedDraftFiles,
25185
+ hasFailedDraftImages,
25186
+ hasFailedDraftLargeTexts,
25187
+ hasUploadingDraftFiles,
25188
+ hasUploadingDraftImages,
25189
+ hasUploadingDraftLargeTexts,
25190
+ isSelectedProjectMissing,
25191
+ promptImagesSupported,
25192
+ sendButtonBusy,
25193
+ sendDisabledReason: sendDisabledReasonKey || null,
25194
+ submitDisabled,
25195
+ uploadFunctionAvailable: Boolean(
25196
+ agentActivityRuntime?.uploadPromptContent
25197
+ )
25198
+ },
25199
+ event: "agent.gui.composer.submit_state_changed",
25200
+ level: "info",
25201
+ source: "agent-gui",
25202
+ workspaceId
25203
+ });
25204
+ }, [
25205
+ agentActivityRuntime,
25206
+ canUploadAttachment,
25207
+ draftFiles.length,
25208
+ draftImages.length,
25209
+ draftLargeTexts.length,
25210
+ hasDraftContent,
25211
+ hasFailedDraftFiles,
25212
+ hasFailedDraftImages,
25213
+ hasFailedDraftLargeTexts,
25214
+ hasUploadingDraftFiles,
25215
+ hasUploadingDraftImages,
25216
+ hasUploadingDraftLargeTexts,
25217
+ isSelectedProjectMissing,
25218
+ promptImagesSupported,
25219
+ sendButtonBusy,
25220
+ sendDisabledReasonKey,
25221
+ submitDisabled,
25222
+ workspaceId
25223
+ ]);
25036
25224
  const activePromptRequestId = activePrompt?.requestId ?? null;
25037
25225
  const [dismissedPromptRequestId, setDismissedPromptRequestId] = useState14(null);
25038
25226
  const visibleActivePrompt = activePrompt && dismissedPromptRequestId !== activePromptRequestId ? activePrompt : null;
@@ -25102,6 +25290,7 @@ ${normalizedText}` : normalizedText;
25102
25290
  type: "submit",
25103
25291
  className: AgentGUINode_styles_default.composerSendButton,
25104
25292
  "data-state": sendButtonState,
25293
+ "data-disabled-reason": sendDisabledReasonKey || void 0,
25105
25294
  disabled: isSelectedProjectMissing || submitDisabled || !hasDraftContent || hasUploadingDraftImages || hasFailedDraftImages || hasUploadingDraftFiles || hasFailedDraftFiles || hasUploadingDraftLargeTexts || hasFailedDraftLargeTexts || sendButtonBusy,
25106
25295
  "aria-label": labels.send,
25107
25296
  title: labels.send,
@@ -33512,15 +33701,14 @@ var AgentGUINode = memo4(function AgentGUINode2({
33512
33701
  ),
33513
33702
  [normalizedAgents]
33514
33703
  );
33515
- const selectedDirectoryAgent = useMemo12(() => {
33516
- const selectedAgentTargetId = state.agentTargetId?.trim() || defaultAgentTargetId?.trim() || "";
33517
- return agentByTargetId.get(selectedAgentTargetId) ?? normalizedAgents[0] ?? null;
33518
- }, [
33519
- agentByTargetId,
33520
- defaultAgentTargetId,
33521
- normalizedAgents,
33522
- state.agentTargetId
33523
- ]);
33704
+ const selectedDirectoryAgent = useMemo12(
33705
+ () => resolveAgentGUISelectedDirectoryAgent({
33706
+ agents: normalizedAgents,
33707
+ agentTargetId: state.agentTargetId,
33708
+ defaultAgentTargetId
33709
+ }),
33710
+ [defaultAgentTargetId, normalizedAgents, state.agentTargetId]
33711
+ );
33524
33712
  const internalProviderReadinessGates = useMemo12(() => {
33525
33713
  if (!selectedDirectoryAgent || selectedDirectoryAgent.availability.status === "ready") {
33526
33714
  return {};
@@ -33547,7 +33735,7 @@ var AgentGUINode = memo4(function AgentGUINode2({
33547
33735
  };
33548
33736
  }, [agentByTargetId, renderAgentUnavailableState]);
33549
33737
  const renderInternalAgentReadinessState = useMemo12(() => {
33550
- if (!renderAgentReadinessState) {
33738
+ if (!renderAgentReadinessState || !selectedDirectoryAgent) {
33551
33739
  return void 0;
33552
33740
  }
33553
33741
  return ({ target, showAllProviders }) => {