Skip to content

fix(gateway): auto-deliver image_generate output as native media#42616

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-2f0cbb89
Jun 9, 2026
Merged

fix(gateway): auto-deliver image_generate output as native media#42616
teknium1 merged 1 commit into
mainfrom
hermes/hermes-2f0cbb89

Conversation

@teknium1

@teknium1 teknium1 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Generated images now deliver natively on every gateway platform (WhatsApp, Telegram, Signal, …) without depending on the model restating the file path.

image_generate returns its artifact as a JSON payload ({"success": true, "image": "/abs/path.png"}) with no MEDIA: tag. The gateway's auto-append path only recognized literal MEDIA: tags from text_to_speech, so image delivery silently relied on the model echoing the path into its reply. When it didn't, the image was dropped.

Changes

  • gateway/run.py: add image_generate to _AUTO_APPEND_MEDIA_TOOL_NAMES; the auto-append scanner now extracts the local-file path from the tool's JSON result (host_imageimageagent_visible_image, first deliverable wins) and synthesizes a MEDIA: tag. Reuses the existing extension-anchored _TOOL_MEDIA_RE and history-dedupe set, so remote URLs, unknown extensions, failed generations, and already-delivered paths are all rejected.
  • tests/gateway/test_media_extraction.py: 4 new tests — JSON path delivery, host-path preference, failure/URL rejection, history dedupe.

Validation

Case Result
image_generate JSON → MEDIA:/path delivered
host vs sandbox path host path wins
success: false / remote URL / unknown ext not delivered
path already in history not re-sent (no dupes)
existing text_to_speech MEDIA: path unchanged

tests/gateway/test_media_extraction.py test_platform_base.py test_stream_consumer.py test_tts_media_routing.py → 262 passed.

Closes the one path from #19105 not already covered by the WhatsApp native-media work on main. The other four paths in that issue (WhatsApp send_message MEDIA:, native image/video/audio bridge sends, inbound video paths, history dedupe) were independently implemented since the issue was filed; PR #19106 (@hedirman) was closed in favor of that work with credit.

Infographic

auto-deliver-generated-media

image_generate returns its artifact as JSON ({"image": "/abs/path.png"})
with no MEDIA: tag, so the gateway auto-append path (which only recognized
text_to_speech MEDIA: tags) never delivered it — image delivery silently
depended on the model restating the path in its reply. Add image_generate to
the producer allowlist and extract the local path from its JSON result
(host_image > image > agent_visible_image), reusing the existing
extension-anchored matcher and history-dedupe so remote URLs, unknown
extensions, failures, and already-sent paths are rejected.

Closes the remaining unfixed path from #19105.
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-2f0cbb89 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10569 on HEAD, 10569 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5557 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1 teknium1 merged commit 9351cba into main Jun 9, 2026
23 checks passed
@teknium1 teknium1 deleted the hermes/hermes-2f0cbb89 branch June 9, 2026 05:51
a249169329-cpu pushed a commit to a249169329-cpu/hermes-agent that referenced this pull request Jun 9, 2026
…sResearch#42616)

image_generate returns its artifact as JSON ({"image": "/abs/path.png"})
with no MEDIA: tag, so the gateway auto-append path (which only recognized
text_to_speech MEDIA: tags) never delivered it — image delivery silently
depended on the model restating the path in its reply. Add image_generate to
the producer allowlist and extract the local path from its JSON result
(host_image > image > agent_visible_image), reusing the existing
extension-anchored matcher and history-dedupe so remote URLs, unknown
extensions, failures, and already-sent paths are rejected.

Closes the remaining unfixed path from NousResearch#19105.
wachoo pushed a commit to wachoo/hermes-agent that referenced this pull request Jun 10, 2026
…sResearch#42616)

image_generate returns its artifact as JSON ({"image": "/abs/path.png"})
with no MEDIA: tag, so the gateway auto-append path (which only recognized
text_to_speech MEDIA: tags) never delivered it — image delivery silently
depended on the model restating the path in its reply. Add image_generate to
the producer allowlist and extract the local path from its JSON result
(host_image > image > agent_visible_image), reusing the existing
extension-anchored matcher and history-dedupe so remote URLs, unknown
extensions, failures, and already-sent paths are rejected.

Closes the remaining unfixed path from NousResearch#19105.
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
…sResearch#42616)

image_generate returns its artifact as JSON ({"image": "/abs/path.png"})
with no MEDIA: tag, so the gateway auto-append path (which only recognized
text_to_speech MEDIA: tags) never delivered it — image delivery silently
depended on the model restating the path in its reply. Add image_generate to
the producer allowlist and extract the local path from its JSON result
(host_image > image > agent_visible_image), reusing the existing
extension-anchored matcher and history-dedupe so remote URLs, unknown
extensions, failures, and already-sent paths are rejected.

Closes the remaining unfixed path from NousResearch#19105.
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
)

image_generate returns its artifact as JSON ({"image": "/abs/path.png"})
with no MEDIA: tag, so the gateway auto-append path (which only recognized
text_to_speech MEDIA: tags) never delivered it — image delivery silently
depended on the model restating the path in its reply. Add image_generate to
the producer allowlist and extract the local path from its JSON result
(host_image > image > agent_visible_image), reusing the existing
extension-anchored matcher and history-dedupe so remote URLs, unknown
extensions, failures, and already-sent paths are rejected.

Closes the remaining unfixed path from #19105.
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.

2 participants