Spaces:
Paused
Paused
File size: 4,109 Bytes
e6312c4 c5a51e4 e6312c4 17d50b3 c5a51e4 e6312c4 c5a51e4 e6312c4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 17d50b3 c5a51e4 e6312c4 c5a51e4 e6312c4 c5a51e4 17d50b3 c5a51e4 17d50b3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | import React, { useState, useEffect } from 'react';
import { FaRobot, FaSpinner, FaCheck, FaTimes } from 'react-icons/fa';
import axios from 'axios';
const AgentPanel: React.FC<{ projectPath: string }> = ({ projectPath }) => {
const [prompt, setPrompt] = useState('');
const [running, setRunning] = useState(false);
const [taskId, setTaskId] = useState<string | null>(null);
const [status, setStatus] = useState('');
const [logs, setLogs] = useState<string[]>([]);
const [pendingChanges, setPendingChanges] = useState<any[]>([]);
const [selectedModel, setSelectedModel] = useState('groq-llama-3.3-70b-versatile');
const [models, setModels] = useState<any[]>([]);
useEffect(() => {
axios.get('/api/models').then(res => setModels(res.data));
}, []);
const startTask = async () => {
setRunning(true);
setLogs([]);
setPendingChanges([]);
setStatus('running');
try {
const resp = await fetch('/api/agent/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, project_path: projectPath, model: selectedModel }),
});
const data = await resp.json();
setTaskId(data.task_id);
setStatus(data.status);
setLogs(data.logs || []);
setPendingChanges(data.pending_changes || []);
} catch (e) {
setLogs(['Error: ' + e]);
}
setRunning(false);
};
const approve = async () => {
if (!taskId) return;
try {
const resp = await fetch(`/api/agent/approve/${taskId}`, { method: 'POST' });
const data = await resp.json();
setStatus(data.status);
setLogs(prev => [...prev, ...(data.logs || [])]);
} catch (e) {}
};
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg-primary)', padding: 12 }}>
<div style={{ fontWeight: 600, marginBottom: 8 }}><FaRobot /> AI Agent</div>
<select
style={{ width: '100%', background: 'var(--bg-tertiary)', color: 'var(--text-primary)', border: '1px solid var(--border)', padding: '6px 8px', borderRadius: 6, marginBottom: 8 }}
value={selectedModel}
onChange={e => setSelectedModel(e.target.value)}
>
{models.map((m: any) => (
<option key={m.id} value={m.id}>{m.name}</option>
))}
</select>
<textarea
style={{ width: '100%', height: 60, background: 'var(--bg-tertiary)', color: 'var(--text-primary)', border: '1px solid var(--border)', borderRadius: 6, padding: 8, resize: 'vertical', marginBottom: 8 }}
value={prompt}
onChange={e => setPrompt(e.target.value)}
placeholder="E.g., 'Create a REST API for todos with a database'"
/>
<button
onClick={startTask}
disabled={running}
style={{ background: 'var(--accent)', color: 'white', padding: '6px 16px', borderRadius: 6, fontWeight: 600, marginBottom: 8 }}
>
{running ? <><FaSpinner className="spin" /> Running...</> : 'Start Agent'}
</button>
{status === 'awaiting_approval' && pendingChanges.length > 0 && (
<div style={{ marginBottom: 8 }}>
<div style={{ color: 'var(--warning)', marginBottom: 4 }}>Pending changes ({pendingChanges.length}):</div>
{pendingChanges.map((c, i) => (
<div key={i} style={{ fontSize: 12, marginBottom: 2 }}>
{c.action} – {c.filepath}
</div>
))}
<button onClick={approve} style={{ background: 'var(--success)', color: 'white', padding: '4px 12px', borderRadius: 4 }}>
<FaCheck /> Approve & Apply All
</button>
</div>
)}
<div style={{ flex: 1, overflowY: 'auto', fontFamily: 'monospace', fontSize: 12, whiteSpace: 'pre-wrap', background: 'var(--bg-secondary)', padding: 8, borderRadius: 4 }}>
{logs.map((log, i) => (
<div key={i}>• {log}</div>
))}
{status === 'completed' && <div style={{ color: 'var(--success)' }}>✅ Task completed.</div>}
</div>
</div>
);
};
export default AgentPanel; |