import { memo } from "react"; import { GitCompareArrows } from "lucide-react"; import type { ToolPart } from "../types/parts"; import { CodeBlock } from "../markdown/code-block"; import { PreviewCard, PreviewEmpty, PreviewError, PreviewLoading } from "./preview-primitives"; function extractString(record: Record, ...keys: string[]) { for (const key of keys) { const value = record[key]; if (typeof value === "string" && value.length > 0) { return value; } } return undefined; } function extractDiffPayload(part: ToolPart): { path?: string; diff?: string; before?: string; after?: string; } { const sources = [part.state.input, part.state.output, part.state.metadata]; for (const source of sources) { if (!source || typeof source !== "object") { continue; } const record = source as Record; const diff = extractString(record, "diff", "patch", "unifiedDiff", "unified_diff"); const before = extractString(record, "oldString", "old_string", "before", "previous"); const after = extractString(record, "newString", "new_string", "after", "updated"); const path = extractString(record, "file_path", "filePath", "path"); if (diff || before || after) { return { path, diff, before, after }; } } return {}; } export interface DiffPreviewProps { part: ToolPart; } export const DiffPreview = memo(({ part }: DiffPreviewProps) => { const payload = extractDiffPayload(part); return ( } title={payload.path ? `Changes for ${payload.path}` : "File changes"} > {part.state.status === "running" ? : null} {part.state.error ? : null} {!payload.diff && !payload.before && !payload.after ? ( ) : null} {payload.diff ? ( ) : null} {!payload.diff && payload.before ? (
Before
) : null} {!payload.diff && payload.after ? (
After
) : null}
); }); DiffPreview.displayName = "DiffPreview";