mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-23 10:42:00 +00:00
fix(openviking): close session-boundary races on sync_turn and on_session_end
Two hardening fixes prompted by review on #28296:
1. sync_turn() now snapshots the target session id before spawning the
worker. The previous code read self._session_id inside the worker, so
a worker delayed past on_session_switch's bounded join could read the
rotated-in NEW id and write the OLD turn's messages into the wrong
session.
2. on_session_end() resets _turn_count to 0 after a successful commit,
making the old-session commit path idempotent with the new switch
hook. /new and compression call commit_memory_session() (which fires
on_session_end) immediately before on_session_switch; without this,
the old session would be committed twice. On commit failure we leave
_turn_count > 0 so on_session_switch retries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 2ea8d5c537)
This commit is contained in:
parent
813a4e3838
commit
a30b40c73a
2 changed files with 120 additions and 1 deletions
|
|
@ -589,6 +589,14 @@ class OpenVikingMemoryProvider(MemoryProvider):
|
|||
if not user_content:
|
||||
return
|
||||
|
||||
# Capture the target session id NOW, not inside the worker. Otherwise
|
||||
# a delayed worker can read self._session_id after on_session_switch
|
||||
# has rotated it (the switch's join on _sync_thread is bounded), and
|
||||
# the OLD turn's content lands in the NEW session.
|
||||
sid = str(session_id or self._session_id).strip()
|
||||
if not sid:
|
||||
return
|
||||
|
||||
self._turn_count += 1
|
||||
|
||||
def _sync():
|
||||
|
|
@ -597,7 +605,6 @@ class OpenVikingMemoryProvider(MemoryProvider):
|
|||
self._endpoint, self._api_key,
|
||||
account=self._account, user=self._user, agent=self._agent,
|
||||
)
|
||||
sid = self._session_id
|
||||
|
||||
# Add user message
|
||||
client.post(f"/api/v1/sessions/{sid}/messages", {
|
||||
|
|
@ -642,6 +649,11 @@ class OpenVikingMemoryProvider(MemoryProvider):
|
|||
try:
|
||||
self._client.post(f"/api/v1/sessions/{self._session_id}/commit")
|
||||
logger.info("OpenViking session %s committed (%d turns)", self._session_id, self._turn_count)
|
||||
# Mark the session clean so a subsequent on_session_switch (fired
|
||||
# by /new and compression right after commit_memory_session) skips
|
||||
# its commit instead of double-committing. On commit failure we
|
||||
# leave the count intact so the switch hook gets a retry.
|
||||
self._turn_count = 0
|
||||
except Exception as e:
|
||||
logger.warning("OpenViking session commit failed: %s", e)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue