You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
In-memory rolling window for images to reduce 413 and too-many-images errors #48095
When agent loops use browser tools (Playwright, Chrome DevTools) or iterate on
visual UI tasks, a chat can accumulate many screenshot attachments. Eventually
the provider or gateway may reject the request with errors such as:
413 Request Entity Too Large
Request contains too many images
provider-specific body-size limit errors
Once this happens, sending a plain text message can remain difficult because
the accumulated image payload is assembled again. Compaction can also be
affected if it receives the same raw image data.
Proposed Solution
Add an in-memory rolling window for multimodal image parts during context
assembly, before dispatch to the provider:
Active image window: Keep a configurable number of recent images (for
example, the latest 7) as raw image payloads so recent work keeps full visual
fidelity.
Payload budget: Apply a configurable cumulative image-payload budget in
addition to the count limit. The community implementation uses a default of
16 MiB estimated wire Base64 bytes.
Older images become context cards: Replace images outside either budget
with lightweight text cards containing the file path, what was observed,
why it was captured, and a way to request the image again.
Natural recall: If a user asks about an older screenshot, the model can
read the path from the card and bring that image back into active context.
History untouched: Only the outgoing context is changed. Persisted
conversation history remains complete.
Compaction safety: During compaction, pass text cards instead of raw
image data.
Benefits
Reduces the chance of 413 and image-count failures during long visual
debugging workflows.
Limits image request bandwidth and input-token pressure.
Keeps recent images available at full fidelity while retaining a useful,
best-effort summary of older images.
Does not require a model call or an extra user prompt to prune context.
The community implementation is available at Sugamsss/opencode-prune-images.
It is source-only and currently not published to npm. Its tests use synthetic
fixtures; provider-specific request limits and native core integration still
need independent verification.
If the core team wants this behavior natively, I would be happy to help adapt
the design to OpenCode's context assembly and compaction paths.
Your issue proposes a rolling-window solution (which is a different angle from the bug reports above), and the community plugin is a useful reference. It may be worth linking to or commenting on one of the existing issues, especially #47487 which is already assigned and actively tracked.
changed the title [-]In-memory rolling window for images to prevent 413 and too-many-images errors[/-][+]In-memory rolling window for images to reduce 413 and too-many-images errors[/+]on Sep 9, 2026
Thanks for the detailed proposal, and for building a working plugin. To restate it: you'd like OpenCode to keep only a configurable window of recent images (limited by count and by size) in what it sends to the model, including for compaction, and replace older images with short text cards that name the file so the model can load it again. The stored history would stay untouched.
Part of this already exists in v2. Before each request, including compaction, OpenCode checks how much image data the session has. Once it passes about 25 MiB, it replaces the oldest images with a generic "image removed" note until about 15 MiB remain. That limit can't be configured, there is no image-count limit, and the note doesn't say which file the image was. Your proposal covers all three, so maintainers will consider it as a feature request.
Until then, your plugin is a good way to get this behaviour, since the plugin API's session context and compaction hooks can change the outgoing messages.
One thing worth checking for #59303: it does the right thing by naming the removed file, but only when the image has a name. Pasted screenshots and most browser captures may come in without one, and then the placeholder falls back to the generic text, with no path to read again. That is the case that still wedges a session, because there is nothing to recover from.
Our plugin handles it by copying pasted data and /tmp captures into ~/.cache/opencode/recent-images/ before it replaces them, so the card points at a file we can read again. Beyond #59303 it also lets you set both budgets, instead of the fixed 30/20 images and 25/15 MiB.
So the two are not really in conflict. If #59303 lands, the plugin mainly adds the cache and the tunable budgets, and I am fine dropping the rest. Happy to test the PR against a few real screenshot-heavy sessions if that is useful.
Activity
github-actions commentedon Sep 9, 2026
This issue might be a duplicate of existing issues. Please check:
Your issue proposes a rolling-window solution (which is a different angle from the bug reports above), and the community plugin is a useful reference. It may be worth linking to or commenting on one of the existing issues, especially #47487 which is already assigned and actively tracked.
[-]In-memory rolling window for images to prevent 413 and too-many-images errors[/-][+]In-memory rolling window for images to reduce 413 and too-many-images errors[/+]4Liberty commentedon Sep 29, 2026
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
opencodejr commentedon Oct 28, 2026
Thanks for the detailed proposal, and for building a working plugin. To restate it: you'd like OpenCode to keep only a configurable window of recent images (limited by count and by size) in what it sends to the model, including for compaction, and replace older images with short text cards that name the file so the model can load it again. The stored history would stay untouched.
Part of this already exists in v2. Before each request, including compaction, OpenCode checks how much image data the session has. Once it passes about 25 MiB, it replaces the oldest images with a generic "image removed" note until about 15 MiB remain. That limit can't be configured, there is no image-count limit, and the note doesn't say which file the image was. Your proposal covers all three, so maintainers will consider it as a feature request.
Until then, your plugin is a good way to get this behaviour, since the plugin API's session
contextandcompactionhooks can change the outgoing messages.Related issues and PRs:
/compactopencode-prune-imagesto the ecosystem pageSugamsss commentedon Oct 28, 2026
Thanks, that matches what we see in practice.
One thing worth checking for #59303: it does the right thing by naming the removed file, but only when the image has a name. Pasted screenshots and most browser captures may come in without one, and then the placeholder falls back to the generic text, with no path to read again. That is the case that still wedges a session, because there is nothing to recover from.
Our plugin handles it by copying pasted data and
/tmpcaptures into~/.cache/opencode/recent-images/before it replaces them, so the card points at a file we can read again. Beyond #59303 it also lets you set both budgets, instead of the fixed 30/20 images and 25/15 MiB.So the two are not really in conflict. If #59303 lands, the plugin mainly adds the cache and the tunable budgets, and I am fine dropping the rest. Happy to test the PR against a few real screenshot-heavy sessions if that is useful.