feat: show subagent activity on every chat platform - #369
Open
raullopez-sandbox wants to merge 3 commits into
Open
feat: show subagent activity on every chat platform#369raullopez-sandbox wants to merge 3 commits into
raullopez-sandbox wants to merge 3 commits into
Conversation
raullopez-sandbox
requested review from
amaudruz and
christian-mcdermott
as code owners
September 4, 2026 08:15
raullopez-sandbox
added a commit
that referenced
this pull request
Sep 4, 2026
…te reporting
Completes CHOO-2555 agent-side implementation. Detects Agent tool calls via
hooks, tracks subagent lifecycle (spawn/working/complete), and reports
active_subagents in runtime state POSTs to /agents/{id}/runtime-state.
**Implementation:**
- Created SubagentTracker service managing per-session subagent state
- Added hook detection in event-enricher for Agent/SendMessage MCP tools
- Wired tracker through SwitchNotificationPoller to all RoomConnections
- Extended RoomConnection.postRuntimeState() to include active_subagents
- Added session lifecycle cleanup (session:deleted, session:remote-terminated)
- Fixed unsafe type casts in extractTargetAgent() with proper validation
**Files created:**
- src/shared/core/switch-rooms/subagent-activity.ts - shared types
- src/main/core/switch-rooms/subagent-tracker.ts - tracking service
**Files modified:**
- src/main/core/agent-hooks/event-enricher.ts - detect Agent tool calls
- src/main/core/agent-hooks/agent-hook-service.ts - route to tracker
- src/main/core/switch-rooms/switch-notification-poller.ts - own tracker
- src/main/core/switch-rooms/room-connection.ts - accept & use tracker
- src/main/core/switch-rooms/room-connection.test.ts - mock tracker
- src/sidecar/sidecar-runtime.ts - own tracker for remote sessions
The backend implementation (PR #369) is already merged and ready to receive
this data. Once this lands, subagent activity will flow through the full
stack: console → API → DB → Matrix → bridge → Teams/Slack/Mattermost/etc.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Parent agents can now report their active subagents with runtime state
(POST /agents/{id}/runtime-state, active_subagents, max 50). The list is
stored on agent_runtime_states with the same preserve-on-omit rule as
control_capabilities, carried on AgentRuntimeStateEvent, and rendered
under the working indicator by every collaboration adapter with
platform-specific escaping and limits.
Also stop tracking internal/ and .claude/worktrees.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tq1pDDfir5c96Lzzc3txk1
The Claude plugin already maps SubagentStart/SubagentStop to the subagent/subagent-done hook events. The room connection now keeps the live subagents of the running turn from those events and posts them with runtime state at once on each spawn and finish, so the room's working indicator lists them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tq1pDDfir5c96Lzzc3txk1
raullopez-sandbox
force-pushed
the
feat/agent-list-all-references
branch
from
September 4, 2026 10:39
7716f25 to
174e340
Compare
Claude Code does not report the same agent_id on a named subagent's SubagentStart and its matching SubagentStop — observed against a real session: Stop carried a different id than Start, and no agent_type at all. Matching the finish event by id silently never cleared the started entry, so the indicator never showed anything. Track subagents in an ordered list and clear the oldest live one on finish instead. Verified against a real Claude Code session driven by the console: Mattermost's working indicator gains the subagent line on spawn and loses it on finish. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tq1pDDfir5c96Lzzc3txk1
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.
Implements subagent activity visibility on every bridged chat platform. When an agent delegates to subagents, the room's working indicator now lists them.
What changes
Backend (
core/)POST /agents/{id}/runtime-stateacceptsactive_subagents: a list of{agent_id, agent_name, state, detail}, max 50 entries.nullmeans "unchanged".agent_runtime_states.active_subagents(JSONB, migrationf8a1b2c3d4e5) with the same preserve-on-omit rule ascontrol_capabilities, and carried onAgentRuntimeStateEvent.- <emoji> <name>[: detail]. Names and details are escaped for the platform (mrkdwn for Slack, markdown for Discord, Mattermost and Teams, HTML for Telegram). Limits: Slack 10 entries and 100-char detail, Teams 4 entries, Telegram 120-char detail, others 20 entries.Console (
console/)SubagentStart/SubagentStophooks. The Claude plugin already maps them to thesubagent/subagent-donehook events. The event enricher now returns asubagentevent for them, and both the desktop hook service and the sidecar runtime dispatch it.RoomConnectionkeeps the live subagents of the running turn and posts them with runtime state at once on each spawn and finish. The list is cleared when the turn ends, when the state leavesworking, and when a new turn starts.Housekeeping
internal/and.claude/worktrees/are no longer tracked and are ignored.Result
Mattermost, from a stack built on this branch:
The same message is edited in place when the subagent finishes and the line is removed.
Tests
just check,just typecheck,just test(2284 passed).subagent/subagent-done;RoomConnectionposts one runtime state per event with the list, keys by id, clears at turn end, and does not push outside a working turn. Typecheck, lint and vitest are green (one pre-existing failure insession-spawner.test.tsis identical onmain).🤖 Generated with Claude Code
https://claude.ai/code/session_01Tq1pDDfir5c96Lzzc3txk1