import { Component, type ErrorInfo, type ReactNode, StrictMode, Suspense, use, useEffect, useMemo, useRef, useState } from "react"; import { createRoot } from "react-dom/client"; import { callTool, connectToServer, hasAppHtml, initializeApp, loadSandboxProxy, log, newAppBridge, type ServerInfo, type ToolCallInfo } from "./implementation"; import styles from "./index.module.css"; // Host passes serversPromise to CallToolPanel interface HostProps { serversPromise: Promise; } type ToolCallEntry = ToolCallInfo & { id: number }; let nextToolCallId = 0; function Host({ serversPromise }: HostProps) { const [toolCalls, setToolCalls] = useState([]); const [destroyingIds, setDestroyingIds] = useState>(new Set()); const requestClose = (id: number) => { setDestroyingIds((s) => new Set(s).add(id)); }; const completeClose = (id: number) => { setDestroyingIds((s) => { const next = new Set(s); next.delete(id); return next; }); setToolCalls((calls) => calls.filter((c) => c.id !== id)); }; return ( <> {toolCalls.map((info) => ( requestClose(info.id)} onCloseComplete={() => completeClose(info.id)} /> ))} setToolCalls([...toolCalls, { ...info, id: nextToolCallId++ }])} /> ); } // CallToolPanel renders the unified form with Suspense around ServerSelect interface CallToolPanelProps { serversPromise: Promise; addToolCall: (info: ToolCallInfo) => void; } function CallToolPanel({ serversPromise, addToolCall }: CallToolPanelProps) { const [selectedServer, setSelectedServer] = useState(null); const [selectedTool, setSelectedTool] = useState(""); const [inputJson, setInputJson] = useState("{}"); const toolNames = selectedServer ? Array.from(selectedServer.tools.keys()) : []; const isValidJson = useMemo(() => { try { JSON.parse(inputJson); return true; } catch { return false; } }, [inputJson]); const handleServerSelect = (server: ServerInfo) => { setSelectedServer(server); const [firstTool] = server.tools.keys(); setSelectedTool(firstTool ?? ""); }; const handleSubmit = () => { if (!selectedServer) return; const toolCallInfo = callTool(selectedServer, selectedTool, JSON.parse(inputJson)); addToolCall(toolCallInfo); }; return (
{ e.preventDefault(); handleSubmit(); }}>