'use client'; import { AlertCircle, Bot, BrainCircuit, Loader2, ServerCog, Square } from 'lucide-react'; import type { ProcessEvent, ProcessRun } from '@/types'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { ScrollArea } from '@/components/ui/scroll-area'; import { appActorTypeLabel, appEventKindLabel, appStatusLabel } from '@/lib/i18n/common'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; import { cn } from '@/lib/utils'; function statusTone(status: string) { if (status === 'done') return 'bg-emerald-500/10 text-emerald-300 border-emerald-500/20'; if (status === 'error') return 'bg-rose-500/10 text-rose-300 border-rose-500/20'; if (status === 'cancelled') return 'bg-zinc-500/10 text-zinc-300 border-zinc-500/20'; if (status === 'waiting') return 'bg-amber-500/10 text-amber-300 border-amber-500/20'; return 'bg-sky-500/10 text-sky-300 border-sky-500/20'; } function actorIcon(run: ProcessRun) { if (run.actor_type === 'mcp') return ; if (run.actor_type === 'system') return ; return ; } export function ProcessLane({ runs, events, selectedRunId, onSelectRun, onCancelRun, }: { runs: ProcessRun[]; events: ProcessEvent[]; selectedRunId: string | null; onSelectRun: (runId: string) => void; onCancelRun: (runId: string) => void; }) { const { locale } = useAppI18n(); const sortedRuns = [...runs].sort((a, b) => { const at = new Date(a.started_at).getTime(); const bt = new Date(b.started_at).getTime(); return bt - at; }); if (sortedRuns.length === 0) { return null; } return (

{pickAppText(locale, '执行过程', 'Execution')}

{pickAppText(locale, '智能体、A2A、MCP 的实时过程', 'Live process stream for agents, A2A, and MCP')}

{pickAppText(locale, `${sortedRuns.length} 个任务`, `${sortedRuns.length} tasks`)}
{sortedRuns.map((run) => { const runEvents = events .filter((event) => event.run_id === run.run_id) .slice(-5) .reverse(); const isSelected = run.run_id === selectedRunId; const canCancel = !run.parent_run_id && run.actor_type !== 'mcp' && (run.status === 'running' || run.status === 'waiting'); return ( onSelectRun(run.run_id)} >
{actorIcon(run)}
{run.actor_name}

{run.title}

{appStatusLabel(run.status, locale)} {canCancel && ( )}
{appActorTypeLabel(run.actor_type, locale)} {run.source && {run.source}} {run.parent_run_id && {pickAppText(locale, '子任务', 'Subtask')}}
{run.summary && (
{run.summary}
)}
{runEvents.length === 0 && run.status === 'running' && (
{pickAppText(locale, '等待首个事件...', 'Waiting for the first event...')}
)} {runEvents.map((event) => (
{appEventKindLabel(event.kind, locale)} {event.status && {appStatusLabel(event.status, locale)}}
{event.text || pickAppText(locale, '结构化更新', 'Structured update')}
))} {run.status === 'error' && (
{pickAppText(locale, '此任务执行失败。', 'This task failed.')}
)}
); })}
); }