fix(vision): cap pixel dimensions proactively at embed time + declare Pillow
Follow-up to the salvaged #37727. That PR fixed the reactive recovery path (classifier + post-failure shrinker) but left the PROACTIVE embed-time guard in vision_tools byte-only — a tall small-byte screenshot (e.g. 1200x12000 at 0.06 MB) still baked into immutable history un-resized, relying on a failed round-trip to trigger reactive shrink. - vision_tools: add _image_exceeds_dimension() + _EMBED_MAX_DIMENSION (7900px); the embed-time cap now fires on bytes OR pixels and passes max_dimension to the resizer, so tall small-byte images are shrunk before they're embedded. - vision_tools: best-effort lazy-install of Pillow (tool.vision) in the resize ImportError fallback so the soft dep self-heals (respects allow_lazy_installs). - error_classifier: add two more Anthropic dimension-cap wording variants. - pyproject + lazy_deps: declare Pillow as the [vision] extra / tool.vision lazy dep (it was undeclared everywhere; without it ALL resize recovery no-ops). - tests: cover _image_exceeds_dimension (tall/small/edge/no-Pillow/corrupt). Co-authored-by: kyssta-exe <kyssta-exe@users.noreply.github.com>
This commit is contained in:
committed by
Teknium
co-authored by
kyssta-exe
parent
6bdbe30763
commit
dd4ba4c2c4
@@ -127,6 +127,14 @@ pty = [
|
||||
# without pulling in extra packages.
|
||||
]
|
||||
honcho = ["honcho-ai==2.0.1"]
|
||||
# Image resize recovery for the vision tools. Pillow is a soft dependency:
|
||||
# vision_tools / conversation_compression degrade gracefully without it (they
|
||||
# log and skip the resize), but without it the byte AND pixel-dimension shrink
|
||||
# paths silently no-op, so an oversized image (>5 MB or >8000px) bakes into
|
||||
# immutable history and bricks the session on Anthropic's non-retryable 400.
|
||||
# Declared here so packagers (Nix, Homebrew) ship it with [all] and so
|
||||
# `pip install hermes-agent[vision]` / the lazy-install path can resolve it.
|
||||
vision = ["Pillow==12.2.0"]
|
||||
# CVE-2026-48710 (BadHost): Starlette is pulled transitively by mcp's
|
||||
# sse-starlette / HTTP-SSE stack (and by fastapi in the `web` extra). Before
|
||||
# 1.0.1, a malformed Host header makes `request.url.path` desync from the path
|
||||
|
||||
Reference in New Issue
Block a user