"use client"; import React, { useState, useMemo, useCallback } from "react"; import { ChevronDown, ChevronUp, Terminal, AlertCircle, Loader2, CircleCheckBigIcon, StopCircle, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ToolCall, ActionRequest, ReviewConfig } from "@/app/types/types"; import { cn } from "@/lib/utils"; import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui"; import { ToolApprovalInterrupt } from "@/app/components/ToolApprovalInterrupt"; interface ToolCallBoxProps { toolCall: ToolCall; uiComponent?: any; stream?: any; graphId?: string; actionRequest?: ActionRequest; reviewConfig?: ReviewConfig; onResume?: (value: any) => void; isLoading?: boolean; } export const ToolCallBox = React.memo( ({ toolCall, uiComponent, stream, graphId, actionRequest, reviewConfig, onResume, isLoading, }) => { const [isExpanded, setIsExpanded] = useState( () => !!uiComponent || !!actionRequest ); const [expandedArgs, setExpandedArgs] = useState>( {} ); const { name, args, result, status } = useMemo(() => { return { name: toolCall.name || "Unknown Tool", args: toolCall.args || {}, result: toolCall.result, status: toolCall.status || "completed", }; }, [toolCall]); const statusIcon = useMemo(() => { switch (status) { case "completed": return ; case "error": return ( ); case "pending": return ( ); case "interrupted": return ( ); default: return ( ); } }, [status]); const toggleExpanded = useCallback(() => { setIsExpanded((prev) => !prev); }, []); const toggleArgExpanded = useCallback((argKey: string) => { setExpandedArgs((prev) => ({ ...prev, [argKey]: !prev[argKey], })); }, []); const hasContent = result || Object.keys(args).length > 0; return (
{isExpanded && hasContent && (
{uiComponent && stream && graphId ? (
) : actionRequest && onResume ? ( // Show tool approval UI when there's an action request but no GenUI
) : ( <> {Object.keys(args).length > 0 && (

Arguments

{Object.entries(args).map(([key, value]) => (
{expandedArgs[key] && (
                                {typeof value === "string"
                                  ? value
                                  : JSON.stringify(value, null, 2)}
                              
)}
))}
)} {result && (

Result

                      {typeof result === "string"
                        ? result
                        : JSON.stringify(result, null, 2)}
                    
)} )}
)}
); } ); ToolCallBox.displayName = "ToolCallBox";