Skip to content

fix(delegation): preserve parent session identity across child runs - #75856

Merged
teknium1 merged 1 commit into
mainfrom
salvage/pr74858-parent-session-id
Aug 1, 2026
Merged

fix(delegation): preserve parent session identity across child runs#75856
teknium1 merged 1 commit into
mainfrom
salvage/pr74858-parent-session-id

Conversation

@teknium1

@teknium1 teknium1 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Delegated child agents no longer clobber the parent's session identity: set_current_session_id() now suppresses ContextVar/env writes while a delegated-child scope is active, and delegated_child_context() saves and restores the parent id around the child run.

Root cause: child AIAgent() construction happens on the parent thread, and agent init unconditionally calls set_current_session_id(child.session_id) — which writes both the ContextVar and process-global HERMES_SESSION_ID. Main's own comment in tools/delegate_tool.py documents the clobber but only works around it for the async wake-sid; every parent subprocess spawned after a delegation carried the last child's identity.

The guard lives at the helper level so single, batch, and nested delegation are all covered; child subprocesses still receive the correct child id via the existing scoped context bridge.

Salvaged from #74858 by @Xipong with authorship preserved (1 commit cherry-picked onto current main).

Changes

  • gateway/session_context.py: delegation-scope guard in set_current_session_id(); save/restore in the delegated-child scope.
  • tools/delegate_tool.py: use the scoped context at the child construction site.
  • tests/gateway/test_delegation_session_id_leak.py: single/nested/concurrent regression tests using real build_subprocess_env.

Validation

Result
tests/gateway/test_delegation_session_id_leak.py 7/7 pass
tests/gateway/test_session_context_inheritance.py 2/2 pass
Parent subprocess after delegation carries parent id (was: last child's id)

Infographic

parent session identity preserved

…cess env

AIAgent.__init__ calls set_current_session_id(self.session_id), which
mutated both the task-local ContextVar and the process-global os.environ.
Because _build_child_agent wraps construction in delegated_child_context(),
the ContextVar write is harmless (task-local), but the os.environ write
clobbered the parent's HERMES_SESSION_ID for the rest of the process —
leaking the child id into parent tools and subprocesses spawned after
the child was built.

Root cause of HermesPRDelegationSessionContext: parent
20260729_212118_5d797e dispatched child 20260730_160515_736ea1; later
parent terminal inherited HERMES_SESSION_ID=the child.

Fix: set_current_session_id() skips the process-global os.environ write
when called from within a delegated_child_context(). The child's own
tools and subprocesses still resolve their id through the ContextVar
(task-local), while the parent's process-wide env keeps the parent's
session identity. Root agents (CLI, gateway, cron) retain both paths.

Adds 7 regression tests covering single child, concurrent children (8
parallel), parent-tool observation after construction, and root-agent
session rotation backward compatibility. All pass; ruff clean.
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on abf34d0

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

2 visual diffs.

inline evidence upload failed.

Failed to upload diff-1508682a2ae8-boot-ready-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-1508682a2ae8-boot-ready-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso)

@teknium1 teknium1 added the area/sessions Session lifecycle, resume, persistence, history label Aug 1, 2026
@teknium1
teknium1 merged commit 0af8fb0 into main Aug 1, 2026
39 checks passed
@teknium1
teknium1 deleted the salvage/pr74858-parent-session-id branch August 1, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants