"use client"; import { Handle, Position, type Node, type NodeProps } from "@xyflow/react"; import { useTranslations } from "next-intl"; import BaseNodeWrapper from "./base-node-wrapper"; type AgentOutputNodeData = { isSkeleton?: boolean; stepId?: string; stepIndex?: number; stepTotal?: number; title?: string; channel?: string; outputType?: string; body?: string; _status?: string; _statusMessage?: string; }; type AgentOutputNodeType = Node; function tryFormatJsonBody(body: string): string | null { const trimmed = body.trim(); if (!trimmed) { return null; } const looksLikeJsonObject = trimmed.startsWith("{") && trimmed.endsWith("}"); const looksLikeJsonArray = trimmed.startsWith("[") && trimmed.endsWith("]"); if (!looksLikeJsonObject && !looksLikeJsonArray) { return null; } try { const parsed = JSON.parse(trimmed) as unknown; return JSON.stringify(parsed, null, 2); } catch { return null; } } export default function AgentOutputNode({ data, selected }: NodeProps) { const t = useTranslations("agentOutputNode"); const nodeData = data as AgentOutputNodeData; const isSkeleton = nodeData.isSkeleton === true; const hasStepCounter = typeof nodeData.stepIndex === "number" && Number.isFinite(nodeData.stepIndex) && typeof nodeData.stepTotal === "number" && Number.isFinite(nodeData.stepTotal) && nodeData.stepTotal > 0; const safeStepIndex = typeof nodeData.stepIndex === "number" && Number.isFinite(nodeData.stepIndex) ? Math.max(0, Math.floor(nodeData.stepIndex)) : 0; const safeStepTotal = typeof nodeData.stepTotal === "number" && Number.isFinite(nodeData.stepTotal) ? Math.max(1, Math.floor(nodeData.stepTotal)) : 1; const stepCounter = hasStepCounter ? `${safeStepIndex + 1}/${safeStepTotal}` : null; const resolvedTitle = nodeData.title ?? (isSkeleton ? t("plannedOutputDefaultTitle") : t("defaultTitle")); const body = nodeData.body ?? ""; const formattedJsonBody = isSkeleton ? null : tryFormatJsonBody(body); return (

{resolvedTitle}

{isSkeleton ? ( {t("skeletonBadge")} ) : null}
{isSkeleton ? (

{t("plannedOutputLabel")} {stepCounter ? ` - ${stepCounter}` : ""} {nodeData.stepId ? ` - ${nodeData.stepId}` : ""}

) : null}

{t("channelLabel")}

{nodeData.channel ?? "-"}

{t("typeLabel")}

{nodeData.outputType ?? "-"}

{t("bodyLabel")}

{isSkeleton ? (

{t("plannedContent")}

) : formattedJsonBody ? (
              {formattedJsonBody}
            
) : (

{body}

)}
); }