nandi/oripublic Fork 0
34e69b510306161654f26903a269247aefa9c94d
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

ToolCallCard.tsx · 126 lines · 3.4 KBTypeScript Blame HistoryRaw
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday1/**
2 * ToolCallCard shows one tool call the agent is running, in the spirit of
3 * Zed's agent panel: a collapsible card with the tool kind, a live status,
4 * touched locations, and the call's output (text, or a file diff).
5 *
6 * @example
7 * <ToolCallCard call={{ toolCallId: "c1", title: "Reading main.go",
8 * toolKind: "read", status: "in_progress", contents: [], locations: [] }} />
9 */
10
11import type { ToolCall } from "../reducer";
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday12import { InlineText } from "./InlineText";
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday13import type { AcpToolCallContent } from "../protocol";
14import { Markdown } from "./Markdown";
15
16const kindIcons: Record<string, string> = {
17 read: "📖",
18 edit: "✏️",
19 delete: "🗑️",
20 move: "📦",
21 search: "🔍",
22 execute: "⚡",
23 think: "💭",
24 fetch: "🌐",
25 switch_mode: "🔀",
26 other: "🔧",
27};
28
29const statusLabels: Record<string, string> = {
30 pending: "pending",
31 in_progress: "running",
32 completed: "done",
33 failed: "failed",
34};
35
36export function ToolCallCard({ call }: { call: ToolCall }) {
37 return (
38 <details className={`tool tool-${call.status}`}>
39 <summary className="tool-summary">
40 <span className="tool-icon" aria-hidden>
41 {kindIcons[call.toolKind] ?? kindIcons.other}
42 </span>
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday43 <span className="tool-title">
44 <InlineText text={call.title} />
45 </span>
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday46 <span className={`tool-status tool-status-${call.status}`}>
47 {statusLabels[call.status] ?? call.status}
48 </span>
49 </summary>
50 <div className="tool-body">
51 {call.locations.length > 0 && (
52 <ul className="tool-locations">
53 {call.locations.map((location, index) => (
54 // biome-ignore lint/suspicious/noArrayIndexKey: tool-call locations carry no id and the list is replaced wholesale on every update.
55 <li key={index}>
56 <code>
57 {location.path}
58 {location.line != null ? `:${location.line}` : ""}
59 </code>
60 </li>
61 ))}
62 </ul>
63 )}
64 {call.contents.map((content, index) => (
65 // biome-ignore lint/suspicious/noArrayIndexKey: tool-call contents carry no id and the list is replaced wholesale on every update.
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday66 <ToolContent key={index} content={content} toolKind={call.toolKind} />
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday67 ))}
68 </div>
69 </details>
70 );
71}
72
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday73function ToolContent({
74 content,
75 toolKind,
76}: { content: AcpToolCallContent; toolKind: string }) {
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday77 switch (content.type) {
78 case "content":
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday79 return (
80 <TextToolContent text={content.content?.text} toolKind={toolKind} />
81 );
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday82 case "diff":
83 return (
84 <div className="tool-diff">
85 <code className="tool-diff-path">{content.path}</code>
86 {content.oldText != null && (
87 <pre className="tool-diff-old">
88 {prefixLines(content.oldText, "- ")}
89 </pre>
90 )}
91 <pre className="tool-diff-new">
92 {prefixLines(content.newText ?? "", "+ ")}
93 </pre>
94 </div>
95 );
96 case "terminal":
97 return <p className="tool-terminal">terminal: {content.terminalId}</p>;
98 default:
99 return null;
100 }
101}
102
✨ Workspace panel, selectors, previews, desktop app, sandbox template, resizable file tree, light/dark theme 76d62ac k33g yesterday103/**
104 * TextToolContent renders a tool call's textual output. System-command
105 * output (kind "execute") is verbatim text: it goes into a monospace block,
106 * never through the markdown pipeline.
107 */
108function TextToolContent({
109 text,
110 toolKind,
111}: { text: string | undefined; toolKind: string }) {
112 if (!text) {
113 return null;
114 }
115 if (toolKind === "execute") {
116 return <pre className="tool-output">{text}</pre>;
117 }
118 return <Markdown text={text} />;
119}
120
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday121function prefixLines(text: string, prefix: string): string {
122 return text
123 .split("\n")
124 .map((line) => prefix + line)
125 .join("\n");
126}