mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
fix(gateway): send /new response before cancel_session_processing to avoid race (#18912)
When /new is issued while an agent is actively processing, the confirmation response was never sent to the user because cancel_session_processing() was called before _send_with_retry(). Task cancellation side effects could silently drop the response. Fix: reorder to send the response BEFORE cancelling the old task. Add logging at the send point (matching the pattern at line 2800 in _process_message_background) so future failures are visible. Closes: #18912
This commit is contained in:
parent
bf3239472f
commit
934103476f
1 changed files with 19 additions and 7 deletions
|
|
@ -2489,15 +2489,20 @@ class BasePlatformAdapter(ABC):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = await self._message_handler(event)
|
response = await self._message_handler(event)
|
||||||
# Old adapter task (if any) is cancelled AFTER the runner has
|
|
||||||
# fully handled the command — keeps ordering deterministic.
|
|
||||||
await self.cancel_session_processing(
|
|
||||||
session_key,
|
|
||||||
release_guard=False,
|
|
||||||
discard_pending=False,
|
|
||||||
)
|
|
||||||
_text, _eph_ttl = self._unwrap_ephemeral(response)
|
_text, _eph_ttl = self._unwrap_ephemeral(response)
|
||||||
|
# Send the response BEFORE cancelling the old task so the send
|
||||||
|
# cannot be affected by task-cancellation side effects (race
|
||||||
|
# condition fix — issue #18912). Previously the send happened
|
||||||
|
# after cancel_session_processing, which could silently drop the
|
||||||
|
# "/new" confirmation when an agent was actively running.
|
||||||
if _text:
|
if _text:
|
||||||
|
logger.info(
|
||||||
|
"[%s] Sending command '/%s' response (%d chars) to %s",
|
||||||
|
self.name,
|
||||||
|
cmd,
|
||||||
|
len(_text),
|
||||||
|
event.source.chat_id,
|
||||||
|
)
|
||||||
_r = await self._send_with_retry(
|
_r = await self._send_with_retry(
|
||||||
chat_id=event.source.chat_id,
|
chat_id=event.source.chat_id,
|
||||||
content=_text,
|
content=_text,
|
||||||
|
|
@ -2510,6 +2515,13 @@ class BasePlatformAdapter(ABC):
|
||||||
message_id=_r.message_id,
|
message_id=_r.message_id,
|
||||||
ttl_seconds=_eph_ttl,
|
ttl_seconds=_eph_ttl,
|
||||||
)
|
)
|
||||||
|
# Old adapter task (if any) is cancelled AFTER the response has
|
||||||
|
# been sent — keeps ordering deterministic and avoids the race.
|
||||||
|
await self.cancel_session_processing(
|
||||||
|
session_key,
|
||||||
|
release_guard=False,
|
||||||
|
discard_pending=False,
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
# On failure, restore the original guard if one still exists so
|
# On failure, restore the original guard if one still exists so
|
||||||
# we don't leave the session in a half-reset state.
|
# we don't leave the session in a half-reset state.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue