Multi-Session Threads For Telegram - #237
Open
tamircher wants to merge 1 commit into
Open
Conversation
Each Telegram topic already gets its own session and the runner keeps independent per-thread serial queues (threadQueues), but the handler gated every incoming message on the global isMainBusy() — any in-flight run anywhere blocked all topics. Add per-thread busy tracking in the runner (isThreadBusy/isGlobalBusy) and check only the target topic's queue (or the global session for non-topic chats), so each topic is a fully independent session running in parallel. A second message to the same topic still gets the polite busy reply.
TerrysPOV
requested changes
Jun 28, 2026
TerrysPOV
left a comment
Collaborator
There was a problem hiding this comment.
Code review
Found 1 issue:
/killbecomes a cross-topic footgun once parallel topics are enabled.killActive()iterates the globalmainActiveProcsset and SIGTERMs every entry — before this PR that set could only ever hold one proc, so kill-all was kill-mine. After this PR, a/killissued from topic A also terminates the in-flight Claude run in topics B, C, etc. Codex flagged this exact concern on PR #184 ("Track active subprocesses per task before exposing /kill") — the Set was added then, butkillActivewas never made thread-aware.
killActive is global:
Lines 283 to 295 in fc2b9f6
Telegram /kill handler invokes it without scoping to the caller's topic:
claudeclaw/src/commands/telegram.ts
Lines 1148 to 1153 in fc2b9f6
Quickest fix: track procs per-thread (e.g. Map<string | "__global__", Set<Proc>> keyed on threadId from the execClaude call site) and have killActive(threadId) only iterate its own bucket. Telegram handler passes the message's sessionKey.
Also missing the mandatory plugin + marketplace version bumps (.claude-plugin/plugin.json and .claude-plugin/marketplace.json). I can maintainer-commit those once the killActive fix lands.
This was referenced Jul 19, 2026
tbertran
added a commit
to tbertran/claudeclaw
that referenced
this pull request
Jul 19, 2026
killActive() terminates every in-flight main run across all channels and threads. Matches Telegram's existing contract (moazbuilds#184), not a regression; thread-scoped kill tracked separately (moazbuilds#237). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Each Telegram topic already gets its own session, and the runner keeps independent per-thread serial queues (
threadQueues) — but the Telegram handler gates every incoming message on the globalisMainBusy(), so any in-flight run anywhere blocks all topics.This PR adds per-thread busy tracking in the runner (
isThreadBusy/isGlobalBusy) and checks only the target topic's queue (or the global session for non-topic chats). Each topic becomes a fully independent session running in parallel; a second message to the same topic still gets the polite busy reply.Changes
src/runner.ts: per-thread busy set + global counter, maintained inexecClaude's entry/finally alongsidemainRunCountsrc/commands/telegram.ts: busy check scoped to the message'ssessionKeyinstead of global🤖 Generated with Claude Code