Skip to content

feat(vision): report real image dimensions in vision results - #6858

Merged
Hmbown merged 1 commit into
codewhale-hq:wave/0.10.1-nextfrom
asto18089:upstream/vision-image-dimensions
Oct 6, 2026
Merged

Hmbown merged 1 commit into
codewhale-hq:wave/0.10.1-nextfrom
asto18089:upstream/vision-image-dimensions

Conversation

@asto18089

@asto18089 asto18089 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

image_analyze held the original bytes but let the vision model guess the image size by eye. The result now carries header-derived width/height (via image::image_dimensions — header-only, no pixel decode; the container is identified from the file extension, same decision as the mime detection) plus a format label; animated GIF/WebP report the canvas size.

The probe is best-effort: unparsable headers — including BMP, whose decoder is not compiled in — omit the fields and the tool still succeeds. The tool description tells the model to take size from the metadata (as stored; rotation metadata not applied) instead of guessing. No new dependency: the image crate is already a tui dependency with png/jpeg/webp/gif features.

Testing

  • cargo test -p codewhale-tui --lib vision::tools — wiremock end-to-end pinning real 64×48 PNG / 30×20 JPEG dimensions and labels through an actual execute round-trip; an unparsable-bytes degradation case; a minimal-BMP omission case that doubles as a decoder-feature canary
  • cargo clippy -p codewhale-tui --all-targets --all-features --locked

Adapted from the Pinvou fork's surface-alignment audit (Pinvou/CodeWhale 6f780290f, the vision dimension slice).

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • No CHANGELOG.md changes

No-Issue: Complete vision result metadata while keeping existing image analysis behavior.

The image_analyze tool held the original image bytes yet let the vision
model guess the image size from the picture, which matters for
downstream layout and analysis reasoning. The tool result now carries
the image's pixel width and height plus a format label, read with the
image crate's header-only image_dimensions probe so no pixel decode is
needed; the format label comes from the same extension decision as the
mime detection. Animated GIF/WebP report the first frame's size.

The probe is best-effort: when the header cannot be parsed — including
BMP, whose decoder is not compiled in — the fields are omitted and the
tool still succeeds, since the vision request itself does not depend on
the metadata. The tool description now tells the model to take image
size from that metadata instead of guessing by eye, names the fields as
the stored dimensions (camera rotation metadata is not applied), and
scopes the promise to images whose container can be sized.

Tests: a wiremock-backed end-to-end case asserts real PNG and JPEG
dimensions and the format label reach the result payload; an
unparsable-bytes case pins the degradation (tool succeeds, no
width/height/format keys); a well-formed minimal BMP pins the
no-decoder-feature omission boundary.

Signed-off-by: asto <asto18089@126.com>
@asto18089
asto18089 requested a review from Hmbown as a code owner October 5, 2026 11:52
@github-actions github-actions Bot added the contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm label Oct 5, 2026
@Hmbown Hmbown added this to the v0.10.2 milestone Oct 5, 2026
@Hmbown
Hmbown enabled auto-merge (squash) October 6, 2026 00:16
@Hmbown
Hmbown changed the base branch from main to wave/0.10.1-next October 6, 2026 05:30
@Hmbown
Hmbown merged commit dd3c20b into codewhale-hq:wave/0.10.1-next Oct 6, 2026
26 of 29 checks passed
Hmbown pushed a commit that referenced this pull request Oct 6, 2026
Reconcile the complete contributions from #6832 (@aboimpinto), #6867
(@hodeswildsmith455-boop), and #6805 (@LIghtJUNction) with the current
Engine, provider identities, reviewed-plugin policy, and task lifecycle.
Original contributor histories are recorded by subsequent resolved merges.

Fix the already integrated contributor cases: snapshot corruption is an
explicit unavailable/error result (#6817), malformed locales cannot select
an incidental script (#6860), image metadata uses the exact uploaded bytes
and respects available decoders (#6858), automation deletion waits for
actual scheduler reconciliation (#6864), and blocking trust/skill reads stay
off the async executor (#6869). Preserve #6857's compaction regression.

Extend #6872's human-wait lifecycle guard to approval/elevation cards;
retire only the matching ended parent request and refresh activity only
after a delivered decision. Enforce configured finite approval deadlines in
the Engine, including deadline/cancellation races and durable receipts.

Serialize Native Windows ACL admission/retirement across Core processes
with a logon-scoped kernel mutex, preserving exact SID/object validation.
Add an actual child-process lock test; serialize DSH host tests in the
existing extension-host lane. Windows execution proof remains hosted CI.

Reconcile the vendored computer-use plugin with canonical main a656f67455fc
while preserving Core's 0.12.1 embedding contract. Canonical b47/a656 tree
passed Ubuntu/macOS/Windows source and package gates, including 28/28
Windows-focused tests and the controlled desktop fixture; this is separate
from the new Engine head's CI verdict.

Partial adaptation of the discovery-cache priority portion from PR #6393
by @AdityaVG13 (original ac33dd4). Preserve the best match under count
and byte limits without importing the unfinished echolocation/fork design;
the broader draft remains open.

Validation:
- npm test: 1286 passed, 0 failed, 7 skipped; web 767/767.
- npm run check:web: lint, typecheck and production build passed.
- Affected Rust selection: 801/803 initially passed; the two fixture/lifecycle
  expectation failures were corrected and each passed a focused rerun.
- Additional focused Rust: approval 28/28, discovery cache 11/11,
  OrcaRouter synthetic catalog 3/3, and 33/33 lifecycle/API/routing checks.
- Final CI-repair selection: 37/39 initially passed; the BMP feature-proxy
  and feature-registry summary failures were corrected; both corrected tests passed (2/2, 0 failures).
- Qualified Clippy: six packages, all targets/all features, passed with
  the CI style allowances. Portable no-default-feature check passed;
  portable policy verifier 6/6 passed; formatting and diff checks passed.
- Runtime contract: 55 measured metrics passed after explicit remeasurement;
  all 21 structural identities were unchanged. Twelve byte/token-estimate
  budgets account for bounded child-wait disclosure and contributor locale
  descriptions; no runtime field/prompt was removed to lower the budget.
- Persistence budget was not qualified locally: the checker requires a
  clean tree and this shared checkout retains an unrelated operator file.
  Clean hosted CI, fresh stamped build and real DeepSeek TUI acceptance
  remain required before the integration PR can merge to main.

Refs #6872, #6843, #6795.

Co-authored-by: Paulo Aboim Pinto <paulo.aboim.pinto@gmail.com>
Co-authored-by: hodeswildsmith455-boop <hodeswildsmith455-boop@users.noreply.github.com>
Co-authored-by: LIghtJUNction <lightjunction.me@gmail.com>
Co-authored-by: AdityaVG13 <adityavgcode@gmail.com>
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants