/**
* ChatThread renders the conversation: user prompts, streamed agent answers
* (markdown) and inline errors, auto-scrolled to the latest entry.
*
* @example
*
*/
import { useEffect, useRef } from "react";
import type { ThreadItem } from "../reducer";
import { Markdown } from "./Markdown";
import { ToolCallCard } from "./ToolCallCard";
interface ChatThreadProps {
thread: ThreadItem[];
turnActive: boolean;
}
export function ChatThread({ thread, turnActive }: ChatThreadProps) {
const endRef = useRef(null);
// biome-ignore lint/correctness/useExhaustiveDependencies: thread and turnActive intentionally retrigger the scroll-to-bottom on every conversation change.
useEffect(() => {
// Optional call: test DOMs (jsdom) do not implement scrollIntoView.
endRef.current?.scrollIntoView?.({ behavior: "smooth" });
}, [thread, turnActive]);
return (
{thread.length === 0 && (
Send a prompt to start working with the agent.
)}
{thread.map((item, index) => (
// biome-ignore lint/suspicious/noArrayIndexKey: the thread is append-only (never reordered or spliced), so the index is a stable identity.
))}
{turnActive && (
)}
);
}
function ThreadEntry({ item }: { item: ThreadItem }) {
switch (item.kind) {
case "user":
return