import { ChevronDown, ChevronRight, Settings } from "lucide-react"; import type { FunctionCall } from "../_types/types"; interface FunctionCallsProps { functionCalls: FunctionCall[]; messageIndex?: number; expandedFunctionCalls: Set; onToggle: (functionCallId: string) => void; } export function FunctionCalls({ functionCalls, messageIndex, expandedFunctionCalls, onToggle, }: FunctionCallsProps) { if (!functionCalls || functionCalls.length === 0) return null; return (
{functionCalls.map((fc, index) => { const functionCallId = `${messageIndex || "streaming"}-${index}`; const isExpanded = expandedFunctionCalls.has(functionCallId); // Determine display name - show both name and type if available const displayName = fc.type && fc.type !== fc.name ? `${fc.name} (${fc.type})` : fc.name; return (
onToggle(functionCallId)} > Function Call: {displayName} {fc.id && ( {fc.id.substring(0, 8)}... )}
{fc.status}
{isExpanded ? ( ) : ( )}
{isExpanded && (
{/* Show type information if available */} {fc.type && (
Type: {fc.type}
)} {/* Show ID if available */} {fc.id && (
ID: {fc.id}
)} {/* Show arguments - either completed or streaming */} {(fc.arguments || fc.argumentsString) && (
Arguments:
                      {fc.arguments
                        ? JSON.stringify(fc.arguments, null, 2)
                        : fc.argumentsString || "..."}
                    
)} {fc.result && (
Result: {Array.isArray(fc.result) ? (
{(() => { // Handle different result formats let resultsToRender = fc.result; // Check if this is function_call format with nested results // Function call format: results = [{ results: [...] }] // Tool call format: results = [{ text_key: ..., data: {...} }] if ( fc.result.length > 0 && fc.result[0]?.results && Array.isArray(fc.result[0].results) && !fc.result[0].text_key ) { resultsToRender = fc.result[0].results; } type ToolResultItem = { text_key?: string; data?: { file_path?: string; text?: string }; filename?: string; page?: number; score?: number; source_url?: string | null; text?: string; }; const items = resultsToRender as unknown as ToolResultItem[]; return items.map((result, idx: number) => (
{/* Handle tool_call format (file_path in data) */} {result.data?.file_path && (
📄 {result.data.file_path || "Unknown file"}
)} {/* Handle function_call format (filename directly) */} {result.filename && !result.data?.file_path && (
📄 {result.filename} {result.page && ` (page ${result.page})`} {result.score && ( Score: {result.score.toFixed(3)} )}
)} {/* Handle tool_call text format */} {result.data?.text && (
{result.data.text.length > 300 ? result.data.text.substring(0, 300) + "..." : result.data.text}
)} {/* Handle function_call text format */} {result.text && !result.data?.text && (
{result.text.length > 300 ? result.text.substring(0, 300) + "..." : result.text}
)} {/* Show additional metadata for function_call format */} {result.source_url && ( )} {result.text_key && (
Key: {result.text_key}
)}
)); })()}
Found {(() => { let resultsToCount = fc.result; if ( fc.result.length > 0 && fc.result[0]?.results && Array.isArray(fc.result[0].results) && !fc.result[0].text_key ) { resultsToCount = fc.result[0].results; } return resultsToCount.length; })()} result {(() => { let resultsToCount = fc.result; if ( fc.result.length > 0 && fc.result[0]?.results && Array.isArray(fc.result[0].results) && !fc.result[0].text_key ) { resultsToCount = fc.result[0].results; } return resultsToCount.length !== 1 ? "s" : ""; })()}
) : (
                        {JSON.stringify(fc.result, null, 2)}
                      
)}
)}
)}
); })}
); }