Skip to content

fix(honcho): dedupe repeated message flushes - #18536

Closed
erosika wants to merge 1 commit into
NousResearch:mainfrom
erosika:fix/honcho-skip-synthetic-sync
Closed

fix(honcho): dedupe repeated message flushes#18536
erosika wants to merge 1 commit into
NousResearch:mainfrom
erosika:fix/honcho-skip-synthetic-sync

Conversation

@erosika

@erosika erosika commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add bounded per-session batch fingerprints inside the Honcho session manager
  • skip repeated Honcho uploads from stale async queue/retry/session-end flush paths after a successful sync
  • keep the fix scoped to the Honcho plugin only

Test Plan

  • scripts/run_tests.sh tests/honcho_plugin/test_honcho_idempotency.py tests/honcho_plugin/test_session.py::TestConcludeToolDispatch::test_sync_turn_strips_leaked_memory_context_before_honcho_ingest tests/honcho_plugin/test_async_memory.py -q

@erosika
erosika force-pushed the fix/honcho-skip-synthetic-sync branch from 8bb5f4a to 802ec88 Compare May 1, 2026 19:52
@erosika erosika changed the title fix(honcho): skip synthetic review turn sync fix(honcho): dedupe repeated message flushes May 1, 2026
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins labels May 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Implements part of #9404. Related to #17153 (gateway-restart dedup). This adds batch fingerprint dedup for async/retry/session-end flush paths.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Implements part of #9404

@erosika
erosika force-pushed the fix/honcho-skip-synthetic-sync branch from 802ec88 to 237a499 Compare May 21, 2026 16:02

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for narrowing the change to the Honcho plugin. The duplicate-ingest problem remains present on current main: plugins/memory/honcho/session.py:440-446 creates and uploads messages from content alone, with no stable Hermes source-event identity.

Problems

  • The new guard at plugins/memory/honcho/session.py:385 treats an equal role/content batch as a replay. That drops legitimate repeated turns; the #9404 discussion explicitly requires repeated content from distinct source events to remain ingestible.
  • The check and record operations at plugins/memory/honcho/session.py:385 and :399 are not synchronized. Current main can call _flush_session() via the async writer (session.py:471), flush_all() (session.py:534,544), and the background sync_turn() path (__init__.py:1232-1248), so two callers can both pass the check before either records the fingerprint.

Suggested changes

  • Re-scope deduplication around stable Hermes source-event identifiers plus chunk identity, with an atomic claim/commit protocol.
  • Test replay of one source event separately from two equal-content turns, and cover concurrent flush entry points.

Automated hermes-sweeper review.

session.key, (set(), deque())
)
batch_fp = _batch_fingerprint(new_messages)
if batch_fp in recent_set:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This key contains only roles and content, so it cannot distinguish a retry from a later legitimate turn with the same text. #9404 requires source-event idempotency while preserving repeated messages; please key this on stable Hermes event/turn and chunk identity instead.

honcho_session.add_messages(honcho_messages)
for msg in new_messages:
msg["_synced"] = True
recent_set.add(batch_fp)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recording the fingerprint only after add_messages() and without synchronization leaves a check-then-act race: concurrent async/session-end flushes can both pass the earlier membership test and upload the same batch. Use an atomic per-event claim/commit protocol with rollback on failed upload.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
@erosika erosika closed this Jul 13, 2026
@teknium1 teknium1 added the area/memory Memory subsystem: store, providers, sync, background reviews label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/memory Memory subsystem: store, providers, sync, background reviews comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants