mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(gateway): replace os.environ session state with contextvars for concurrency safety
When two gateway messages arrived concurrently, _set_session_env wrote HERMES_SESSION_PLATFORM/CHAT_ID/CHAT_NAME/THREAD_ID into the process-global os.environ. Because asyncio tasks share the same process, Message B would overwrite Message A's values mid-flight, causing background-task notifications and tool calls to route to the wrong thread/chat. Replace os.environ with Python's contextvars.ContextVar. Each asyncio task (and any run_in_executor thread it spawns) gets its own copy, so concurrent messages never interfere. Changes: - New gateway/session_context.py with ContextVar definitions, set/clear/get helpers, and os.environ fallback for CLI/cron/test backward compatibility - gateway/run.py: _set_session_env returns reset tokens, _clear_session_env accepts them for proper cleanup in finally blocks - All tool consumers updated: cronjob_tools, send_message_tool, skills_tool, terminal_tool (both notify_on_complete AND check_interval blocks), tts_tool, agent/skill_utils, agent/prompt_builder - Tests updated for new contextvar-based API Fixes #7358 Co-authored-by: teknium1 <127238744+teknium1@users.noreply.github.com>
This commit is contained in:
parent
dab5ec8245
commit
e8034e2f6a
10 changed files with 255 additions and 52 deletions
|
|
@ -1420,10 +1420,11 @@ def terminal_tool(
|
|||
# In gateway mode, auto-register a fast watcher so the
|
||||
# gateway can detect completion and trigger a new agent
|
||||
# turn. CLI mode uses the completion_queue directly.
|
||||
_gw_platform = os.getenv("HERMES_SESSION_PLATFORM", "")
|
||||
from gateway.session_context import get_session_env as _gse
|
||||
_gw_platform = _gse("HERMES_SESSION_PLATFORM", "")
|
||||
if _gw_platform and not check_interval:
|
||||
_gw_chat_id = os.getenv("HERMES_SESSION_CHAT_ID", "")
|
||||
_gw_thread_id = os.getenv("HERMES_SESSION_THREAD_ID", "")
|
||||
_gw_chat_id = _gse("HERMES_SESSION_CHAT_ID", "")
|
||||
_gw_thread_id = _gse("HERMES_SESSION_THREAD_ID", "")
|
||||
proc_session.watcher_platform = _gw_platform
|
||||
proc_session.watcher_chat_id = _gw_chat_id
|
||||
proc_session.watcher_thread_id = _gw_thread_id
|
||||
|
|
@ -1445,9 +1446,10 @@ def terminal_tool(
|
|||
result_data["check_interval_note"] = (
|
||||
f"Requested {check_interval}s raised to minimum 30s"
|
||||
)
|
||||
watcher_platform = os.getenv("HERMES_SESSION_PLATFORM", "")
|
||||
watcher_chat_id = os.getenv("HERMES_SESSION_CHAT_ID", "")
|
||||
watcher_thread_id = os.getenv("HERMES_SESSION_THREAD_ID", "")
|
||||
from gateway.session_context import get_session_env as _gse2
|
||||
watcher_platform = _gse2("HERMES_SESSION_PLATFORM", "")
|
||||
watcher_chat_id = _gse2("HERMES_SESSION_CHAT_ID", "")
|
||||
watcher_thread_id = _gse2("HERMES_SESSION_THREAD_ID", "")
|
||||
|
||||
# Store on session for checkpoint persistence
|
||||
proc_session.watcher_platform = watcher_platform
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue