Skip to content

sub(#250) Phase 2: Chat UI integration and collapsible tool result cards #274

@mmogr

Description

@mmogr

Summary

Integrate the ToolResultRenderer system (from Phase 1) into the chat UI components so tool results are displayed using their registered renderers instead of raw JSON.

Context

After Phase 1 establishes the renderer extension point and implements built-in renderers, this phase connects them to the actual chat UI. Currently, tool results appear as plain text in assistant messages. This phase makes the chat components aware of renderers and adds interactive features (collapse/expand, copy).

Proposed Changes

1. Update tool result display in chat messages

Modify the chat message component that displays tool results to:

// Pseudocode for the tool result display component
function ToolResultDisplay({ toolName, result }: Props) {
  const registry = useToolRegistry();
  const renderer = registry.getRenderer(toolName);
  
  const [expanded, setExpanded] = useState(false);
  
  if (!renderer) {
    return <FallbackRenderer data={result} />;
  }
  
  return (
    <div className="tool-result">
      <div className="tool-result-header" onClick={() => setExpanded(!expanded)}>
        <ToolIcon name={toolName} />
        <span>{renderer.renderSummary?.(result, toolName) ?? toolName}</span>
        <ChevronIcon expanded={expanded} />
      </div>
      {expanded && (
        <div className="tool-result-body">
          {renderer.renderResult(result, toolName)}
        </div>
      )}
    </div>
  );
}

2. Add collapsible tool result sections

  • Tool results default to collapsed state showing just the summary line
  • Click to expand shows the full rendered result
  • Long results (> threshold) get a "Show more" button within the expanded view

3. Add copy-to-clipboard for tool results

  • Each tool result card gets a copy button
  • Copies the raw JSON data (not the rendered HTML)
  • Toast notification on copy

4. Style tool result cards

.tool-result {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  margin: 8px 0;
  overflow: hidden;
}

.tool-result-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  cursor: pointer;
  background: var(--surface-secondary);
}

.tool-result-body {
  padding: 12px;
  max-height: 400px;
  overflow-y: auto;
}

5. Handle error results distinctly

function ToolErrorDisplay({ error }: { error: string }) {
  return (
    <div className="tool-result tool-result--error">
      <AlertIcon />
      <pre>{error}</pre>
    </div>
  );
}

Files to Modify

File Change
src/components/ (chat message component) Use ToolResultDisplay for tool results
src/components/ToolResultDisplay.tsx New component: renderer-aware tool result display
src/styles/ Add tool result card styles
src/hooks/useGglibRuntime/runAgenticLoop.ts Ensure raw tool result data is preserved in message for rendering

Dependencies

Acceptance Criteria

  • Tool results use registered renderers when available
  • Fallback to pretty-printed JSON for tools without a renderer
  • Tool results are collapsible (default: collapsed with summary)
  • Copy-to-clipboard button on each tool result
  • Error results displayed distinctly with red styling and alert icon
  • Responsive: tool result cards work on narrow viewports
  • No regression in chat scrolling behavior with many tool results
  • Keyboard accessible (Enter/Space to expand/collapse)

Metadata

Metadata

Assignees

No one assigned

    Labels

    component: frontendReact/TypeScript UIpriority: lowNice to havesize: m4-8 hours (half to full day)type: featureNew functionality or enhancementuxUser experience improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions