import { useEffect, useRef, useState } from "react"; import type { AgentLogEntry } from "@kb/core"; interface AgentLogViewerProps { entries: AgentLogEntry[]; loading: boolean; } /** * Renders agent log entries in a scrollable, monospace container. * Auto-scrolls to the bottom as new entries arrive, but pauses * auto-scroll when the user scrolls up (scroll-lock). */ export function AgentLogViewer({ entries, loading }: AgentLogViewerProps) { const containerRef = useRef(null); const lastScrollTopRef = useRef(0); const [autoScroll, setAutoScroll] = useState(true); // Auto-scroll to bottom when new entries arrive (if scroll-lock is not active) useEffect(() => { if (autoScroll && containerRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; } }, [entries, autoScroll]); const handleScroll = () => { const el = containerRef.current; if (!el) return; const currentScrollTop = el.scrollTop; const lastScrollTop = lastScrollTopRef.current; // Detect scroll direction: up disables auto-scroll, down re-enables it if (currentScrollTop < lastScrollTop) { setAutoScroll(false); } else if (currentScrollTop > lastScrollTop) { setAutoScroll(true); } lastScrollTopRef.current = currentScrollTop; }; if (loading && entries.length === 0) { return (
Loading agent logs…
); } if (entries.length === 0) { return (
No agent output yet.
); } return (
{entries.map((entry, i) => entry.type === "tool" ? (
⚡ {entry.text} {entry.detail && ( — {entry.detail} )}
) : ( {entry.text} ), )}
); }