Skip to content

fix(honcho): flatten multimodal list content in sync_turn (#30252)#30264

Closed
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/honcho-sync-turn-multimodal-30252
Closed

fix(honcho): flatten multimodal list content in sync_turn (#30252)#30264
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/honcho-sync-turn-multimodal-30252

Conversation

@luyao618

Copy link
Copy Markdown
Contributor

Summary

Fixes #30252.

HonchoMemoryProvider.sync_turn previously passed user_content /
assistant_content straight into sanitize_context, which expects a
string. When the gateway forwarded an OpenAI vision-style multimodal
turn (content as a list of {type: text|image_url, ...} parts),
sanitize_context raised expected string or bytes-like object, got 'list'.
The exception was caught and logged at WARNING by the memory manager, so
the chat completion still succeeded — but the turn was silently dropped
from Honcho's memory and the user representation never learned about
anything visual the assistant was shown.

Fix

Add a small _flatten_content helper on HonchoMemoryProvider and call
it from sync_turn before sanitisation:

  • text / input_text / output_text parts contribute their text
    (non-string values coerced via str() so a malformed part can't crash
    "\n".join(...)).
  • image_url / input_image parts become a literal [image] marker so
    the Honcho turn still records that visuals were exchanged.
  • Other typed parts become [<type>]. Bare strings inside the list are
    kept; non-dict / non-str items are skipped.
  • Plain string callers are untouched — the helper returns its input
    unchanged when it isn't a list.

Scope

Per the issue's scope note, only the Honcho plugin is patched. Other
memory providers (mem0, supermemory, byterover, retaindb,
holographic, openviking) may share the same defect at their
sync_turn(user_content: str, ...) boundary but were not investigated
in this change.

Tests

New file tests/honcho_plugin/test_sync_turn_multimodal.py — 16 tests:

  • _flatten_content unit coverage: string passthrough, None,
    text+image_url flattening, input_text / output_text
    canonicalisation, non-string text coercion, input_image alias,
    unknown-type placeholder, empty list, bare strings inside lists,
    items missing type, non-dict/non-str items.
  • sync_turn integration: with a mocked _manager / session, passing
    list-shaped multimodal user_content no longer raises and the
    flattened text ("what colour is this?\n[image]") reaches the
    session; list-shaped assistant_content also works; plain string
    callers still produce the unchanged messages.
$ pytest tests/honcho_plugin/test_sync_turn_multimodal.py -q
................                                                         [100%]
16 passed in 0.09s

Checklist

  • Bugfix scoped to one plugin file + one new test file.
  • No behavior change for string callers.
  • New tests pass locally against the project venv.
  • Commit SSH-signed.

@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P3 Low — cosmetic, nice to have labels May 22, 2026
…ch#30252)

HonchoMemoryProvider.sync_turn previously passed user_content /
assistant_content straight into sanitize_context, which expects a
string. When the gateway forwarded an OpenAI vision-style multimodal
turn (`content` as a list of `{type: text|image_url, ...}` parts),
sanitize_context raised "expected string or bytes-like object, got
'list'". The exception was caught and logged at WARNING by the
memory manager, so the chat completion still succeeded — but the
turn was silently dropped from Honcho's memory, meaning the user
representation never learned about anything visual the assistant was
shown.

Add a _flatten_content helper that collapses list-shaped content
into a newline-joined string before sanitisation:

- text / input_text / output_text parts contribute their `text`
  (non-string values are coerced via str() so a malformed part can't
  crash the join).
- image_url / input_image parts become a literal '[image]' marker so
  the Honcho turn still records that visuals were exchanged.
- Other typed parts become '[<type>]'. Bare strings inside the list
  are kept; non-dict / non-str items are skipped.

Plain string callers are unaffected — _flatten_content returns the
input unchanged when it is not a list.

Scope kept to the Honcho plugin per the issue's scope note; other
memory providers (mem0, supermemory, byterover, etc.) may share the
same defect but were not investigated here.

Tests: tests/honcho_plugin/test_sync_turn_multimodal.py exercises
_flatten_content directly (string passthrough, multimodal flattening,
input_text/output_text canonicalisation, non-string text coercion,
unknown-type placeholder, empty list, bare strings, type-missing
items) plus an integration check on sync_turn with a mocked manager /
session that asserts list content no longer raises and the flattened
text reaches the session.
@luyao618 luyao618 force-pushed the fix/honcho-sync-turn-multimodal-30252 branch from af3ecae to 14ebb4f Compare May 27, 2026 11:04
@luyao618

Copy link
Copy Markdown
Contributor Author

Closing — open too long, no longer relevant.

@luyao618 luyao618 closed this May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

honcho memory: sync_turn fails on multimodal (list) content — vision turns not recorded

2 participants