diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3dd1d17..f836a64 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -233,6 +233,9 @@ export default function App() { const [userSessions, setUserSessions] = useState([]); const [showSessions, setShowSessions] = useState(false); + /* ── Raw/rendered message toggle state ─────────────────────────────── */ + const [rawMessages, setRawMessages] = useState>(new Set()); + const bottomRef = useRef(null); /* Restore auth session from stored token */ @@ -364,6 +367,22 @@ export default function App() { }); }; + /* ── Copy to clipboard ───────────────────────────────────────────── */ + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(text); + } catch { + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.className = "fixed left-[-9999px]"; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand("copy"); + document.body.removeChild(textarea); + } + }; + /* ── Chat handler ────────────────────────────────────────────────── */ const handleSubmit = async (e: React.FormEvent) => { @@ -595,13 +614,45 @@ export default function App() { className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"}`} >
- + {msg.role === "assistant" && rawMessages.has(i) ? ( +
{msg.content}
+ ) : ( + + )} + + {/* Toolbar for assistant messages */} + {msg.role === "assistant" && ( +
+ + +
+ )} + {msg.role === "assistant" && msg.totalTokens !== undefined && (