"use client"; import type { ReasoningMessagePartComponent } from "@assistant-ui/react"; import { ChevronRightIcon } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; import { TextShimmerLoader } from "@/components/prompt-kit/loader"; import { cn } from "@/lib/utils"; /** * Renders the structured `reasoning` part emitted by the backend's * stream-parity v2 path (A1). * * Behaviour mirrors the existing `ThinkingStepsDisplay`: * - collapsed by default; * - auto-expanded while the part is still `running`; * - auto-collapsed once status flips to `complete`. * * The component is registered via the `Reasoning` slot on * `MessagePrimitive.Parts` in `assistant-message.tsx` so it lives at the * exact ordinal position of the reasoning block in the message content * array (i.e. above the assistant text that follows it). */ export const ReasoningMessagePart: ReasoningMessagePartComponent = ({ text, status }) => { const isRunning = status?.type === "running"; const [isOpen, setIsOpen] = useState(() => isRunning); useEffect(() => { if (isRunning) { setIsOpen(true); } else if (status?.type === "complete") { setIsOpen(false); } }, [isRunning, status?.type]); const headerLabel = useMemo(() => { if (isRunning) return "Thinking"; if (status?.type === "incomplete") return "Thinking interrupted"; return "Thought"; }, [isRunning, status?.type]); if (!text || text.length === 0) { if (!isRunning) return null; } return (