import { useState } from "react"; import { useTranslation } from "react-i18next"; import { ChevronDown, ChevronRight, Loader2, Wrench } from "lucide-react"; import type { ToolActivity } from "./use-ai-stream"; import { toolLabel } from "./labels"; /** * Every tool call is shown, so the user can always see what the assistant * looked at rather than having to trust the summary. */ export function AiToolCall({ tool, streaming = false, }: { tool: ToolActivity; /** False once the turn has ended, whatever ended it. */ streaming?: boolean; }) { const { t } = useTranslation(); const [open, setOpen] = useState(false); // A tool can only still be running while the turn is. An aborted or failed // stream leaves calls without results, and treating those as pending left a // spinner running forever after the conversation had finished. const pending = !("result" in tool) && streaming; return (
{open && (
{/* The header reads as an action, so the actual tool id lives here. */}
{tool.name}
{Object.keys(tool.arguments).length > 0 && (
{t("ai.toolArguments")}
                {JSON.stringify(tool.arguments, null, 2)}
              
)} {/* Gated on the result existing, not on !pending: an interrupted turn leaves a call with no result at all, which would otherwise print "undefined" under a Result heading. */} {"result" in tool && (
{t("ai.toolResult")}
                {JSON.stringify(tool.result, null, 2)}
              
)}
)}
); }