Images in chat history break text-only model sessions (GLM-5.2 and other non-vision providers)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Problem
When jcode takes a screenshot or otherwise captures an image during a session, that image is stored as a ContentBlock::Image in the message history. On every subsequent turn, the full message history (including image blocks) is replayed to the provider.
For vision-capable models this is fine. But for text-only models like GLM-5.2 (via Z.AI OpenAI-compatible endpoint), the image content is sent to an API that cannot accept it. The request fails, the chat is permanently broken, and there is no in-TUI way to recover. The only option is to start a new session, losing all conversation context.
This happens even when the system prompt explicitly tells the agent not to capture screenshots. Tool calls that produce images (browser screenshot, computer_use, etc.) still inject ContentBlock::Image into history, and the provider has no way to handle it.
Reproduction
- Configure jcode with a text-only model (e.g. GLM-5.2 via Z.AI coding endpoint)
- In a session, trigger any action that produces an image in the message history (screenshot tool, pasted image, browser automation screenshot, etc.)
- Send another prompt
Expected behavior
The session continues working. Either:
- (A) Image blocks are automatically stripped from the request payload when the active provider does not support vision (the
Providertrait already exposessupports_image_input()for this), OR - (B) The user can remove individual images from the chat history via the TUI (hover/click an X on the image, or a
/remove-imagecommand), so the next request no longer contains them.
Ideally both. (A) prevents the problem. (B) gives the user manual control.
Actual behavior
The API request includes the image block. The text-only provider rejects it (400 error or similar). The session is stuck. Every subsequent prompt re-sends the same broken history. There is no way to delete the offending image without abandoning the session.
Environment
- jcode v0.66.0
- Provider: Z.AI GLM-5.2 (OpenAI-compatible,
api.z.ai/api/coding/paas/v4) - macOS 26.5.1, Apple Silicon
Relevant code
ContentBlock::Imagevariant incrates/jcode-message-types/src/lib.rsProvider::supports_image_input()already exists on the trait but is not consulted before replaying image blocks- Message serialization for provider requests happens in the provider runtime crates (e.g.
jcode-provider-openai-runtime,jcode-provider-openrouter-runtime)
Proposed approach
Option A (automatic stripping) would be the least invasive fix. In the request-building path for each provider, filter out ContentBlock::Image when supports_image_input() == false. This is a one-line guard per provider message serialization.
Option B (manual deletion) requires TUI work: a hover-to-reveal delete affordance on rendered images, or a slash command, that removes the image block from the persisted session history.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ContentBlock::Image in crates/jcode-message-types/src/lib.rs and trace provider request serialization in jcode-provider-openai-runtime and jcode-provider-openrouter-runtime. Check how Provider::supports_image_input() is exposed and identify the request-building paths that replay message history. Done means text-only sessions can continue after image-producing actions without sending unsupported image blocks; TUI deletion is an additional option described by the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100