File size: 2,203 Bytes
86f402d
 
 
 
 
 
 
58a4476
 
 
 
 
 
 
 
5241b71
58a4476
86f402d
58a4476
 
 
 
 
 
86f402d
 
 
 
58a4476
 
 
 
 
 
 
 
 
 
 
 
 
 
86f402d
 
58a4476
 
86f402d
58a4476
86f402d
58a4476
86f402d
58a4476
86f402d
58a4476
 
 
 
 
86f402d
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { ToolCall } from '../types';
import './ToolCallCard.css';

interface ToolCallCardProps {
  toolCall: ToolCall;
}

const TOOL_LABELS: Record<string, string> = {
  analyze_image: 'Analyse image',
  compare_images: 'Compare images',
  load_model: 'Loading analysis model',
  visual_exam: 'MedGemma visual examination',
  classify: 'Running classifier',
  gradcam: 'Generating attention map',
  guidelines: 'Searching clinical guidelines',
  search_guidelines: 'Searching clinical guidelines',
};

const STATUS_CONFIG: Record<string, { label: string; dot: string }> = {
  STABLE: { label: 'Stable', dot: 'dot-green' },
  MINOR_CHANGE: { label: 'Minor Change', dot: 'dot-amber' },
  SIGNIFICANT_CHANGE: { label: 'Significant Change', dot: 'dot-red' },
  IMPROVED: { label: 'Improved', dot: 'dot-blue' },
};

export function ToolCallCard({ toolCall }: ToolCallCardProps) {
  const isLoading = toolCall.status === 'calling';
  const isError = toolCall.status === 'error';
  const label = TOOL_LABELS[toolCall.tool] ?? toolCall.tool.replace(/_/g, ' ');

  // Build summary text for completed tools
  let summary = '';
  if (toolCall.status === 'complete' && toolCall.result) {
    const r = toolCall.result;
    if (toolCall.tool === 'analyze_image' && (r.full_name || r.diagnosis)) {
      const pct = r.confidence != null ? ` (${Math.round(r.confidence * 100)}%)` : '';
      summary = `${r.full_name ?? r.diagnosis}${pct}`;
    } else if (toolCall.tool === 'compare_images' && r.status_label) {
      const cfg = STATUS_CONFIG[r.status_label];
      summary = cfg?.label ?? r.status_label;
    }
  }

  return (
    <div className="tool-line">
      <span className="tool-line-indicator">
        {isLoading ? (
          <span className="tool-spinner" />
        ) : isError ? (
          <span className="tool-dot dot-red" />
        ) : (
          <span className="tool-dot dot-green" />
        )}
      </span>
      <span className="tool-line-label">{label}</span>
      {isLoading && <span className="tool-line-status">running</span>}
      {summary && <span className="tool-line-summary">{summary}</span>}
      {isError && <span className="tool-line-error">failed</span>}
    </div>
  );
}