fix(gateway): fire MemoryProvider.on_session_end on session expiry#11410
Closed
zerone0x wants to merge 1 commit into
Closed
fix(gateway): fire MemoryProvider.on_session_end on session expiry#11410zerone0x wants to merge 1 commit into
zerone0x wants to merge 1 commit into
Conversation
The gateway's session-end paths (idle expiry, scheduled reset, /reset) all converge on _flush_memories_for_session, which spawned a bespoke flush AIAgent but never invoked MemoryProvider.on_session_end on the live cached agent's memory manager. Plugin providers that implement on_session_end as their final-pass extraction hook (per the ABC docstring) therefore never fired on gateway platforms. Dispatch the hook on the cached agent (looked up in _agent_cache, with a fallback to _running_agents when the agent is mid-turn) before the bespoke flush runs, mirroring the contract honored by the CLI graceful shutdown path in run_agent.shutdown_memory_provider. Wrapped in try/except so a misbehaving provider can't block the rest of the flush sequence. Fixes #11205
This was referenced Apr 22, 2026
Collaborator
Contributor
|
Thanks for this fix, @zerone0x — the root cause you identified was real. This PR is superseded by the
The PR's head is now This is an automated hermes-sweeper review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11205
The gateway session-expiry code path shut sessions down without invoking
MemoryProvider.on_session_end(), so memory providers never got a chance to flush state for expired sessions. This patch invokes the hook on the expiry path, mirroring the graceful-end behavior.What
_flush_memories_for_session(gateway/run.py:743) is the convergence point for all three gateway session-end paths:_session_expiry_watcher(:2046)/resetfrom a platform handler (:4343,:6422)Until now it only spawned a separate flush
AIAgentto nudge the builtin memory tool — it never calledmemory_manager.on_session_end(history)on the live cached agent's memory manager. As a result, pluginMemoryProviders that implementon_session_endas their documented final-pass extraction hook fired exactly zero times on gateway platforms (per the bug report log: manyperiodic/pre_compresstriggers, zerosession_end).This patch dispatches the hook before the bespoke flush runs, looking up the live agent in
_agent_cachefirst (where idle agents live) and falling back to_running_agents(in case the agent is still mid-turn when expiry fires). The dispatch is wrapped intry/exceptso a misbehaving provider can't block the rest of the flush sequence — matching the per-provider error tolerance that already exists insideMemoryManager.on_session_end.This is the same structural class of bug as #7193 / #7192: the hook contract exists, the dispatch layer works, but one caller was missing.
How
The bespoke flush-agent path is left fully intact (it addresses an orthogonal concern tracked in #6157).
Testing
New
tests/gateway/test_flush_memory_session_end.py(6 tests, all passing) covers:_agent_cache(idle path)_running_agents(mid-turn fallback)session_keypassed -> no cached-agent lookup, hook not calledExisting related tests (
test_async_memory_flush.py,test_flush_memory_stale_guard.py,test_memory_provider.py) continue to pass — 82/82 green.Test plan
on_session_end, let an idle session expire, confirm the log line now appears🤖 Generated with Claude Code