BrowserConsoleLogsTool.tsx

 1import React, { useState } from "react";
 2import { LLMContent } from "../types";
 3
 4interface BrowserConsoleLogsToolProps {
 5  toolName: string; // to distinguish between recent and clear
 6  toolInput?: unknown;
 7  isRunning?: boolean;
 8  toolResult?: LLMContent[];
 9  hasError?: boolean;
10  executionTime?: string;
11}
12
13function BrowserConsoleLogsTool({
14  toolName,
15  isRunning,
16  toolResult,
17  hasError,
18  executionTime,
19}: BrowserConsoleLogsToolProps) {
20  const [isExpanded, setIsExpanded] = useState(false);
21
22  // Extract output from toolResult
23  const output =
24    toolResult && toolResult.length > 0 && toolResult[0].Text ? toolResult[0].Text : "";
25
26  // Determine display text based on tool name and state
27  const getDisplayText = () => {
28    if (isRunning) {
29      return toolName === "browser_console_clear_logs"
30        ? "clearing console..."
31        : "fetching console logs...";
32    }
33    return toolName === "browser_console_clear_logs" ? "clear console" : "console logs";
34  };
35
36  const displayText = getDisplayText();
37  const isComplete = !isRunning && toolResult !== undefined;
38
39  return (
40    <div className="tool" data-testid={isComplete ? "tool-call-completed" : "tool-call-running"}>
41      <div className="tool-header" onClick={() => setIsExpanded(!isExpanded)}>
42        <div className="tool-summary">
43          <span className={`tool-emoji ${isRunning ? "running" : ""}`}>📋</span>
44          <span className="tool-command">{displayText}</span>
45          {isComplete && hasError && <span className="tool-error"></span>}
46          {isComplete && !hasError && <span className="tool-success"></span>}
47        </div>
48        <button
49          className="tool-toggle"
50          aria-label={isExpanded ? "Collapse" : "Expand"}
51          aria-expanded={isExpanded}
52        >
53          <svg
54            width="12"
55            height="12"
56            viewBox="0 0 12 12"
57            fill="none"
58            xmlns="http://www.w3.org/2000/svg"
59            style={{
60              transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)",
61              transition: "transform 0.2s",
62            }}
63          >
64            <path
65              d="M4.5 3L7.5 6L4.5 9"
66              stroke="currentColor"
67              strokeWidth="1.5"
68              strokeLinecap="round"
69              strokeLinejoin="round"
70            />
71          </svg>
72        </button>
73      </div>
74
75      {isExpanded && (
76        <div className="tool-details">
77          {isComplete && (
78            <div className="tool-section">
79              <div className="tool-label">
80                Output{hasError ? " (Error)" : ""}:
81                {executionTime && <span className="tool-time">{executionTime}</span>}
82              </div>
83              <pre className={`tool-code ${hasError ? "error" : ""}`}>
84                {output || "(no output)"}
85              </pre>
86            </div>
87          )}
88        </div>
89      )}
90    </div>
91  );
92}
93
94export default BrowserConsoleLogsTool;