Skip to content

Allow sending chat requests with attachments only#317776

Open
federicobrancasi wants to merge 3 commits into
mainfrom
attachment-only-chat-sends
Open

Allow sending chat requests with attachments only#317776
federicobrancasi wants to merge 3 commits into
mainfrom
attachment-only-chat-sends

Conversation

@federicobrancasi
Copy link
Copy Markdown
Member

Fixes #317775

This change allows chat requests to be sent with explicit attachments even when the text input is empty.

The work is split into two commits:

  1. Allow sending chat requests with attachments only

    Enables attachment-only sends for explicit file, directory, and image attachments.

    This updates the chat input send gating and service-side empty-message validation so attachment-only requests are accepted, while hidden or automatic context such as workspace/implicit context does not make an empty request sendable.

    It also adds localized fallback request summaries for the UI and accessibility paths, so attachment-only requests do not appear blank. Examples:

    • Attached 1 image
    • Attached 2 images
    • Attached 1 file
    • Attached 2 files
  2. Use attachment summary for empty chat request text (I don't know if necessary)

    Uses the same attachment summary as the actual request text for attachment-only sends.

    This means the user sees Attached 1 image / Attached N files, and the model also receives that summary as the request message alongside the attached context.

Videos: attachment-only send works and displays the attachment summary (Both VSCode and Agents app)

Files.Upload.Agents.mov
Files.Upload.Vscode.mov

@federicobrancasi federicobrancasi requested review from Copilot and removed request for Copilot May 21, 2026 14:08
@federicobrancasi
Copy link
Copy Markdown
Member Author

I am also exploring better UI options for attachment-only chat messages, so we may not need to show literal text like Attached 1 image long term.

For this PR, I am using that summary because otherwise the request appears as an empty chat bubble. This keeps the UI understandable and gives the model a non-empty request message alongside the attachment context.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Screenshot Changes

Base: 3d13ddb4 Current: 0e6a8d57

Changed (20)

chat/chatToolRiskBadge/GreenInContext/Dark
Before After
before after
chat/chatToolRiskBadge/GreenInContext/Light
Before After
before after
chat/chatToolRiskBadge/OrangeInContext/Dark
Before After
before after
chat/chatToolRiskBadge/OrangeInContext/Light
Before After
before after
chat/chatToolRiskBadge/RedInContext/Dark
Before After
before after
chat/chatToolRiskBadge/RedInContext/Light
Before After
before after
chat/chatToolRiskBadge/GreenElicitationInContext/Dark
Before After
before after
chat/chatToolRiskBadge/GreenElicitationInContext/Light
Before After
before after
chat/chatToolRiskBadge/OrangeElicitationInContext/Dark
Before After
before after
chat/chatToolRiskBadge/OrangeElicitationInContext/Light
Before After
before after
chat/chatToolRiskBadge/RedElicitationInContext/Dark
Before After
before after
chat/chatToolRiskBadge/RedElicitationInContext/Light
Before After
before after
chat/chatToolRiskBadge/BadgeOffInContext/Dark
Before After
before after
chat/chatToolRiskBadge/BadgeOffInContext/Light
Before After
before after
chat/chatToolRiskBadge/BadgeOffWithDisclaimerInContext/Dark
Before After
before after
chat/chatToolRiskBadge/BadgeOffWithDisclaimerInContext/Light
Before After
before after
chat/chatToolRiskBadge/BadgeOffUnsandboxedInContext/Dark
Before After
before after
chat/chatToolRiskBadge/BadgeOffUnsandboxedInContext/Light
Before After
before after
chat/chatToolRiskBadge/BadgeOffUnsandboxedWithDisclaimerInContext/Dark
Before After
before after
chat/chatToolRiskBadge/BadgeOffUnsandboxedWithDisclaimerInContext/Light
Before After
before after

dbaeumer
dbaeumer previously approved these changes May 21, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enables sending chat requests that contain only explicit attachments (files/directories/images) even when the text input is empty, and ensures these requests don’t render as “blank” in UI and accessibility surfaces across the Workbench chat and the Sessions/Agents app.

Changes:

  • Relax empty-message rejection in ChatService.sendRequest when explicit file/directory/image attachments are present.
  • Add attachment-only fallback summaries for request rendering, accessibility labels, and image carousel titles.
  • Update input gating/context keys so the primary “Send” actions/buttons can be enabled for attachment-only requests; add targeted unit tests.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/test/common/chatService/chatService.test.ts Adds coverage for accepting empty text when explicit file attachment exists, and rejecting empty text otherwise.
src/vs/workbench/contrib/chat/test/common/chatImageExtraction.test.ts Verifies image extraction UI uses attachment summary when the request text is empty.
src/vs/workbench/contrib/chat/test/common/attachments/chatVariableEntries.test.ts Adds unit tests for explicit-attachment detection and summary generation.
src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.ts Allows empty requests when explicit file/directory/image attachments are present.
src/vs/workbench/contrib/chat/common/chatImageExtraction.ts Uses attachment summary as fallback title when request message text is empty.
src/vs/workbench/contrib/chat/common/attachments/chatVariableEntries.ts Introduces helpers to detect explicit file/directory/image entries and create localized summaries.
src/vs/workbench/contrib/chat/common/actions/chatContextKeys.ts Adds chatInputHasSendableContent context key for “text or attachments” send gating.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Updates context key updates to reflect sendable attachments, not just text.
src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts Renders attachment summary when request markdown/text is empty.
src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts Switches primary submit preconditions to use inputHasSendableContent.
src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.ts Provides non-empty aria labels for attachment-only requests via attachment summary.
src/vs/sessions/contrib/chat/browser/newChatInput.ts Enables Sessions/Agents send button and send behavior for attachment-only input.

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 4

Comment on lines +483 to +485
return fileOrImageEntries.length === 1
? localize('chat.attachmentSummary.file.one', "Attached 1 file")
: localize('chat.attachmentSummary.file.many', "Attached {0} files", fileOrImageEntries.length);
export const editApplied = new RawContextKey<boolean>('chatEditApplied', false, { type: 'boolean', description: localize('chatEditApplied', "True when the chat text edits have been applied.") });

export const inputHasText = new RawContextKey<boolean>('chatInputHasText', false, { type: 'boolean', description: localize('interactiveInputHasText', "True when the chat input has text.") });
export const inputHasSendableContent = new RawContextKey<boolean>('chatInputHasSendableContent', false, { type: 'boolean', description: localize('interactiveInputHasSendableContent', "True when the chat input has text or file attachments that can be sent.") });
Comment on lines 191 to 196
const menuCondition = ChatContextKeys.chatModeKind.isEqualTo(ChatModeKind.Ask);
const precondition = ContextKeyExpr.and(
ChatContextKeys.inputHasText,
ChatContextKeys.inputHasSendableContent,
ContextKeyExpr.or(whenNotInProgress, ChatContextKeys.editingRequestType.isEqualTo(ChatContextKeys.EditingRequestType.Sent)),
ChatContextKeys.chatSessionOptionsValid,
);
const attachedContext = this._contextAttachments.attachments.length > 0
? [...this._contextAttachments.attachments]
: undefined;
const request = query;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow sending chat requests with attachments only

3 participants