Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

feat: add dedicated subagent view to TUI

Open
#1,360 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@avoidwork is already working on this.

Since Oct 11, 2026.

  • #1371 by @avoidwork — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
22/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
javascript, nodejs
Domain
cli

Research direction

Start in callProvider in index.js (around line 228), where _namespace from agent.stream() is currently discarded, and confirm how the root graph and subagent namespaces differ. Then read createStreamingHandler in src/tui/conversationArea.js and src/tui/panels.js to see how events and panels are routed. Done means subagent events reach a separate store and a SUBAGENTS panel renders them, with tests in tests/unit/tui/subagentsPanel.test.js. The issue says the design must be approved first, so confirm with maintainers before writing code.

Written by the indexing model from the issue text.

Description

approved feature in progress

Summary

Add a dedicated SUBAGENTS panel to the TUI that captures and renders each subagent's reasoning and message segments separately from the orchestrator's conversation, including subagent tool calls.

Motivation

When the orchestrator delegates work via the task tool, the subagent's reasoning and message segments are currently flattened into the same assistant bubble as the orchestrator's own output. The stream namespace that identifies which subgraph produced each event is discarded in callProvider, so there is no way to distinguish what the orchestrator said from what each subagent did. This makes multi-agent runs hard to follow and audit.

Proposed Solution

Capture the stream namespace in callProvider (index.js) to distinguish subagent subgraphs from the root graph. With subgraphs: true, the stream yields [namespace, mode, payload] where the root graph has an empty namespace and each subagent subgraph has a populated namespace (e.g. ["task:<uuid>"]). Emit new event types for subagent reasoning, message, and tool activity, and route them to a dedicated SUBAGENTS panel instead of the main assistant bubble.

Alternatives Considered

  • Inline collapsible sections — subagent activity renders in the conversation as collapsible/indented blocks. Keeps everything in context, but the conversation gets busier and harder to scan.
  • Second message list in the conversation area — a dedicated subagent stream always visible alongside the main one. More complex layout, but always visible.
  • Dedicated SUBAGENTS panel (chosen) — consistent with the existing panel system (SKILLS/MEMORIES/SETTINGS/SESSIONS/PROJECTS). Clean separation; tab to it to see what each subagent did.

Dependencies

  • None — this uses the existing LangGraph stream namespace (subgraphs: true) and the existing TUI panel system. No new npm packages required.

Testing Strategy

  • Unit tests: Verify namespace discrimination (root graph empty namespace vs subagent populated namespace), event routing to the subagent store, and that subagent tool calls are redirected.
  • Integration test: Run a multi-agent turn and confirm subagent reasoning/message segments land in the SUBAGENTS panel, not the main conversation.
  • Edge cases: Multiple subagents in one turn, nested subagent delegation, subagent with reasoning-only output, subagent tool calls with errors.

Security Considerations

  • Credential storage: No new credentials — this is a TUI rendering change.
  • Input validation: No new user input surface.
  • OWASP: No new attack surface; existing URL allowlist and tool validation rules still apply.

Environment

  • OS: Linux 7.0.14-17-pve
  • Node.js: v25.8.1
  • madz version: 1.107.0
  • LLM provider: Unknown — user to confirm

OpenSpec Note

This project uses OpenSpec for feature development. If this request is approved, I will:

  1. Run /opsx:propose to generate a full proposal with specs and tasks
  2. Iterate on the design before any code is written
  3. Follow the task-driven implementation workflow

Additional Context

The key interception point is callProvider in index.js (around line 208), where the _namespace from agent.stream() is currently discarded. The TUI streaming handler in src/tui/conversationArea.js (createStreamingHandler) folds all events into a single assistant bubble via streamingMsgIdRef. The capture must happen in callProvider because the namespace is lost by the time events reach the TUI.

Audit Findings (for Issue #1360)

  • index.js:228 — callProvider iterates agent.stream(input, { streamMode: ["messages", "tools"], subgraphs: true }) and destructures [_namespace, mode, payload]. The _namespace is discarded — this is the single interception point. With subgraphs: true, the root graph yields an empty namespace [] and each subagent subgraph yields a populated namespace (e.g. ["task:<uuid>"]). namespace.length > 0 discriminates subagent activity.
  • index.js:228-300 — The messages mode handler emits { type: "message" } and { type: "reasoning" }; the tools mode handler emits on_tool_start/on_tool_end. All of these are emitted regardless of namespace, so subagent events are indistinguishable from orchestrator events.
  • src/tui/conversationArea.js:370 — streamingMsgIdRef.current = messageListRef.current.addMessage("assistant", "", ...) creates the single assistant bubble that all stream events fold into via createStreamingHandler.
  • src/tui/conversationArea.js:createStreamingHandler — Handles message, reasoning, on_chat_model_stream, on_tool_start, on_tool_end, tool, on_tool_error. All update streamingMsgIdRef.current. Subagent events must be routed to a separate store instead.
  • src/tui/panels.js:4 — PANELS enum. Add a SUBAGENTS panel here and register it in getPanelOrder() for tab navigation.
  • src/tui/app.js — Panel routing in the render switch (currentView === PANELS.SKILLS etc.). Add a SUBAGENTS branch rendering the new panel.
  • src/tui/messageBubble.js — Reusable MessageBubble component; the subagent panel can reuse it (or a variant) to render each subagent's reasoning/message segments.

Fix Steps

  1. Capture the namespace — In callProvider (index.js:228), stop discarding _namespace. When namespace.length > 0, emit new event types (subagent_message, subagent_reasoning, subagent_tool_start, subagent_tool_end) carrying the namespace, instead of the flat message/reasoning/on_tool_* events. Keep the root graph (empty namespace) emitting the existing event types.
  2. Route subagent events in the TUI — In createStreamingHandler (src/tui/conversationArea.js), handle the new subagent_* event types by routing them to a dedicated subagent store (e.g. a ref keyed by namespace), not to streamingMsgIdRef.current.
  3. Add the SUBAGENTS panel — Add SUBAGENTS to PANELS (src/tui/panels.js) and register it in getPanelOrder(). Create src/tui/subagentsPanel.js rendering each subagent's reasoning/message segments and tool calls, reusing MessageBubble or a variant.
  4. Wire the panel into App — Add a currentView === PANELS.SUBAGENTS branch in the App render switch (src/tui/app.js) rendering the new panel, passing the subagent store.
  5. Write unit tests — Add tests/unit/tui/subagentsPanel.test.js covering namespace discrimination, event routing, and tool-call redirection.
  6. Verify — Run npm run test, npm run lint, and npm run coverage to confirm everything passes.
Dominant language
JavaScript
Stars
2
Forks
0
Avg merge
1h 15m
Merged PRs (30d)
237

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from avoidwork/madz

All issues in avoidwork/madz

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.