import type { ToolCallBlock, ToolResultBlock } from '@agentscope-ai/agentscope/message'; import { ChevronRight } from 'lucide-react'; import * as mime from 'mime-types'; import type { ReactNode } from 'react'; import { CornerLine, ToolStateIcon } from './_shared'; import type { TFunction, ToolCallWithResult } from './types'; import { Button } from '@/components/ui/button.tsx'; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible.tsx'; function processToolInput(input: string): string { try { const obj = JSON.parse(input); const entries = Object.entries(obj).map(([k, v]) => `${k}: "${v}"`); return entries.join('\n'); } catch { return input; } } export function defaultGetDisplayName(call: ToolCallBlock): string { return call.name; } export function defaultRenderCallArgs(call: ToolCallBlock): ReactNode { if (call.input.length <= 2) return null; return processToolInput(call.input); } export function defaultRenderResult( call: ToolCallBlock, result: ToolResultBlock, t: TFunction, maxLines = 7, ): ReactNode { if (call.state === 'asking' || !result || result.state === 'running') { return {t('common.running')} ...; } if (result.state === 'interrupted') { return {t('common.interrupted')}; } let resultStr: string; if (typeof result.output === 'string') { resultStr = result.output; } else { const parts = result.output.map((b) => { if (b.type === 'text') return b.text; const mainType = b.source.media_type.split('/')[0].toUpperCase(); const ext = (mime.extension(b.source.media_type) || 'bin').toLowerCase(); return `[${mainType}.${ext}]`; }); resultStr = parts.join('\n'); } let lines = resultStr.split('\n'); if (lines.length > maxLines) { const total = lines.length; lines = lines.slice(0, maxLines); lines.push(t('tool.moreLines', { count: total - maxLines })); } return (