@tutti-os/agent-gui 0.0.24 → 0.0.25

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
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  AgentInteractivePromptSurface,
15
15
  approvalOptionDisplayLabel
16
- } from "./chunk-4MOHKNXA.js";
16
+ } from "./chunk-OSBLVO4N.js";
17
17
  import {
18
18
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
19
19
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -36,13 +36,13 @@ import {
36
36
  skillDescriptionForDisplay,
37
37
  skillTriggerForPrefix,
38
38
  useProjectedAgentConversation
39
- } from "./chunk-7JW4OAKS.js";
39
+ } from "./chunk-3QDLVPMJ.js";
40
40
  import {
41
41
  AgentMessageMarkdown,
42
42
  ZoomableImage,
43
43
  cn,
44
44
  resolveWorkspaceLinkAction
45
- } from "./chunk-BUBD5E4F.js";
45
+ } from "./chunk-VNRRXUI3.js";
46
46
  import {
47
47
  AGENT_MENTION_FILTER_TAB_ORDER,
48
48
  AgentFileMentionPalette,
@@ -50,7 +50,7 @@ import {
50
50
  DEFAULT_AGENT_MENTION_FILTER,
51
51
  agentMentionItemKey,
52
52
  preloadAgentMentionBrowse
53
- } from "./chunk-Q6QE7JNG.js";
53
+ } from "./chunk-5PIXN7UF.js";
54
54
  import {
55
55
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
56
56
  buildWorkspaceAgentActivityListViewModel,
@@ -90,7 +90,7 @@ import {
90
90
  useAgentActivitySnapshot,
91
91
  useAgentHostApi,
92
92
  useOptionalAgentActivityRuntime
93
- } from "./chunk-CCI6EK5W.js";
93
+ } from "./chunk-YHRJD6HA.js";
94
94
  import "./chunk-TYGL25EL.js";
95
95
  import {
96
96
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
@@ -3171,10 +3171,10 @@ function compareTimelineItemsForMerge(left, right) {
3171
3171
  // agent-gui/agentGuiNode/model/agentComposerDraft.ts
3172
3172
  var MAX_AGENT_COMPOSER_DRAFT_IMAGES = 8;
3173
3173
  function emptyAgentComposerDraft() {
3174
- return { prompt: "", images: [] };
3174
+ return { prompt: "", images: [], files: [] };
3175
3175
  }
3176
3176
  function agentComposerDraftHasContent(draft) {
3177
- return draft.prompt.trim() !== "" || draft.images.length > 0;
3177
+ return draft.prompt.trim() !== "" || draft.images.length > 0 || (draft.files?.length ?? 0) > 0;
3178
3178
  }
3179
3179
  function normalizeAgentPromptContentBlocks(content) {
3180
3180
  const result = [];
@@ -3201,6 +3201,26 @@ function normalizeAgentPromptContentBlocks(content) {
3201
3201
  });
3202
3202
  continue;
3203
3203
  }
3204
+ if (block.type === "file") {
3205
+ const filePath = block.path?.trim();
3206
+ const hostPath = block.hostPath?.trim();
3207
+ if (!filePath && !hostPath) {
3208
+ continue;
3209
+ }
3210
+ result.push({
3211
+ type: "file",
3212
+ ...block.mimeType?.trim() ? { mimeType: block.mimeType.trim() } : {},
3213
+ ...filePath ? { path: filePath } : {},
3214
+ ...hostPath ? { hostPath } : {},
3215
+ ...block.name?.trim() ? { name: block.name.trim() } : {},
3216
+ ...block.uri?.trim() ? { uri: block.uri.trim() } : {},
3217
+ ...block.uploadStatus?.trim() ? { uploadStatus: block.uploadStatus.trim() } : {},
3218
+ ...block.assetId?.trim() ? { assetId: block.assetId.trim() } : {},
3219
+ ...typeof block.sizeBytes === "number" ? { sizeBytes: block.sizeBytes } : {},
3220
+ kind: "file"
3221
+ });
3222
+ continue;
3223
+ }
3204
3224
  if (block.type === "skill" || block.type === "mention") {
3205
3225
  const name = block.name?.trim();
3206
3226
  const path = block.path?.trim();
@@ -3228,6 +3248,9 @@ function agentPromptContentToComposerDraft(content, idPrefix) {
3228
3248
  prompt: agentPromptContentDisplayText(normalizedContent),
3229
3249
  images: agentPromptContentImageBlocks(normalizedContent).slice(0, MAX_AGENT_COMPOSER_DRAFT_IMAGES).map(
3230
3250
  (image, index) => agentPromptImageBlockToDraftImage(image, idPrefix, index)
3251
+ ),
3252
+ files: agentPromptFileBlocks(normalizedContent).map(
3253
+ (file, index) => agentPromptFileBlockToDraftFile(file, idPrefix, index)
3231
3254
  )
3232
3255
  };
3233
3256
  }
@@ -3249,9 +3272,24 @@ function agentComposerDraftToPromptContent(input) {
3249
3272
  mimeType: image.mimeType,
3250
3273
  ...image.path ? { path: image.path } : { data: image.data },
3251
3274
  name: image.name
3275
+ })),
3276
+ ...(input.draft.files ?? []).filter((file) => !file.uploading && !file.uploadError).map((file) => ({
3277
+ type: "file",
3278
+ ...file.mimeType ? { mimeType: file.mimeType } : {},
3279
+ ...file.path ? { path: file.path } : {},
3280
+ ...file.hostPath ? { hostPath: file.hostPath } : {},
3281
+ ...file.assetId ? { assetId: file.assetId } : {},
3282
+ ...file.sizeBytes ? { sizeBytes: file.sizeBytes } : {},
3283
+ name: file.name,
3284
+ kind: "file"
3252
3285
  }))
3253
3286
  ]);
3254
3287
  }
3288
+ function agentPromptFileBlocks(content) {
3289
+ return normalizeAgentPromptContentBlocks(content).filter(
3290
+ (block) => block.type === "file" && (typeof block.path === "string" || typeof block.hostPath === "string")
3291
+ );
3292
+ }
3255
3293
  function promptItemBlocksForProviderSkills(input) {
3256
3294
  if (input.provider.trim() !== "codex") {
3257
3295
  return [];
@@ -3289,11 +3327,22 @@ function agentPromptImageBlockToDraftImage(image, idPrefix, index) {
3289
3327
  id: `${idPrefix}:image:${index}`,
3290
3328
  name: image.name?.trim() || `image-${index + 1}`,
3291
3329
  mimeType: image.mimeType,
3292
- data: image.data,
3293
- path: image.path,
3330
+ ...image.data ? { data: image.data } : {},
3331
+ ...image.path ? { path: image.path } : {},
3294
3332
  previewUrl: typeof image.data === "string" && image.data ? `data:${image.mimeType};base64,${image.data}` : image.path ?? ""
3295
3333
  };
3296
3334
  }
3335
+ function agentPromptFileBlockToDraftFile(file, idPrefix, index) {
3336
+ return {
3337
+ id: `${idPrefix}:file:${index}`,
3338
+ name: file.name?.trim() || `file-${index + 1}`,
3339
+ mimeType: file.mimeType,
3340
+ path: file.path,
3341
+ hostPath: file.hostPath,
3342
+ assetId: file.assetId,
3343
+ sizeBytes: file.sizeBytes
3344
+ };
3345
+ }
3297
3346
 
3298
3347
  // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
3299
3348
  function projectWorkspaceAgentMessagesToTimelineItems(messages) {
@@ -17108,6 +17157,7 @@ function AgentComposer({
17108
17157
  "use memo";
17109
17158
  const draftPrompt = draftContent.prompt;
17110
17159
  const draftImages = draftContent.images;
17160
+ const draftFiles = draftContent.files ?? [];
17111
17161
  const agentActivityRuntime = useOptionalAgentActivityRuntime();
17112
17162
  const [isPaletteOpen, setIsPaletteOpen] = useState10(true);
17113
17163
  const [isReviewPickerOpen, setIsReviewPickerOpen] = useState10(false);
@@ -17144,6 +17194,7 @@ function AgentComposer({
17144
17194
  const paletteContentRef = useRef12(null);
17145
17195
  const draftPromptRef = useRef12(draftPrompt);
17146
17196
  const draftImagesRef = useRef12(draftImages);
17197
+ const draftFilesRef = useRef12(draftFiles);
17147
17198
  const submittedImagePreviewObservedBusyRef = useRef12(false);
17148
17199
  const promptTipRef = useRef12(null);
17149
17200
  const mentionControllerRef = useRef12(
@@ -17350,6 +17401,9 @@ function AgentComposer({
17350
17401
  useEffect11(() => {
17351
17402
  draftImagesRef.current = draftImages;
17352
17403
  }, [draftImages]);
17404
+ useEffect11(() => {
17405
+ draftFilesRef.current = draftFiles;
17406
+ }, [draftFiles]);
17353
17407
  useEffect11(() => {
17354
17408
  if (previousSlashStatusAgentSessionIdRef.current === slashStatusAgentSessionId) {
17355
17409
  return;
@@ -17901,7 +17955,8 @@ function AgentComposer({
17901
17955
  draftImagesRef.current = nextDraftImages;
17902
17956
  onDraftContentChange({
17903
17957
  prompt: draftPromptRef.current,
17904
- images: nextDraftImages
17958
+ images: nextDraftImages,
17959
+ files: draftFilesRef.current
17905
17960
  });
17906
17961
  if (!uploadPromptContent) {
17907
17962
  return;
@@ -17938,7 +17993,8 @@ function AgentComposer({
17938
17993
  draftImagesRef.current = uploadedDraftImages;
17939
17994
  onDraftContentChange({
17940
17995
  prompt: draftPromptRef.current,
17941
- images: uploadedDraftImages
17996
+ images: uploadedDraftImages,
17997
+ files: draftFilesRef.current
17942
17998
  });
17943
17999
  }).catch((error) => {
17944
18000
  const message = error instanceof Error ? error.message : String(error);
@@ -17952,7 +18008,8 @@ function AgentComposer({
17952
18008
  draftImagesRef.current = failedDraftImages;
17953
18009
  onDraftContentChange({
17954
18010
  prompt: draftPromptRef.current,
17955
- images: failedDraftImages
18011
+ images: failedDraftImages,
18012
+ files: draftFilesRef.current
17956
18013
  });
17957
18014
  });
17958
18015
  }
@@ -17979,7 +18036,103 @@ function AgentComposer({
17979
18036
  draftImagesRef.current = nextDraftImages;
17980
18037
  onDraftContentChange({
17981
18038
  prompt: draftPromptRef.current,
17982
- images: nextDraftImages
18039
+ images: nextDraftImages,
18040
+ files: draftFilesRef.current
18041
+ });
18042
+ },
18043
+ [onDraftContentChange]
18044
+ );
18045
+ const addDraftFiles = useCallback9(
18046
+ (attachments) => {
18047
+ if (attachments.length === 0) {
18048
+ return;
18049
+ }
18050
+ const uploadPromptContent = agentActivityRuntime?.uploadPromptContent;
18051
+ const nextFiles = attachments.map((attachment) => ({
18052
+ id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,
18053
+ name: attachment.name,
18054
+ mimeType: attachment.mimeType?.trim() || "application/octet-stream",
18055
+ hostPath: attachment.hostPath,
18056
+ uploading: Boolean(uploadPromptContent)
18057
+ }));
18058
+ const nextDraftFiles = [...draftFilesRef.current, ...nextFiles];
18059
+ draftFilesRef.current = nextDraftFiles;
18060
+ onDraftContentChange({
18061
+ prompt: draftPromptRef.current,
18062
+ images: draftImagesRef.current,
18063
+ files: nextDraftFiles
18064
+ });
18065
+ if (!uploadPromptContent) {
18066
+ return;
18067
+ }
18068
+ for (const draftFile of nextFiles) {
18069
+ void uploadPromptContent({
18070
+ workspaceId,
18071
+ content: [
18072
+ {
18073
+ type: "file",
18074
+ mimeType: draftFile.mimeType,
18075
+ hostPath: draftFile.hostPath,
18076
+ name: draftFile.name,
18077
+ kind: "file"
18078
+ }
18079
+ ]
18080
+ }).then((result) => {
18081
+ const uploadedFile = result.content.find(
18082
+ (block) => block.type === "file"
18083
+ );
18084
+ const uploadedPath = uploadedFile?.path?.trim() ?? "";
18085
+ if (!uploadedPath) {
18086
+ throw new Error("Prompt file upload completed without path.");
18087
+ }
18088
+ const uploadedDraftFiles = draftFilesRef.current.map(
18089
+ (file) => file.id === draftFile.id ? {
18090
+ id: file.id,
18091
+ name: uploadedFile?.name ?? file.name,
18092
+ mimeType: uploadedFile?.mimeType ?? file.mimeType,
18093
+ path: uploadedPath,
18094
+ hostPath: uploadedFile?.hostPath ?? file.hostPath,
18095
+ assetId: uploadedFile?.assetId,
18096
+ sizeBytes: uploadedFile?.sizeBytes,
18097
+ uploading: false
18098
+ } : file
18099
+ );
18100
+ draftFilesRef.current = uploadedDraftFiles;
18101
+ onDraftContentChange({
18102
+ prompt: draftPromptRef.current,
18103
+ images: draftImagesRef.current,
18104
+ files: uploadedDraftFiles
18105
+ });
18106
+ }).catch((error) => {
18107
+ const message = error instanceof Error ? error.message : String(error);
18108
+ const failedDraftFiles = draftFilesRef.current.map(
18109
+ (file) => file.id === draftFile.id ? {
18110
+ ...file,
18111
+ uploading: false,
18112
+ uploadError: message
18113
+ } : file
18114
+ );
18115
+ draftFilesRef.current = failedDraftFiles;
18116
+ onDraftContentChange({
18117
+ prompt: draftPromptRef.current,
18118
+ images: draftImagesRef.current,
18119
+ files: failedDraftFiles
18120
+ });
18121
+ });
18122
+ }
18123
+ },
18124
+ [agentActivityRuntime, onDraftContentChange, workspaceId]
18125
+ );
18126
+ const removeDraftFile = useCallback9(
18127
+ (id) => {
18128
+ const nextDraftFiles = draftFilesRef.current.filter(
18129
+ (file) => file.id !== id
18130
+ );
18131
+ draftFilesRef.current = nextDraftFiles;
18132
+ onDraftContentChange({
18133
+ prompt: draftPromptRef.current,
18134
+ images: draftImagesRef.current,
18135
+ files: nextDraftFiles
17983
18136
  });
17984
18137
  },
17985
18138
  [onDraftContentChange]
@@ -17992,8 +18145,11 @@ function AgentComposer({
17992
18145
  if (result.mentionItems.length > 0) {
17993
18146
  editorHandleRef.current?.insertMentionItems(result.mentionItems);
17994
18147
  }
18148
+ if (result.hostAttachments && result.hostAttachments.length > 0) {
18149
+ addDraftFiles(result.hostAttachments);
18150
+ }
17995
18151
  },
17996
- []
18152
+ [addDraftFiles]
17997
18153
  );
17998
18154
  const handleWorkspaceReferencePicker = useCallback9(async () => {
17999
18155
  if (!onRequestWorkspaceReferences) {
@@ -18260,6 +18416,7 @@ function AgentComposer({
18260
18416
  const effectivePlaceholder = disabledReasonText || placeholder;
18261
18417
  const showingSubmittedImagePreview = draftImages.length === 0 && submittedImagePreview.length > 0;
18262
18418
  const visibleDraftImages = draftImages.length > 0 ? draftImages : submittedImagePreview;
18419
+ const visibleDraftFiles = draftFiles;
18263
18420
  useEffect11(() => {
18264
18421
  if (submittedImagePreview.length === 0) {
18265
18422
  submittedImagePreviewObservedBusyRef.current = false;
@@ -18502,6 +18659,56 @@ function AgentComposer({
18502
18659
  ))
18503
18660
  }
18504
18661
  ) : null,
18662
+ visibleDraftFiles.length > 0 ? /* @__PURE__ */ jsx26(
18663
+ "div",
18664
+ {
18665
+ className: "mb-2 flex max-w-[520px] flex-wrap gap-2",
18666
+ "data-testid": "agent-gui-composer-file-drafts",
18667
+ children: visibleDraftFiles.map((file) => /* @__PURE__ */ jsxs13(
18668
+ "div",
18669
+ {
18670
+ className: cn(
18671
+ "group inline-flex max-w-full items-center gap-2 rounded-[6px] border border-[var(--line-1)] bg-[var(--background-fronted)] px-2 py-1 text-xs text-[var(--text-primary)]",
18672
+ file.uploadError && "border-[color:color-mix(in_srgb,var(--danger)_55%,var(--line-1))]"
18673
+ ),
18674
+ "data-uploading": file.uploading ? "true" : void 0,
18675
+ "data-upload-error": file.uploadError ? "true" : void 0,
18676
+ title: file.hostPath ?? file.path ?? file.name,
18677
+ children: [
18678
+ file.uploading ? /* @__PURE__ */ jsx26(
18679
+ Spinner,
18680
+ {
18681
+ className: "shrink-0 text-[var(--text-primary)]",
18682
+ size: 14,
18683
+ strokeWidth: 2.4,
18684
+ trackColor: "var(--transparency-hover)",
18685
+ testId: "agent-gui-composer-file-upload-spinner"
18686
+ }
18687
+ ) : /* @__PURE__ */ jsx26(
18688
+ "span",
18689
+ {
18690
+ className: "size-2 shrink-0 rounded-full bg-[var(--text-tertiary)]",
18691
+ "aria-hidden": true
18692
+ }
18693
+ ),
18694
+ /* @__PURE__ */ jsx26("span", { className: "min-w-0 max-w-[220px] truncate", children: file.name }),
18695
+ /* @__PURE__ */ jsx26(
18696
+ "button",
18697
+ {
18698
+ type: "button",
18699
+ className: "inline-flex size-5 shrink-0 items-center justify-center rounded-full text-[var(--text-secondary)] transition hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:color-mix(in_srgb,var(--text-primary)_34%,transparent)]",
18700
+ "aria-label": labels.removeMention,
18701
+ title: labels.removeMention,
18702
+ onClick: () => removeDraftFile(file.id),
18703
+ children: /* @__PURE__ */ jsx26(X, { size: 12, strokeWidth: 2.4, "aria-hidden": true })
18704
+ }
18705
+ )
18706
+ ]
18707
+ },
18708
+ file.id
18709
+ ))
18710
+ }
18711
+ ) : null,
18505
18712
  /* @__PURE__ */ jsx26(
18506
18713
  AgentRichTextEditor,
18507
18714
  {
@@ -19492,6 +19699,7 @@ function AgentGUINodeView({
19492
19699
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS3
19493
19700
  }) {
19494
19701
  "use memo";
19702
+ const agentHostApi = useAgentHostApi();
19495
19703
  const layoutElementRef = useRef13(null);
19496
19704
  const railResizeInteractionRef = useRef13(null);
19497
19705
  const [isRailResizing, setIsRailResizing] = useState11(false);
@@ -19509,18 +19717,117 @@ function AgentGUINodeView({
19509
19717
  );
19510
19718
  const workspaceReferencePickerResolverRef = useRef13(null);
19511
19719
  const emptyReferencePickResult = useMemo10(
19512
- () => ({ files: [], mentionItems: [] }),
19720
+ () => ({ files: [], mentionItems: [], hostAttachments: [] }),
19513
19721
  []
19514
19722
  );
19723
+ const hostLocalFileLabel = uiLanguage === "zh-CN" ? "\u672C\u5730\u6587\u4EF6(\u5BBF\u4E3B\u673A)" : "Local files (Host)";
19724
+ const hostLocalFileSelectLabel = uiLanguage === "zh-CN" ? "\u4ECE\u7535\u8111\u9009\u62E9\u2026" : "Choose from computer\u2026";
19725
+ const hostLocalFileActionPath = "host-local-file://select";
19726
+ const referenceSourceAggregatorWithHostLocalFile = useMemo10(() => {
19727
+ if (!referenceSourceAggregator) {
19728
+ return null;
19729
+ }
19730
+ const sourceId = "host-local-file";
19731
+ const actionNode = {
19732
+ ref: { sourceId, nodeId: "select-files" },
19733
+ kind: "file",
19734
+ displayName: hostLocalFileSelectLabel
19735
+ };
19736
+ const rootNode = {
19737
+ ref: { sourceId, nodeId: "\0source-root" },
19738
+ kind: "folder",
19739
+ displayName: hostLocalFileLabel,
19740
+ hasChildren: true
19741
+ };
19742
+ return {
19743
+ ...referenceSourceAggregator,
19744
+ async listSources(scope) {
19745
+ const sources = await referenceSourceAggregator.listSources(scope);
19746
+ return [
19747
+ ...sources,
19748
+ {
19749
+ sourceId,
19750
+ label: hostLocalFileLabel,
19751
+ icon: "file",
19752
+ capabilities: {
19753
+ searchable: false,
19754
+ previewable: false,
19755
+ paginated: false,
19756
+ navigable: false,
19757
+ filterable: false
19758
+ }
19759
+ }
19760
+ ];
19761
+ },
19762
+ async listRoot(scope) {
19763
+ const root = await referenceSourceAggregator.listRoot(scope);
19764
+ return [...root, rootNode];
19765
+ },
19766
+ async listChildren(scope, node, input) {
19767
+ if (node.sourceId === sourceId) {
19768
+ return { entries: [actionNode], nextCursor: null };
19769
+ }
19770
+ return await referenceSourceAggregator.listChildren(scope, node, input);
19771
+ },
19772
+ async search(scope, currentSourceId, input) {
19773
+ if (currentSourceId === sourceId) {
19774
+ return { entries: [], nextCursor: null };
19775
+ }
19776
+ return await referenceSourceAggregator.search(
19777
+ scope,
19778
+ currentSourceId,
19779
+ input
19780
+ );
19781
+ },
19782
+ async open(scope, node) {
19783
+ if (node.ref.sourceId === sourceId) {
19784
+ return;
19785
+ }
19786
+ await referenceSourceAggregator.open(scope, node);
19787
+ },
19788
+ async readPreview(scope, node) {
19789
+ if (node.ref.sourceId === sourceId) {
19790
+ return null;
19791
+ }
19792
+ return await referenceSourceAggregator.readPreview(scope, node);
19793
+ },
19794
+ resolveSelection(node) {
19795
+ if (node.ref.sourceId === sourceId) {
19796
+ return {
19797
+ path: hostLocalFileActionPath,
19798
+ kind: "file",
19799
+ displayName: actionNode.displayName
19800
+ };
19801
+ }
19802
+ return referenceSourceAggregator.resolveSelection(node);
19803
+ },
19804
+ async locateTarget(scope, currentSourceId, params) {
19805
+ if (currentSourceId === sourceId) {
19806
+ return null;
19807
+ }
19808
+ return await referenceSourceAggregator.locateTarget(
19809
+ scope,
19810
+ currentSourceId,
19811
+ params
19812
+ );
19813
+ },
19814
+ getLoadedSource(currentSourceId) {
19815
+ if (currentSourceId === sourceId) {
19816
+ return void 0;
19817
+ }
19818
+ return referenceSourceAggregator.getLoadedSource(currentSourceId);
19819
+ }
19820
+ };
19821
+ }, [hostLocalFileLabel, hostLocalFileSelectLabel, referenceSourceAggregator]);
19515
19822
  const requestWorkspaceReferences = useCallback10(
19516
19823
  async (entity) => {
19517
19824
  if (previewMode) {
19518
19825
  return emptyReferencePickResult;
19519
19826
  }
19520
- if (!workspaceFileReferenceAdapter && !referenceSourceAggregator || !workspaceFileReferenceCopy) {
19827
+ if (!workspaceFileReferenceAdapter && !referenceSourceAggregatorWithHostLocalFile || !workspaceFileReferenceCopy) {
19521
19828
  return emptyReferencePickResult;
19522
19829
  }
19523
- const target = entity && referenceSourceAggregator ? resolveMentionReferenceTarget?.(entity) ?? null : referenceSourceAggregator ? resolveWorkspaceReferenceInitialTarget?.({
19830
+ const target = entity && referenceSourceAggregatorWithHostLocalFile ? resolveMentionReferenceTarget?.(entity) ?? null : referenceSourceAggregatorWithHostLocalFile ? resolveWorkspaceReferenceInitialTarget?.({
19524
19831
  activeConversation: viewModel.activeConversation,
19525
19832
  composerSelectedProjectPath: viewModel.composerSettings.selectedProjectPath ?? null,
19526
19833
  userProjects: viewModel.userProjects
@@ -19534,7 +19841,7 @@ function AgentGUINodeView({
19534
19841
  [
19535
19842
  emptyReferencePickResult,
19536
19843
  previewMode,
19537
- referenceSourceAggregator,
19844
+ referenceSourceAggregatorWithHostLocalFile,
19538
19845
  resolveMentionReferenceTarget,
19539
19846
  resolveWorkspaceReferenceInitialTarget,
19540
19847
  viewModel.activeConversation,
@@ -19563,10 +19870,32 @@ function AgentGUINodeView({
19563
19870
  [onWorkspaceFileReferencesAdded]
19564
19871
  );
19565
19872
  const confirmWorkspaceReferencePicker = useCallback10(
19566
- (refs) => {
19567
- settleReferencePicker({ files: refs, mentionItems: [] }, refs);
19873
+ async (refs) => {
19874
+ const wantsHostFiles = refs.some(
19875
+ (ref) => ref.path === hostLocalFileActionPath
19876
+ );
19877
+ if (!wantsHostFiles) {
19878
+ settleReferencePicker(
19879
+ { files: refs, mentionItems: [], hostAttachments: [] },
19880
+ refs
19881
+ );
19882
+ return;
19883
+ }
19884
+ const workspaceRefs = refs.filter(
19885
+ (ref) => ref.path !== hostLocalFileActionPath
19886
+ );
19887
+ const selected = await agentHostApi.workspace.selectFiles();
19888
+ const hostAttachments = selected.map((file) => ({
19889
+ hostPath: file.path,
19890
+ name: file.name || file.path.split("/").pop() || file.path,
19891
+ mimeType: null
19892
+ }));
19893
+ settleReferencePicker(
19894
+ { files: workspaceRefs, mentionItems: [], hostAttachments },
19895
+ workspaceRefs
19896
+ );
19568
19897
  },
19569
- [settleReferencePicker]
19898
+ [agentHostApi.workspace, settleReferencePicker]
19570
19899
  );
19571
19900
  const confirmWorkspaceReferenceBundles = useCallback10(
19572
19901
  (result) => {
@@ -19597,7 +19926,7 @@ function AgentGUINodeView({
19597
19926
  };
19598
19927
  });
19599
19928
  settleReferencePicker(
19600
- { files: result.files, mentionItems },
19929
+ { files: result.files, mentionItems, hostAttachments: [] },
19601
19930
  result.files
19602
19931
  );
19603
19932
  },
@@ -19943,10 +20272,10 @@ function AgentGUINodeView({
19943
20272
  ]
19944
20273
  }
19945
20274
  ),
19946
- referenceSourceAggregator ? /* @__PURE__ */ jsx29(
20275
+ referenceSourceAggregatorWithHostLocalFile ? /* @__PURE__ */ jsx29(
19947
20276
  ReferenceSourcePicker,
19948
20277
  {
19949
- aggregator: referenceSourceAggregator,
20278
+ aggregator: referenceSourceAggregatorWithHostLocalFile,
19950
20279
  copy: workspaceFileReferenceCopy ?? fallbackWorkspaceFileReferenceCopy,
19951
20280
  initialTarget: workspaceReferencePickerTarget,
19952
20281
  open: workspaceReferencePickerOpen,