2026 03 06 Tool Renderer Library Design
Documentation for Plans
Tool Renderer Library — Design Document
Date: 2026-03-06
Session: 187+
Status: Design (pending approval)
1. Problem Statement
The current chat UI presents tool outputs in a crowded, unpolished way:
- Raw JSON everywhere:
start_module_generationandcheck_module_generationshow{"sessionId":"modgen-xxx","status":"started","message":"..."}as raw text - No tool-specific UX: Each tool has unique semantics (status, phases, modules, errors) but all fall through to
DefaultRenderer, which dumps key-value pairs or raw JSON - Crowded layout: Tool cards, condensed execution summary, and footer bar compete for space with poor visual hierarchy
- Errors as raw text: LLM provider failures appear as long technical blocks instead of user-friendly error components
User need: Each tool should have a dedicated component that renders its output in a clear, scannable, user-friendly way. Code should be segregated and maintainable.
2. Current Architecture
lib-unified-chat
└── lib-unified-message
└── lib-tool-use-card [toolCall]
├── .tool-header (name, icon, status, duration)
└── .tool-details (when expanded)
└── lib-tool-renderer-host [toolCall]
└── switch by toolName:
- browser → BrowserRenderer
- screen-capture → ScreenCaptureRenderer
- shell → ShellRenderer
- search → SearchRenderer
- delegation → DelegationRenderer
- default → DefaultRenderer (raw JSON / key-value)
Tools without dedicated renderers (fall to DefaultRenderer):
start_module_generationcheck_module_generationhttp_requestquery_platformmcp_*toolsmanage_group,send_messagestart_computer_use,check_computer_use_status,computer_use_intervenetask_complete- Others
3. Proposed Architecture
3.1 Tool Renderer Library Structure
libs/libs-ai/vitto-chat/src/lib/
├── components/
│ └── tool-renderers/
│ ├── tool-renderer-host/ # Dispatcher (unchanged)
│ ├── default-renderer/ # Fallback (improved)
│ ├── renderers/
│ │ ├── browser-renderer/
│ │ ├── shell-renderer/
│ │ ├── search-renderer/
│ │ ├── delegation-renderer/
│ │ ├── screen-capture-renderer/
│ │ ├── module-generation-renderer/ # NEW: start + check
│ │ ├── http-request-renderer/ # NEW
│ │ ├── computer-use-renderer/ # NEW: start/check/intervene
│ │ ├── error-renderer/ # NEW: LLM/tool failures
│ │ └── ...
│ └── shared/ # NEW: shared primitives
│ ├── tool-status-badge/
│ ├── tool-phase-indicator/
│ └── tool-error-panel/
3.2 Module Generation Renderer (Priority 1)
Input: start_module_generation or check_module_generation tool call
Output shape (from backend):
start_module_generation:{ sessionId, status: 'started', message }check_module_generation:{ status, currentPhase, completedPhases[], modules[], qualityScore, error }
Component design:
- start_module_generation:
- Compact card: "Generation started" with session ID (truncated, copyable)
- Short message: "Polling for results..."
- No raw JSON by default
- check_module_generation:
- status: running: Phase indicator (e.g. "ENHANCE" with progress bar or step list)
- status: completed: List of generated modules (name, description, id)
- status: failed: Error message in user-friendly panel, no stack trace
- Optional "Show raw" for developers
3.3 Error Renderer (Priority 2)
Trigger: When toolCall.success === false or output contains error / ERROR: pattern
Design:
- Short summary: "Generation failed" or "Provider error"
- Expandable "Details" for technical info (copyable)
- No pink-highlighted raw API text in main view
- Optional "Retry" / "Copy error" actions
3.4 Tool Use Card Improvements
- Spacing: Increase padding between tool cards in
unified-message__tools - Subtitle: Show meaningful context (e.g. "ENHANCE phase" for check_module_generation) instead of raw JSON preview
- Compact mode: Keep header tight; details panel only when expanded
- Friendly names: Add
start_module_generation→ "Starting module generation",check_module_generation→ "Checking generation status"
3.5 Registry Pattern
ToolRendererHost dispatches by toolName:
// tool-renderer-host.component.ts
readonly rendererType = computed(() => {
const name = this.toolCall().toolName;
if (['start_module_generation', 'check_module_generation'].includes(name)) return 'module-generation';
if (['start_computer_use', 'check_computer_use_status', 'computer_use_intervene'].includes(name)) return 'computer-use';
if (name === 'http_request') return 'http-request';
// ... existing mappings
return 'default';
});
Each new renderer is a standalone component in renderers/ with a single responsibility.
4. Design Principles
- User-first: Show what the user cares about (status, result, error) — not raw JSON
- Progressive disclosure: Summary by default; optional "Show raw" for developers
- Segregated code: One renderer per tool (or tool family); one file per component
- Shared primitives: Reuse
ToolStatusBadge,ToolPhaseIndicator,ToolErrorPanelacross renderers - Consistent styling: Use
--chat-*variables, same spacing/typography as other chat components
5. Implementation Plan (High-Level)
| Phase | Scope | Deliverables |
|---|---|---|
| 1 | Module generation | ModuleGenerationRendererComponent, ToolRendererHost mapping, friendly names |
| 2 | Error handling | ErrorRendererComponent or enhance DefaultRenderer for failures |
| 3 | Layout improvements | Tool card spacing, subtitle logic, condensed summary |
| 4 | Additional tools | HTTP, computer-use, MCP tools as needed |
6. File Changes Summary
| File | Action |
|---|---|
tool-renderer-host.component.ts |
Add module-generation, error, http-request mappings |
tool-use-card.component.ts |
Add friendly names for module gen tools; improve subtitle |
renderers/module-generation-renderer/ |
NEW — component + template + styles |
renderers/error-renderer/ |
NEW — component for failed tool calls |
shared/tool-status-badge/ |
NEW — optional shared primitive |
unified-message.component.scss |
Increase spacing in unified-message__tools |
default-renderer.component.* |
Improve layout; avoid raw JSON as primary view |
7. Approval
Design ready for implementation. Please confirm before proceeding.