mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
fix(vision): mkdir converted-PNG output dir; wire SVG pass-through to rasterizer; AUTHOR_MAP for #52688
- _normalize_to_supported_image: ensure cache/vision exists before writing the converted PNG (fresh HERMES_HOME had no dir -> FileNotFoundError). - resolver: SVG passes through as image/svg+xml instead of erroring; the call sites rasterize to PNG via the salvaged normalize step (cairosvg / svglib / rsvg-convert / inkscape, best-effort with actionable error). - normalization offloaded via asyncio.to_thread at both call sites. - tests: resolver pass-through + rasterization + no-converter error paths. - AUTHOR_MAP: jonathan@mintrx.com -> JAlmanzarMint (PR #52688 salvage).
This commit is contained in:
parent
ac94f2c8a1
commit
4ac8c7546b
3 changed files with 41 additions and 4 deletions
|
|
@ -45,6 +45,7 @@ ACP_REGISTRY_MANIFEST = REPO_ROOT / "acp_registry" / "agent.json"
|
|||
|
||||
# Auto-extracted from noreply emails + manual overrides
|
||||
AUTHOR_MAP = {
|
||||
"jonathan@mintrx.com": "JAlmanzarMint", # PR #52688 salvage (vision: rasterize SVG / re-encode unsupported raster formats to PNG before embedding), folded into #57890
|
||||
"al3060388206@gmail.com": "ooiuuii", # PR #58466/#58377 salvage (redact: fireworks fw-/fpk_ prefixes; telegram: redact bot tokens out of transport error strings)
|
||||
"yingwaizhiying@gmail.com": "msh01", # PR #58250 salvage (telegram: wall-clock init timeout via daemon-thread deadline + abandon the shielded initialize task on timeout so the retry ladder advances instead of hanging on attempt 1/8 under s6 supervision; #58236). Also covers PR #58276 salvage (compression: preserve a real user turn after compaction; #55677).
|
||||
"danilo@falcao.org": "danilofalcao", # PR #56674 salvage (update: skip unsupported platform.matrix lazy refresh on native Windows — python-olm has no Windows wheel)
|
||||
|
|
|
|||
|
|
@ -223,3 +223,40 @@ class TestExecReadSafety:
|
|||
with pytest.raises(isrc.SourceNotFound):
|
||||
await isrc.resolve_image_source(
|
||||
"/workspace/nope.png", isrc.ResolveContext(task_id="t1"))
|
||||
|
||||
|
||||
class TestSvgNormalization:
|
||||
"""SVG resolves end-to-end: the resolver passes it through as
|
||||
image/svg+xml and the vision call sites rasterize it to PNG via
|
||||
_normalize_to_supported_image (PR #52688, folded in)."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_svg_rasterized_when_converter_available(self, tmp_path, monkeypatch):
|
||||
from tools import vision_tools as vt
|
||||
isrc = _reload(monkeypatch, tmp_path / "hermes")
|
||||
monkeypatch.setenv("TERMINAL_ENV", "local")
|
||||
svg = tmp_path / "art.svg"
|
||||
svg.write_bytes(b'<svg xmlns="http://www.w3.org/2000/svg" width="4" height="4"/>')
|
||||
|
||||
def fake_rasterize(svg_path, out_path):
|
||||
out_path.write_bytes(PNG)
|
||||
return True
|
||||
|
||||
with patch.object(vt, "_rasterize_svg_to_png", side_effect=fake_rasterize):
|
||||
res = await isrc.resolve_image_source(str(svg), isrc.ResolveContext())
|
||||
assert res.mime == "image/svg+xml"
|
||||
path, mime, err = vt._normalize_to_supported_image(svg, "image/svg+xml")
|
||||
assert err is None
|
||||
assert mime == "image/png"
|
||||
assert path.read_bytes() == PNG
|
||||
path.unlink()
|
||||
|
||||
def test_svg_actionable_error_when_no_converter(self, tmp_path, monkeypatch):
|
||||
from tools import vision_tools as vt
|
||||
_reload(monkeypatch, tmp_path / "hermes")
|
||||
svg = tmp_path / "art.svg"
|
||||
svg.write_bytes(b'<svg xmlns="http://www.w3.org/2000/svg"/>')
|
||||
with patch.object(vt, "_rasterize_svg_to_png", return_value=False):
|
||||
path, mime, err = vt._normalize_to_supported_image(svg, "image/svg+xml")
|
||||
assert path is None
|
||||
assert "rasterizer" in err
|
||||
|
|
|
|||
|
|
@ -316,10 +316,9 @@ def _normalize_to_supported_image(
|
|||
if detected_mime in _ANTHROPIC_SUPPORTED_MEDIA_TYPES:
|
||||
return image_path, detected_mime, None
|
||||
|
||||
out_path = (
|
||||
get_hermes_dir("cache/vision", "temp_vision_images")
|
||||
/ f"converted_{uuid.uuid4()}.png"
|
||||
)
|
||||
out_dir = get_hermes_dir("cache/vision", "temp_vision_images")
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
out_path = out_dir / f"converted_{uuid.uuid4()}.png"
|
||||
|
||||
# SVG: needs a rasterizer (Pillow cannot render SVG).
|
||||
if detected_mime == "image/svg+xml":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue