feat(ui): display subagent name in progress bar#94
Conversation
Add explicit subagent agent name to the real-time spinner display in the StreamComponent. When a subagent tool starts executing, the spinner now shows the agent type (derived from the 'agent' parameter in ToolArgs JSON) in the format 'subagent (explore)', 'subagent (general)', etc. Changes: - Add encoding/json import for parsing ToolArgs - Add extractAgentNameFromArgs() helper to safely parse the agent field from JSON-encoded ToolArgs, returning empty string on parse failure - Update formatToolExecutionMessage() to accept optional agentName parameter and format subagents as 'subagent (agentName)' when agent is specified - Modify ToolExecutionEvent handler in StreamComponent.Update() to extract agent name from ToolArgs when tool is 'subagent' and pass it through This improves user visibility into which subagent type is running without requiring additional event fields or architectural changes. Falls back gracefully to 'subagent' if agent field is missing or JSON parsing fails. No functional changes to non-subagent tools or existing behavior. All existing tests pass.
|
Connected to Huly®: KIT-95 |
📝 WalkthroughWalkthroughThe stream UI extracts and sanitizes an optional ChangesSubagent spinner labels
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/ui/stream.go (1)
593-612: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd focused tests for the new fallback behavior.
Cover valid agent names, missing/empty fields, malformed JSON, non-string values, and non-subagent formatting so future changes preserve the existing fallback to the tool name.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/ui/stream.go` around lines 593 - 612, The new helper behavior lacks focused test coverage. Add tests for extractAgentNameFromArgs covering valid, missing, empty, malformed, and non-string agent fields, plus formatToolExecutionMessage cases for subagents with and without valid agent names and non-subagent tool names; verify fallback returns the tool name or empty string as appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/ui/stream.go`:
- Around line 600-601: Sanitize the agent value in the agent-selection logic
before returning it for spinner rendering: allow only supported agent names, or
strip ANSI/control characters, reject embedded newlines, and enforce a
reasonable length limit. Preserve the existing fallback behavior when the value
is invalid or empty.
---
Nitpick comments:
In `@internal/ui/stream.go`:
- Around line 593-612: The new helper behavior lacks focused test coverage. Add
tests for extractAgentNameFromArgs covering valid, missing, empty, malformed,
and non-string agent fields, plus formatToolExecutionMessage cases for subagents
with and without valid agent names and non-subagent tool names; verify fallback
returns the tool name or empty string as appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Add sanitizeAgentName() validation function to prevent injection attacks and rendering issues when displaying the subagent type in the StreamComponent spinner. Sanitization enforces: - Maximum length of 50 characters (prevents layout overflow) - No embedded newlines or carriage returns (prevents layout corruption) - No ANSI escape sequences (prevents terminal escape injection) - No control characters (0x00-0x1F, 0x7F) (prevents terminal control injection) - Only alphanumeric, hyphens, underscores, and dots (safe character set) The function gracefully returns empty string for invalid inputs, maintaining existing fallback behavior where the spinner shows just 'subagent' when the agent name is missing or invalid. Updated extractAgentNameFromArgs() to call sanitizeAgentName() before returning, ensuring all agent names are validated regardless of source. Valid examples that pass sanitization: - 'explore', 'general' (standard agents) - 'custom-agent', 'agent_v2', 'agent.prod' (extended naming) Invalid examples that are rejected: - 'agent\ngeneral' (newlines) - 'explore\x1b[31m' (ANSI escapes) - 'agent@attack' (special characters) - 'a' * 51 (exceeds length limit) This maintains the full fallback behavior: invalid agent names result in displaying just 'subagent' with no agent type suffix. No functional changes to existing behavior. All tests pass.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/ui/stream.go`:
- Around line 594-638: Move the `^[a-zA-Z0-9_.-]+$` expression used by
`sanitizeAgentName` into a package-level compiled regexp variable, then reuse it
inside the function. Remove the now-redundant newline, ANSI escape, and
control-character checks while preserving the existing empty-string, length, and
invalid-pattern behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Move the agent name validation pattern to package-level compiled variable (agentNamePattern) to eliminate per-call regexp recompilation overhead. Remove redundant character checks (newline, ANSI escape, control character detection) since the regex pattern [a-zA-Z0-9_.-] inherently rejects all of them and is the single source of truth for character validation. This optimization: - Compiles the regex once at package init, not on every sanitizeAgentName() call - Simplifies the function with fewer branches (no loop for control char checks) - Reduces code lines from 45 to 18 (40% reduction) - Maintains identical behavior: same valid/invalid inputs, same security - Preserves efficient early returns for empty string and length limit The regex pattern [a-zA-Z0-9_.-] inherently rejects: - Control characters (0x00-0x1F, 0x7F) - Newlines and carriage returns (0x0A, 0x0D) - ANSI escape sequences (0x1B) - Any other special characters Verified with 16 test cases: 5 valid + 11 invalid (including newlines, ANSI escapes, control chars, special chars, and length overflow). No functional changes. All tests pass.
|
@coderabbitai review |
✅ Action performedReview finished.
|
Add explicit subagent agent name to the real-time spinner display in the StreamComponent. When a subagent tool starts executing, the spinner now shows the agent type (derived from the 'agent' parameter in ToolArgs JSON) in the format 'subagent (explore)', 'subagent (general)', etc.
Changes:
This improves user visibility into which subagent type is running without requiring additional event fields or architectural changes. Falls back gracefully to 'subagent' if agent field is missing or JSON parsing fails.
No functional changes to non-subagent tools or existing behavior. All existing tests pass.
Visual Impact
Before:
▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ subagent
After (with agent type):
▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ subagent (explore)
Summary by CodeRabbit
subagentsubtype when it’s provided, parsed, and safe to display.