Skip to content

fix(core): preserve unsupported image attachments as text instead of dropping them - #41723

Closed
Robin1987China wants to merge 1 commit into
anomalyco:v2from
Robin1987China:preserve-unsupported-images
Closed

Robin1987China wants to merge 1 commit into
anomalyco:v2from
Robin1987China:preserve-unsupported-images

Conversation

@Robin1987China

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #41722

Type of change

  • Bug fix

What does this PR do?

In V2, to-llm-message.ts only lowers image/png|jpeg|gif|webp attachments to provider media; any other image mime (e.g. image/avif, image/tiff) returned [] from attachmentContent, silently dropping the attachment. The TUI file picker accepts .avif and inserts an [Image N] mention, so the model saw the label but never the content (or a notice that it was dropped).

This PR lowers unsupported image formats to a descriptive text attachment (mime + name + reason) instead of dropping them, so the model is aware the user attached an image it cannot view and can respond appropriately instead of referencing a nonexistent image.

How did you verify your code works?

  • Added a regression test in packages/core/test/session-runner-message.test.ts covering an image/avif attachment
  • bun test test/session-runner-message.test.ts — 19 pass
  • bun typecheck (packages/core) — clean

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@Robin1987China
Robin1987China force-pushed the preserve-unsupported-images branch from 834a515 to 984f5c1 Compare August 12, 2026 07:30
@Robin1987China

Copy link
Copy Markdown
Contributor Author

Rebased onto the latest v2 — #41789 (expose local attachment paths) has landed, so the two changes now coexist in the same lowering path: supported images get the Attached file: <path> prefix, and unsupported formats (avif/tiff) get an explicit text notice that also resolves local file:// paths via the same attachmentLocation helper.

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

Overall: Good fix — silently swallowing an attached image is a nasty failure mode, and surfacing a named placeholder keeps the conversation honest. Suggestions:

  • packages/core/src/session/runner/to-llm-message.ts L67 — the branch fires on mime.startsWith("image/") unconditionally, while the message claims "model providers do not support this format"; attachmentContent receives model, and the media() path presumably consults real per-model capability — if any configured model actually accepts e.g. image/webp/image/avif, this text would be factually wrong; tie the branch to the same capability predicate used by media() and phrase it as "this model does not support...".
  • packages/core/src/session/runner/to-llm-message.ts L88-L89 — inconsistency worth a thought: unsupported non-image binaries (PDFs, audio, zip…) still fall through to return [] and vanish silently — the exact UX bug this PR fixes for images; either extend the placeholder to those types too or leave a comment explaining why images are special-cased.
  • packages/core/test/session-runner-message.test.ts L475-L505 — the fallback chain attachmentLocation(file) ?? file.name ?? (source.uri …) is only tested on its middle term; add a case with a type: "uri" source and no name to pin the URI rendering (and ideally one with neither, hitting "inline attachment").
  • packages/core/src/session/runner/to-llm-message.ts L88 — nit: MIME types are case-insensitive per RFC 2045, so startsWith("image/") misses IMAGE/PNG; every other comparison here is exact-match anyway, so a one-line .toLowerCase() (or documenting lowercase-normalized input) settles it.

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants