diamond-in commited on
Commit
fb60fec
·
verified ·
1 Parent(s): 74e87b2

Update frontend/src/App.tsx

Browse files
Files changed (1) hide show
  1. frontend/src/App.tsx +67 -0
frontend/src/App.tsx CHANGED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ export default function App() {
4
+ const [browserFrame, setBrowserFrame] = useState<string>("");
5
+ const [logs, setLogs] = useState<string[]>([]);
6
+ const [input, setInput] = useState("");
7
+
8
+ useEffect(() => {
9
+ // Connect to the Rust SSE Stream
10
+ const eventSource = new EventSource("/api/stream");
11
+
12
+ eventSource.onmessage = (event) => {
13
+ const data = JSON.parse(event.data);
14
+ if (data.type === "frame") {
15
+ setBrowserFrame(data.data); // Base64 image
16
+ } else if (data.type === "log") {
17
+ setLogs(prev => [...prev, data.data].slice(-10));
18
+ }
19
+ };
20
+
21
+ return () => eventSource.close();
22
+ }, []);
23
+
24
+ const sendMessage = async () => {
25
+ await fetch("/api/chat", {
26
+ method: "POST",
27
+ headers: { "Content-Type": "application/json" },
28
+ body: JSON.stringify({ message: input })
29
+ });
30
+ setInput("");
31
+ };
32
+
33
+ return (
34
+ <div className="flex h-screen bg-zinc-950 text-white font-sans">
35
+ {/* Left: Agent Control */}
36
+ <div className="w-1/3 flex flex-col border-r border-zinc-800 p-4">
37
+ <h1 className="text-xl font-bold mb-4 text-blue-400">Polymorphic Agent</h1>
38
+ <div className="flex-1 overflow-y-auto space-y-2 mb-4 text-sm">
39
+ {logs.map((log, i) => (
40
+ <div key={i} className="p-2 bg-zinc-900 rounded border border-zinc-800">{log}</div>
41
+ ))}
42
+ </div>
43
+ <div className="flex gap-2">
44
+ <input
45
+ className="flex-1 bg-zinc-900 border border-zinc-700 p-2 rounded"
46
+ value={input}
47
+ onChange={(e) => setInput(e.target.value)}
48
+ onKeyDown={(e) => e.key === 'Enter' && sendMessage()}
49
+ />
50
+ <button onClick={sendMessage} className="bg-blue-600 px-4 py-2 rounded">Send</button>
51
+ </div>
52
+ </div>
53
+
54
+ {/* Right: Isolated Browser View */}
55
+ <div className="w-2/3 bg-zinc-900 flex flex-col">
56
+ <div className="p-2 bg-zinc-800 text-xs text-zinc-400">Isolated Browser (Nix Environment)</div>
57
+ <div className="flex-1 flex items-center justify-center overflow-hidden">
58
+ {browserFrame ? (
59
+ <img src={`data:image/jpeg;base64,${browserFrame}`} className="max-w-full max-h-full shadow-2xl" />
60
+ ) : (
61
+ <div className="animate-pulse text-zinc-600">Waiting for browser stream...</div>
62
+ )}
63
+ </div>
64
+ </div>
65
+ </div>
66
+ );
67
+ }