Skip to content

fix(opencode): keep screenshot cleanup ahead of churn - #173

Merged
sarath-menon merged 2 commits into
mainfrom
screenshot-cleanup-throughput
Oct 5, 2026
Merged

sarath-menon merged 2 commits into
mainfrom
screenshot-cleanup-throughput

Conversation

@sarath-menon

@sarath-menon sarath-menon commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

A request with 100 new images per turn previously failed on its seventh turn, after only 600 successful lifetime uploads. The eight-file cleanup pass filled the retired-file queue even when every deletion succeeded. This follow-up to #172 drains healthy cleanup continuously with at most 16 concurrent deletions per cache.

Preparation shares a total one-second cleanup wait budget across both eviction passes. Cleanup continues after the caller returns, including after close; each deletion has its own one-second deadline. Failed batches stop and retain tombstones for explicit retry. Active request/stream pins, stateful history, the 300-image active cap, and the bounded retirement queue remain enforced. Sustained provider overload can still cause explicit backpressure.

Validation: both 1,000-lifetime/100-active regression variants failed against the previous implementation and pass with this change. The paced variant uses 200 ms DELETE latency, 20 ms upload latency, and inference pacing. All 50 focused provider tests pass, covering the shared wait budget, bounded concurrency, background failure/recovery, active pins, close/reopen, cancellation, and missing/expired references. Package typecheck and local Cubic review pass. Staging testing awaits the corrected prerelease.


Summary by cubic

Fixes screenshot file cleanup in opencode so requests with sustained image churn (100 new images per turn) no longer fail once the lifetime upload count passes ~600.

  • Previous cleanup ran a single batched pass of up to 8 deletions per turn with a 1 s total deadline, letting the 300-file retirement queue fill up; the new approach drains continuously with at most 16 concurrent deletions per cache.
  • Preparation shares one total 1 s cleanup wait budget across both eviction passes, and cleanup continues in the background after the caller returns (including after close) with a per-deletion 1 s deadline.
  • Failed batches stop the drain and keep tombstones in the queue for an explicit retry; sustained provider overload still surfaces as explicit backpressure.
  • Regression tests at 1000 lifetime / 100 active images fail against the old implementation and pass with this change, both with zero-latency and paced (200 ms DELETE latency) fixtures.

Bug Fixes

  • Active request/stream pins, stateful history, the 300-image active cap, and the bounded retirement queue remain enforced.

Written for commit d8d404f. Summary will update on new commits.

Review in cubic

How we tested in staging

Final staging API suite: 61 passed. Released BrowserCode 0.1.21-screenshot-files.4 on AgentCore 288 passed owned OpenAI GPT-5.5 and direct Anthropic Fable-5 worker runs with 65 screenshot file references, then 66 in the same session, zero inline images, and SHA256-verified visual labels plus prior-label recall. Each native adapter also processed 325 unique generated PNGs across 14 requests with 25 active images, bounded body proofs, correct visual answers, and no duplicate uploads on reuse.

All owned sessions/workspaces were cleaned up; adapter plus explicit fallback deletion left zero fixture files (OpenAI: 324 delete successes + 1 already deleted; Anthropic: 323 + 2 already deleted). These live cleanup counts are aggregate, not proof that the adapter alone deleted every file; local 1,000-image/100-active churn tests cover its background drain. Ten paid runs, including diagnosed harness/provider failures, cost $10.283591. Sonnet via Bedrock remains an intentionally unsupported file route with inline fallback.

Testing began with stable matched integration 406ea87a590fe32c55a0799df2beca571a310581, preserving staging’s existing migrations; backend and worker stayed there. Concurrent control-plane deployments later advanced to 50a3ba0c and b8f69adad, both retaining the screenshot gateway change; the latter has identical relevant gateway files and was still rolling at final inspection. Production was unchanged. Deployment evidence: backend, control plane, worker, verified release.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread packages/opencode/test/provider/image-files-lifecycle.test.ts Outdated
Comment thread packages/opencode/test/provider/image-files-lifecycle.test.ts Outdated
@sarath-menon
sarath-menon merged commit ea72b83 into main Oct 5, 2026
3 checks passed
@sarath-menon sarath-menon added the tested-in-staging Verified in shared staging with recorded evidence label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tested-in-staging Verified in shared staging with recorded evidence

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant