Skip to content

fix(ui): allow composer attachments while a turn is running #4188

Description

@Sun-GLiang

What happened

While a turn is running, the Desktop composer still accepts text for the next follow-up, but pasting an image from the clipboard does nothing. No attachment chip appears, and no error or explanatory message is shown. Once the current turn finishes, pasting the same image works normally.

Expected: clipboard images should be staged in the composer while the current turn is running, just like text for the next follow-up. The user should then be able to submit the text and attachment together as a queued message.

The same active-turn restriction also affects dragging files into the composer and choosing an attachment from the menu.

Root cause: Composer explicitly rejects attachment import while props.streaming is true. ChatComposerInput detects the clipboard file, prevents the browser's default paste, and forwards it to onFiles, but the composer's acceptance gate then silently returns because a turn is active. The import action and attachment-picker row are independently gated by the same streaming state.

This restriction is inconsistent with the follow-up path, which already supports pending attachments when calling enqueueFollowUp.

How to reproduce

  1. Start Maka Desktop and open a session.
  2. Send a prompt that keeps the current turn running long enough to interact with the composer.
  3. While Maka is still processing or streaming the response, focus the composer.
  4. Copy an image or take a screenshot so that an image is available on the clipboard.
  5. Press Cmd+V.
  6. Observe that no attachment is staged and no error is shown.
  7. Wait for the current turn to finish, then paste the same image again.
  8. Observe that the attachment is now staged correctly.

Environment

  • Maka commit: 6fca2f51e
  • OS and version: macOS 15.6
  • Surface: Desktop
  • Node.js version, if running from source: v24.19.0

Logs, screenshots, or additional context

No error is logged or displayed because the clipboard event is handled successfully before the attachment is silently rejected by the active-turn gate.

Relevant code paths are in packages/ui/src/composer.tsx:

  • runImportAction rejects imports when props.streaming is true.
  • canAcceptDroppedFiles rejects clipboard and dropped files when props.streaming is true.
  • The attachment-picker menu item is disabled while props.streaming is true.

A regression test should cover pasting an image into a composer rendered with streaming=true and verify that onAttachFilePaths receives the pasted file. A fix is in progress.

Generated with assistance from Maka.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions