Skip to content

fix(agent): preserve multimodal user content through crash-resilience persist - #47907

Merged
teknium1 merged 2 commits into
mainfrom
hermes/fix-multimodal-persist-clobber
Jun 17, 2026
Merged

fix(agent): preserve multimodal user content through crash-resilience persist#47907
teknium1 merged 2 commits into
mainfrom
hermes/fix-multimodal-persist-clobber

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Images attached to a user turn now survive to the model call instead of being silently dropped before the API request is built.

Root cause: _apply_persist_user_message_override unconditionally overwrote the current-turn user message content with the text-only persist string. build_turn_context runs a crash-resilience persist of the inbound turn before the first API call, on the same messages list the request is later built from — so a multimodal [text, image_url] user turn got clobbered to plain text, and the image was gone end-to-end. This hits every provider regardless of vision support: ACP session/prompt image blocks (#44242) and Telegram native-vision image attachments alike.

Changes

  • run_agent.py: skip the content override when the user message content is a multimodal list; the paired timestamp override still applies (it's metadata, not content).
  • tests/run_agent/test_run_agent.py: regression tests for the multimodal-preserved and text-rewritten paths.
  • scripts/release.py: AUTHOR_MAP entry for the salvaged contributor.

Validation

case before after
multimodal turn + text persist override content → plain string, image dropped content list preserved, image survives, timestamp written
text turn + persist override clean string written clean string written (unchanged)
multimodal + timestamp-only n/a list intact, timestamp written

Targeted suite: tests/run_agent/test_run_agent.py -k "persist_user_message or persist_session" → 5 passed. E2E against the real method confirms all three cases.

Credit

Salvaged from #44249 by @Rivuza (authorship preserved via rebase-merge). #44247 by @liuhao1024 submitted the same one-line fix first — both contributors credited. Adapted the guard so it doesn't regress the timestamp-metadata write that landed after both PRs were filed. Closes #44242.

Infographic

Multimodal persist fix

Rivuza and others added 2 commits June 17, 2026 07:25
Avoid applying text-only persist_user_message overrides to multimodal current-turn user messages. Early crash-resilience persistence mutates the same messages list later used for the API call, so clobbering list content drops ACP image blocks before model dispatch.\n\nAdd regression coverage for both text override behavior and multimodal preservation.\n\nCloses #44242
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/fix-multimodal-persist-clobber 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: 10993 on HEAD, 10995 on base (✅ -2)

🆕 New issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

✅ Fixed issues (2):

Rule Count
unresolved-attribute 2
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:2933: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`

Unchanged: 5790 pre-existing issues carried over.

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

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/vision Vision analysis and image generation P2 Medium — degraded but workaround exists labels Jun 17, 2026
@teknium1
teknium1 merged commit cc9f37e into main Jun 17, 2026
35 checks passed
@teknium1
teknium1 deleted the hermes/fix-multimodal-persist-clobber branch June 17, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists tool/vision Vision analysis and image generation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACP image content blocks dropped before API call (persist_user_message override clobbers multimodal content)

3 participants