import type { ToolInvocationUIPart } from '@ai-sdk/ui-utils'; import { AnimatePresence, motion } from 'framer-motion'; import { memo, useMemo, useState, useEffect } from 'react'; import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki'; import { classNames } from '~/utils/classNames'; import { TOOL_EXECUTION_APPROVAL, TOOL_EXECUTION_DENIED, TOOL_EXECUTION_ERROR, TOOL_NO_EXECUTE_FUNCTION, } from '~/utils/constants'; import { cubicEasingFn } from '~/utils/easings'; import { logger } from '~/utils/logger'; import { themeStore, type Theme } from '~/lib/stores/theme'; import { useStore } from '@nanostores/react'; import type { ToolCallAnnotation } from '~/types/context'; const highlighterOptions = { langs: ['json'], themes: ['light-plus', 'dark-plus'], }; const jsonHighlighter: HighlighterGeneric = import.meta.hot?.data.jsonHighlighter ?? (await createHighlighter(highlighterOptions)); if (import.meta.hot) { import.meta.hot.data.jsonHighlighter = jsonHighlighter; } interface JsonCodeBlockProps { className?: string; code: string; theme: Theme; } function JsonCodeBlock({ className, code, theme }: JsonCodeBlockProps) { let formattedCode = code; try { if (typeof formattedCode === 'object') { formattedCode = JSON.stringify(formattedCode, null, 2); } else if (typeof formattedCode === 'string') { // Attempt to parse and re-stringify for formatting try { const parsed = JSON.parse(formattedCode); formattedCode = JSON.stringify(parsed, null, 2); } catch { // Leave as is if not JSON } } } catch (e) { // If parsing fails, keep original code logger.error('Failed to parse JSON', { error: e }); } return (
); } interface ToolInvocationsProps { toolInvocations: ToolInvocationUIPart[]; toolCallAnnotations: ToolCallAnnotation[]; addToolResult: ({ toolCallId, result }: { toolCallId: string; result: any }) => void; } export const ToolInvocations = memo(({ toolInvocations, toolCallAnnotations, addToolResult }: ToolInvocationsProps) => { const theme = useStore(themeStore); const [showDetails, setShowDetails] = useState(false); const toggleDetails = () => { setShowDetails((prev) => !prev); }; const toolCalls = useMemo( () => toolInvocations.filter((inv) => inv.toolInvocation.state === 'call'), [toolInvocations], ); const toolResults = useMemo( () => toolInvocations.filter((inv) => inv.toolInvocation.state === 'result'), [toolInvocations], ); const hasToolCalls = toolCalls.length > 0; const hasToolResults = toolResults.length > 0; if (!hasToolCalls && !hasToolResults) { return null; } return (
{hasToolResults && (
)}
{hasToolCalls && (
)} {hasToolResults && showDetails && (
)}
); }); const toolVariants = { hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0 }, }; interface ToolResultsListProps { toolInvocations: ToolInvocationUIPart[]; toolCallAnnotations: ToolCallAnnotation[]; theme: Theme; } const ToolResultsList = memo(({ toolInvocations, toolCallAnnotations, theme }: ToolResultsListProps) => { return (
    {toolInvocations.map((tool, index) => { const toolCallState = tool.toolInvocation.state; if (toolCallState !== 'result') { return null; } const { toolName, toolCallId } = tool.toolInvocation; const annotation = toolCallAnnotations.find((annotation) => { return annotation.toolCallId === toolCallId; }); const isErrorResult = [TOOL_NO_EXECUTE_FUNCTION, TOOL_EXECUTION_DENIED, TOOL_EXECUTION_ERROR].includes( tool.toolInvocation.result, ); return (
    {isErrorResult ? (
    ) : (
    )}
    Server:
    {annotation?.serverName}
    Tool: {toolName}
    Description:{' '} {annotation?.toolDescription}
    Parameters:
    Result:
    ); })}
); }); interface ToolCallsListProps { toolInvocations: ToolInvocationUIPart[]; toolCallAnnotations: ToolCallAnnotation[]; addToolResult: ({ toolCallId, result }: { toolCallId: string; result: any }) => void; theme: Theme; } const ToolCallsList = memo(({ toolInvocations, toolCallAnnotations, addToolResult }: ToolCallsListProps) => { const [expanded, setExpanded] = useState<{ [id: string]: boolean }>({}); // OS detection for shortcut display const isMac = typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform); useEffect(() => { const expandedState: { [id: string]: boolean } = {}; toolInvocations.forEach((inv) => { if (inv.toolInvocation.state === 'call') { expandedState[inv.toolInvocation.toolCallId] = true; } }); setExpanded(expandedState); }, [toolInvocations]); // Keyboard shortcut logic useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { // Ignore if focus is in an input/textarea/contenteditable const active = document.activeElement as HTMLElement | null; if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)) { return; } if (Object.keys(expanded).length === 0) { return; } const openId = Object.keys(expanded).find((id) => expanded[id]); if (!openId) { return; } // Cancel: Cmd/Ctrl + Backspace if ((isMac ? e.metaKey : e.ctrlKey) && e.key === 'Backspace') { e.preventDefault(); addToolResult({ toolCallId: openId, result: TOOL_EXECUTION_APPROVAL.REJECT, }); } // Run tool: Cmd/Ctrl + Enter if ((isMac ? e.metaKey : e.ctrlKey) && (e.key === 'Enter' || e.key === 'Return')) { e.preventDefault(); addToolResult({ toolCallId: openId, result: TOOL_EXECUTION_APPROVAL.APPROVE, }); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [expanded, addToolResult, isMac]); return (
    {toolInvocations.map((tool, index) => { const toolCallState = tool.toolInvocation.state; if (toolCallState !== 'call') { return null; } const { toolName, toolCallId } = tool.toolInvocation; const annotation = toolCallAnnotations.find((annotation) => annotation.toolCallId === toolCallId); return (
    {toolName} {annotation?.toolDescription}
    ); })}
); });