fix(gateway): /stop can interrupt a sibling participant's run in a per-user thread - #35959
Merged
Conversation
…r-user thread
In a per-user thread (thread_sessions_per_user=True), each participant
gets an isolated session key (...:{thread_id}:{user_id}). A run another
user started lives under a different key, so the caller's own /stop found
nothing and replied 'no active task to stop'.
When /stop finds no run under the caller's own key, fall back to
interrupting any running agent(s) sharing the caller's thread prefix
({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the
fallback returns [] for non-thread channels, and a prefix-collision guard
prevents thr1 from matching thr11.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
1 |
First entries
tests/gateway/test_stop_thread_sibling.py:11: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
✅ Fixed issues: none
Unchanged: 4946 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
KKT-OPT
pushed a commit
to KKT-OPT/hermes-agent
that referenced
this pull request
May 31, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
alt-glitch
pushed a commit
that referenced
this pull request
Jun 14, 2026
…r-user thread (#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
kossteg
pushed a commit
to kossteg/hermes-agent
that referenced
this pull request
Jun 16, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
T02200059
pushed a commit
to T02200059/hermes-agent
that referenced
this pull request
Jun 18, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
donbowman
pushed a commit
to donbowman/hermes-agent
that referenced
this pull request
Jul 13, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…r-user thread (NousResearch#35959) In a per-user thread (thread_sessions_per_user=True), each participant gets an isolated session key (...:{thread_id}:{user_id}). A run another user started lives under a different key, so the caller's own /stop found nothing and replied 'no active task to stop'. When /stop finds no run under the caller's own key, fall back to interrupting any running agent(s) sharing the caller's thread prefix ({chat_id}:{thread_id}), gated on _is_user_authorized. Thread-only — the fallback returns [] for non-thread channels, and a prefix-collision guard prevents thr1 from matching thr11.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Authorized users can now
/stopa run another user started in the same thread. Previously, in a per-user thread (thread_sessions_per_user=True)/stoponly resolved to the caller's own session key, so a run started by a different participant was invisible and/stopreplied "no active task to stop".Root cause: per-user thread keys are
...:{thread_id}:{user_id}, so each participant is isolated._handle_stop_commandlooked up_running_agentsby the caller's own key only — no channel/thread-wide lookup existed.Changes
gateway/run.py: new_sibling_thread_run_keys(source, own_key)— finds running agents (not the pending sentinel, not the caller's own key) sharing the caller's{chat_id}:{thread_id}prefix._handle_stop_commandfalls back to interrupting those when the caller's own key has no run, gated on_is_user_authorized.tests/gateway/test_stop_thread_sibling.py: 7 tests covering the helper + the authorized/unauthorized fallback paths.Scope guards
[](the broader whole-channel case is intentionally untouched).thr1won't matchthr11._is_user_authorized, no new permission surface.Validation
/stopon a sibling's per-user-thread runTests:
tests/gateway/test_stop_thread_sibling.py7/7;test_command_bypass_active_session+test_session_race_guard+test_session_state_cleanup69/69 (no regression).Infographic