import { MessageSquare, PauseCircle, PlayCircle, Plus, Square, Terminal } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import type { AgentInfo, AgentModelInfo, AgentModeInfo, PermissionEventData, QuestionEventData } from "sandbox-agent"; import ApprovalsTab from "../debug/ApprovalsTab"; import ChatInput from "./ChatInput"; import ChatMessages from "./ChatMessages"; import ChatSetup from "./ChatSetup"; import type { TimelineEntry } from "./types"; const ChatPanel = ({ sessionId, polling, turnStreaming, transcriptEntries, sessionError, message, onMessageChange, onSendMessage, onKeyDown, onCreateSession, agents, agentsLoading, agentsError, messagesEndRef, agentId, agentLabel, agentMode, permissionMode, model, variant, modelOptions, defaultModel, modelsLoading, modelsError, variantOptions, defaultVariant, supportsVariants, streamMode, activeModes, currentAgentVersion, hasSession, modesLoading, modesError, onAgentModeChange, onPermissionModeChange, onModelChange, onVariantChange, onStreamModeChange, onToggleStream, onEndSession, eventError, questionRequests, permissionRequests, questionSelections, onSelectQuestionOption, onAnswerQuestion, onRejectQuestion, onReplyPermission }: { sessionId: string; polling: boolean; turnStreaming: boolean; transcriptEntries: TimelineEntry[]; sessionError: string | null; message: string; onMessageChange: (value: string) => void; onSendMessage: () => void; onKeyDown: (event: React.KeyboardEvent) => void; onCreateSession: (agentId: string) => void; agents: AgentInfo[]; agentsLoading: boolean; agentsError: string | null; messagesEndRef: React.RefObject; agentId: string; agentLabel: string; agentMode: string; permissionMode: string; model: string; variant: string; modelOptions: AgentModelInfo[]; defaultModel: string; modelsLoading: boolean; modelsError: string | null; variantOptions: string[]; defaultVariant: string; supportsVariants: boolean; streamMode: "poll" | "sse" | "turn"; activeModes: AgentModeInfo[]; currentAgentVersion?: string | null; hasSession: boolean; modesLoading: boolean; modesError: string | null; onAgentModeChange: (value: string) => void; onPermissionModeChange: (value: string) => void; onModelChange: (value: string) => void; onVariantChange: (value: string) => void; onStreamModeChange: (value: "poll" | "sse" | "turn") => void; onToggleStream: () => void; onEndSession: () => void; eventError: string | null; questionRequests: QuestionEventData[]; permissionRequests: PermissionEventData[]; questionSelections: Record; onSelectQuestionOption: (requestId: string, optionLabel: string) => void; onAnswerQuestion: (request: QuestionEventData) => void; onRejectQuestion: (requestId: string) => void; onReplyPermission: (requestId: string, reply: "once" | "always" | "reject") => void; }) => { const [showAgentMenu, setShowAgentMenu] = useState(false); const menuRef = useRef(null); useEffect(() => { if (!showAgentMenu) return; const handler = (event: MouseEvent) => { if (!menuRef.current) return; if (!menuRef.current.contains(event.target as Node)) { setShowAgentMenu(false); } }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [showAgentMenu]); const agentLabels: Record = { claude: "Claude Code", codex: "Codex", opencode: "OpenCode", amp: "Amp", mock: "Mock" }; const hasApprovals = questionRequests.length > 0 || permissionRequests.length > 0; const isTurnMode = streamMode === "turn"; const isStreaming = isTurnMode ? turnStreaming : polling; const turnLabel = turnStreaming ? "Streaming" : "On Send"; return (
{sessionId ? "Session" : "No Session"} {sessionId && {sessionId}} {sessionId && ( {agentLabel} {currentAgentVersion && v{currentAgentVersion}} )}
{sessionId && ( )}
{!sessionId ? (
No Session Selected

Create a new session to start chatting with an agent.

{showAgentMenu && (
{agentsLoading &&
Loading agents...
} {agentsError &&
{agentsError}
} {!agentsLoading && !agentsError && agents.length === 0 && (
No agents available.
)} {!agentsLoading && !agentsError && agents.map((agent) => ( ))}
)}
) : transcriptEntries.length === 0 && !sessionError ? (
Ready to Chat

Send a message to start a conversation with the agent.

{agentId === "mock" && (
The mock agent simulates agent responses for testing the inspector UI without requiring API credentials. Send help for available commands.
)}
) : ( )}
{hasApprovals && (
Approvals
)}
); }; export default ChatPanel;