Skip to content

fix: handle list content in _serialize_for_summary for multimodal messages - #59994

Closed
AlexFucuson9 wants to merge 1 commit into
NousResearch:mainfrom
AlexFucuson9:fix/context-compressor-multimodal-crash
Closed

AlexFucuson9 wants to merge 1 commit into
NousResearch:mainfrom
AlexFucuson9:fix/context-compressor-multimodal-crash

Conversation

@AlexFucuson9

Copy link
Copy Markdown
Contributor

Summary

Fix AttributeError crash in _serialize_for_summary when a message has multimodal (list) content — e.g. user sends an image + text.

Problem

agent/context_compressor.py:1416msg.get("content") can return a list of content parts for multimodal messages (images, text, etc.). The code passed this list directly to redact_sensitive_text(text: str), which calls .replace() on its argument. A list has no .replace() method, so this raises AttributeError, causing context compression to fail entirely.

When compression fails, the session context grows unchecked until the provider rejects the request or the session becomes unusable.

Reproduction: Send a message with an attached image (e.g. via Telegram, Discord, or the dashboard) in a session with context compression enabled. When the compressor runs, it crashes on the multimodal message.

Fix

Detect isinstance(content, list) before calling redact_sensitive_text and extract text/image placeholders from the parts list:

  • {"type": "text", "text": "..."} → extracted as-is
  • {"type": "image_url"|"image"|"input_image"} → replaced with [image]
  • bare strings → joined as-is

This follows the same pattern used in tool_dispatch_helpers.py and conversation_compression.py for handling multimodal content.

Testing

3 new tests in tests/agent/test_compressor_media_stripping.py:

  • Multimodal list with text + image_url parts (does not crash)
  • Multimodal list with multiple text parts (preserved in output)
  • Bare string list (joined correctly)

…sages

msg.get('content') can return a list of parts for multimodal messages
(containing text, images, etc.). The old code passed this list directly
to redact_sensitive_text(text: str), which raised AttributeError on
list.replace(), causing context compression to fail entirely for any
session with attached images.

Fix: detect list content and extract text parts before redacting.
Image parts are replaced with '[image]' placeholder.
@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 duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists labels Jul 7, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Duplicate of #32390 (@sontianye, opened 2026-05-26) — same fix at the same code site: context_compressor.py::_serialize_for_summary passing multimodal list content to redact_sensitive_text, resolved by detecting isinstance(content, list), extracting text parts, and appending an image placeholder. #32390 is the earlier open PR and is canonical. (Prior attempts #6916/#7857/#14395 are closed.)

@teknium1

Copy link
Copy Markdown
Collaborator

Merged via PR #65046 with your commit cherry-picked onto current main — authorship preserved (8141a35). Note: the original crash premise turned out stale (redact_sensitive_text grew str() coercion in #52147, after your branch point) — but that coercion made your fix MORE valuable, not less: without flattening, the str() path dumps raw part-dict repr including base64 image data into the summarizer input. Your flattening fixes that. Follow-ups on top: remote http(s) image parts keep an '[image: ]' handle so the reference survives compaction, and unknown part types keep a '[]' marker instead of being dropped. Thanks for both contributions in this cluster.

@teknium1 teknium1 closed this Jul 15, 2026
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 duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants