Add transcript virtualization to Foundry UI (#255)

This commit is contained in:
Nathan Flurry 2026-03-14 17:55:05 -07:00 committed by GitHub
parent 5ea9ec5e2f
commit 400f9a214e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 780 additions and 576 deletions

View file

@ -286,7 +286,7 @@ export default function App() {
const [highlightedEventId, setHighlightedEventId] = useState<string | null>(null);
const [debugPanelCollapsed, setDebugPanelCollapsed] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
const transcriptScrollRef = useRef<HTMLDivElement>(null);
const clientRef = useRef<SandboxAgent | null>(null);
const activeSessionRef = useRef<Session | null>(null);
@ -1434,10 +1434,6 @@ export default function App() {
});
}, [connected, sessionId, sessions, getClient, subscribeToSession]);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [transcriptEntries]);
const currentAgent = agents.find((agent) => agent.id === agentId);
const agentLabel = agentDisplayNames[agentId] ?? agentId;
const selectedSession = sessions.find((s) => s.sessionId === sessionId);
@ -1743,7 +1739,7 @@ export default function App() {
}
agentsLoading={agentsLoading}
agentsError={agentsError}
messagesEndRef={messagesEndRef}
scrollRef={transcriptScrollRef}
agentLabel={agentLabel}
modelLabel={modelPillLabel}
currentAgentVersion={currentAgent?.version ?? null}

View file

@ -1,6 +1,6 @@
import type { TranscriptEntry } from "@sandbox-agent/react";
import { AlertTriangle, Archive, CheckSquare, MessageSquare, Plus, Square, Terminal } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef, useState, type RefObject } from "react";
import type { AgentInfo } from "sandbox-agent";
import { formatShortId } from "../../utils/format";
@ -40,7 +40,7 @@ const ChatPanel = ({
agents,
agentsLoading,
agentsError,
messagesEndRef,
scrollRef,
agentLabel,
modelLabel,
currentAgentVersion,
@ -71,7 +71,7 @@ const ChatPanel = ({
agents: AgentInfo[];
agentsLoading: boolean;
agentsError: string | null;
messagesEndRef: React.RefObject<HTMLDivElement>;
scrollRef: RefObject<HTMLDivElement>;
agentLabel: string;
modelLabel?: string | null;
currentAgentVersion?: string | null;
@ -233,7 +233,7 @@ const ChatPanel = ({
entries={transcriptEntries}
sessionError={sessionError}
eventError={null}
messagesEndRef={messagesEndRef}
scrollRef={scrollRef}
onEventClick={onEventClick}
isThinking={isThinking}
agentId={agentId}

View file

@ -7,7 +7,7 @@ import {
type TranscriptEntry,
} from "@sandbox-agent/react";
import { AlertTriangle, Brain, Check, ChevronDown, ChevronRight, ExternalLink, Info, PlayCircle, Send, Shield, Wrench, X } from "lucide-react";
import type { ReactNode } from "react";
import type { ReactNode, RefObject } from "react";
import MarkdownText from "./MarkdownText";
const agentLogos: Record<string, string> = {
@ -84,7 +84,7 @@ export interface InspectorConversationProps {
entries: TranscriptEntry[];
sessionError: string | null;
eventError?: string | null;
messagesEndRef: React.RefObject<HTMLDivElement>;
scrollRef: RefObject<HTMLDivElement>;
onEventClick?: (eventId: string) => void;
isThinking?: boolean;
agentId?: string;
@ -102,7 +102,7 @@ const InspectorConversation = ({
entries,
sessionError,
eventError,
messagesEndRef,
scrollRef,
onEventClick,
isThinking,
agentId,
@ -119,12 +119,13 @@ const InspectorConversation = ({
<AgentConversation
entries={entries}
classNames={conversationClassNames}
scrollRef={scrollRef}
emptyState={emptyState}
transcriptClassNames={transcriptClassNames}
transcriptProps={{
endRef: messagesEndRef,
sessionError,
eventError,
virtualize: true,
onEventClick,
isThinking,
agentId,