fix(kanban): forward session context vars into worker subprocess env - #57356
fix(kanban): forward session context vars into worker subprocess env#57356wernerhp wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes kanban worker subprocesses spawned by hermes_cli.kanban_db._default_spawn not inheriting the gateway session ContextVar state (e.g., HERMES_SESSION_PLATFORM, HERMES_SESSION_CHAT_ID, HERMES_SESSION_THREAD_ID), which previously caused worker send_message calls to lose thread targeting and post as new root messages.
Changes:
- Add
build_session_subprocess_env()ingateway/session_context.pyto overlay sessionContextVarvalues into a subprocess environment. - Update
hermes_cli/kanban_db.py::_default_spawnto usebuild_session_subprocess_env(dict(os.environ))when available, with a fallback for non-gateway contexts.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
gateway/session_context.py |
Introduces a helper to construct subprocess envs that include session ContextVar state. |
hermes_cli/kanban_db.py |
Uses the helper during kanban worker spawn to preserve originating platform/chat/thread context. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for tracing the ContextVar/subprocess boundary. Current main still has the raw-environment gap at Problems
Suggested changes
This is an automated hermes-sweeper review. |
ce20649 to
98388fd
Compare
|
Both review findings are addressed:
|
Kanban workers spawned by _default_spawn inherit os.environ but not the gateway's ContextVar session state (HERMES_SESSION_PLATFORM/CHAT_ID/ THREAD_ID). Workers therefore have no originating thread context, causing send_message calls to post as new root messages instead of replying in the correct thread. Add build_session_subprocess_env() to gateway/session_context.py (mirrors the approach in upstream PR NousResearch#45940). Overlay the current ContextVar values onto the base env dict before handing it to Popen. The try/except ImportError guard keeps the standalone CLI and test environments working unchanged. Workers now inherit HERMES_SESSION_PLATFORM, HERMES_SESSION_CHAT_ID, and HERMES_SESSION_THREAD_ID, enabling send_message to auto-target the originating Mattermost/Telegram/Discord thread without requiring the thread_id to be baked into the kanban brief.
… forwarding Addresses reviewer findings on PR NousResearch#57356: - send_message with no explicit target now falls back to the forwarded origin session (HERMES_SESSION_PLATFORM/CHAT_ID/THREAD_ID) instead of rejecting outright, without overriding an explicit target. - build_session_subprocess_env now forwards only the narrow routing set (platform, chat_id, thread_id) instead of all HERMES_SESSION_* vars. Adds regression tests for both: rejection when no target and no origin, fallback to origin when target omitted, explicit target takes priority, and the narrowed subprocess-env forwarding set.
… narrow import guard - build_session_subprocess_env: default base_env to os.environ when caller omits it, and stop the per-var os.environ fallback from overriding an explicitly-supplied base_env value (explicit base_env is authoritative). - _default_spawn: narrow the ImportError guard around the gateway.session_context import to ModuleNotFoundError so a real regression inside the module propagates instead of being silently swallowed. - Add regression tests pinning both fixes.
af475b0 to
502d15c
Compare
…sion-env Semantic conflict in hermes_cli/kanban_db.py _default_spawn(): upstream main 148497f (salvaged from NousResearch#69181) STRIPS every _VAR_MAP session-routing key from the dispatched worker env, directly superseding this PR's approach of FORWARDING HERMES_SESSION_* via build_session_subprocess_env. A detached worker that inherits routing auto-subscribes child tasks to an unrelated chat, so the strip is the shipped, correct behavior. Resolved by taking main's strip; the PR's _SUBPROCESS_FORWARD_VARS is a subset of _VAR_MAP so nothing new leaks. send_message_tool.py origin-fallback and build_session_subprocess_env remain (merged clean) — harmless when the env vars are absent.
# Conflicts: # tests/gateway/test_session_env.py # tests/tools/test_send_message_tool.py
|
Closing as superseded by The underlying concern (a detached kanban worker inheriting a previous gateway turn's # hermes_cli/kanban_db.py, worker spawn env
from gateway.session_context import _VAR_MAP
for key in _VAR_MAP:
env.pop(key, None)This PR's If per-task routing forwarding is still wanted, an explicit opt-in on the task, layered on top of the default isolation, would be the safer shape than a blanket inherit at spawn. |
What does this PR do?
Kanban workers spawned by
_default_spawninheritos.environbut not the gateway'sContextVarsession state (HERMES_SESSION_PLATFORM,HERMES_SESSION_CHAT_ID,HERMES_SESSION_THREAD_ID). Workers therefore have no originating thread context --send_messagecalls land as new root posts instead of replying in the correct thread.Fix: add
build_session_subprocess_env()togateway/session_context.pyand use it in_default_spawnto overlay ContextVar values onto the worker's env beforePopen. The existingexcept ImportErrorguard keeps the standalone CLI and test environments working unchanged.Workers now inherit the originating platform/chat/thread, enabling
send_messageto auto-target the correct thread without requiring the thread_id to be baked into the kanban task brief.Related Issue
Relates to #45940 (same root cause, complementary fix -- that PR adds
build_session_subprocess_env()+ explicit--subscribe-*CLI flags; this PR wires the helper into_default_spawn). Also related to #56781 (addresses the notification delivery side of the same dispatch gap).Type of Change
Changes Made
gateway/session_context.py: addbuild_session_subprocess_env(base_env)-- builds a subprocess env dict with ContextVar session values overlaid on top of os.environ (or a provided base).hermes_cli/kanban_db.py:_default_spawncallsbuild_session_subprocess_env(dict(os.environ))instead ofdict(os.environ)directly; falls back todict(os.environ)onImportErrorfor CLI/test safety.How to Test
send_messagein its worker.Checklist