Skip to content

fix(core): keep payload-free images out of the inline budget cut - #61955

Open
rsdenck wants to merge 3 commits into
anomalyco:devfrom
rsdenck:image-budget-remote
Open

rsdenck wants to merge 3 commits into
anomalyco:devfrom
rsdenck:image-budget-remote

Conversation

@rsdenck

@rsdenck rsdenck commented Nov 5, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #61391

Type of change

  • Bug fix

What does this PR do?

boundImages picks how many images to replace by walking sizes in order, then applies that cut by document position. mediaBytes returns 0 for url and ref media because they carry no local payload, so those images still take slots in the removal queue. The budget loop subtracts 0 from kept but advances cut, and replaceMedia then replaces the remote image too. With two remote images followed by two 13 MiB inline images (26 MiB total), three images were replaced instead of one.

The loop now skips zero-byte entries when choosing what to drop, and the replacement pass only counts images with a non-zero payload. Remote and provider-referenced images stay in the request, so removals always free payload. The source-order prefix that keeps the prompt cache stable is unchanged for images that carry payload.

How did you verify your code works?

Added a regression test in packages/core/test/session-model-request.test.ts with two remote images followed by two 13 MiB inline images. On dev it fails with Expected: 1, Received: 3; with the fix it passes.

  • cd packages/core && bun run script/test.ts test/session-model-request.test.ts -> 11 pass, 0 fail
  • bun run check from the repo root -> 35 successful tasks, 0 errors
  • bun run typecheck:tsc from packages/core -> clean

Visual

Not a user-facing visual change; no new UI.

Screenshots / recordings

N/A (request shaping only).

Checklist

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

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks correct. I ran the #61391 reproduction (two remote images followed by two 13 MiB inline ones) on the base and with this change: the base replaced three images, this PR replaces only c.png. A case with remote images placed between three inline ones also drops only the two oldest inline images. session-model-request.test.ts passes (11/11), including the prompt-cache prefix-stability test, and typecheck:tsc in packages/core is clean.

The cut loop and the replacement pass count the same set of images (those with a non-zero payload) in the same order, so the replaced prefix still follows document order for inline images. The inner while (sizes[next] === 0) can't run past the end, because kept > IMAGE_BYTES_TARGET means a non-zero image is still left.

Public API: unchanged.

No blocking concerns.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The new commits only merge dev. The fix in model-request.ts and its test are unchanged. I re-ran the #61391 reproduction and session-model-request.test.ts on the new head: only the inline c.png is replaced, the tests pass and typecheck:tsc in packages/core is clean.

Public API: unchanged.

No new concerns.

This branch has not been deployed

No deployments
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.

core: boundImages spends its image-budget cut on remote images that carry no payload

1 participant