CoolFace
Apppublic

Rahmath1/self_improving_agent

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
app.py395 linesDownload Raw Back to server
1import sys2import os3sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))4 5try:6    from openenv.core.env_server.http_server import create_app7except Exception as e:8    raise ImportError("openenv-core is required. Install with: pip install openenv-core") from e9 10from fastapi.responses import HTMLResponse11from fastapi import Request12from models import AdvanceAgentAction, AdvanceAgentObservation13from server.Advance_agent_environment import AdvanceAgentEnvironment14 15 16def env_factory() -> AdvanceAgentEnvironment:17    return AdvanceAgentEnvironment()18 19app = create_app(20    env=env_factory,21    action_cls=AdvanceAgentAction,22    observation_cls=AdvanceAgentObservation,23    env_name="Advance_agent_environment",24    max_concurrent_envs=1,25)26 27 28DASHBOARD_HTML = """<!DOCTYPE html>29<html>30<head>31    <title>πŸ€– EDA OpenEnv Dashboard</title>32    <style>33        * { box-sizing: border-box; margin: 0; padding: 0; }34        body { font-family: 'Segoe UI', Arial, sans-serif; background: #0f0f0f; color: #fff; padding: 20px; }35        h1 { color: #4fc3f7; margin-bottom: 4px; font-size: 24px; }36        .subtitle { color: #888; margin-bottom: 20px; font-size: 13px; }37        .row { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }38        .box { background: #1a1a2e; padding: 16px; border-radius: 10px; border: 1px solid #2a2a4a; flex: 1; min-width: 200px; }39        .box h3 { color: #4fc3f7; margin-bottom: 12px; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; }40        button { background: #4fc3f7; color: #000; border: none; padding: 9px 18px; border-radius: 6px; cursor: pointer; margin: 4px; font-size: 13px; font-weight: bold; transition: opacity 0.2s; }41        button:hover { opacity: 0.8; }42        .btn-green { background: #66bb6a; }43        .btn-orange { background: #ffa726; }44        .btn-red { background: #ef5350; color: white; }45        .btn-gray { background: #444; color: white; }46        select { background: #2a2a4a; color: white; border: 1px solid #444; padding: 8px 12px; border-radius: 6px; margin: 4px; font-size: 13px; }47        .pipeline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0; }48        .step-box { padding: 8px 14px; border-radius: 20px; font-size: 12px; font-weight: bold; border: 2px solid #444; color: #888; transition: all 0.3s; }49        .step-done { background: #1b5e20; border-color: #66bb6a; color: #66bb6a; }50        .step-next { background: #1a237e; border-color: #4fc3f7; color: #4fc3f7; animation: pulse 1.5s infinite; }51        .step-pending { background: #1a1a1a; border-color: #333; color: #555; }52        .arrow { color: #444; font-size: 18px; }53        @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.5; } }54        .metric { text-align: center; padding: 10px; }55        .metric-val { font-size: 32px; font-weight: bold; color: #4fc3f7; }56        .metric-val.good { color: #66bb6a; }57        .metric-val.bad { color: #ef5350; }58        .metric-label { font-size: 11px; color: #888; margin-top: 4px; text-transform: uppercase; }59        .task-badge { display: inline-block; padding: 6px 14px; border-radius: 20px; font-size: 13px; font-weight: bold; margin: 6px 0; }60        .easy { background: #1b5e20; color: #66bb6a; }61        .medium { background: #e65100; color: #ffa726; }62        .hard { background: #b71c1c; color: #ef9a9a; }63        .log { background: #0a0a1a; padding: 12px; border-radius: 8px; height: 180px; overflow-y: auto; font-family: monospace; font-size: 12px; color: #00ff00; border: 1px solid #1a1a3a; }64        .log .warn { color: #ffa726; }65        .log .error { color: #ef5350; }66        .log .success { color: #66bb6a; }67        .log .info { color: #4fc3f7; }68        .dataset-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; }69        .dataset-table th { background: #1a237e; padding: 6px 10px; text-align: left; color: #4fc3f7; }70        .dataset-table td { padding: 5px 10px; border-bottom: 1px solid #1a1a3a; color: #ccc; }71        .dataset-table tr:hover td { background: #1a1a3a; }72        .reward-bar { height: 8px; background: #1a1a3a; border-radius: 4px; margin-top: 6px; overflow: hidden; }73        .reward-fill { height: 100%; background: linear-gradient(90deg, #4fc3f7, #66bb6a); border-radius: 4px; transition: width 0.5s; }74        .history-item { padding: 6px 10px; margin: 3px 0; border-radius: 6px; font-size: 12px; display: flex; justify-content: space-between; }75        .history-ok { background: #0d2818; border-left: 3px solid #66bb6a; }76        .history-pen { background: #2d0d0d; border-left: 3px solid #ef5350; }77        .cols-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }78        .col-tag { background: #1a237e; color: #4fc3f7; padding: 3px 10px; border-radius: 12px; font-size: 11px; }79        #spinner { display: none; color: #ffa726; font-size: 13px; margin-left: 8px; }80    </style>81</head>82<body>83<h1>πŸ€– EDA OpenEnv Agent Dashboard</h1>84<p class="subtitle">Meta PyTorch OpenEnv Hackathon β€” Real-world RL environment for Exploratory Data Analysis</p>85 86<!-- Controls -->87<div class="row">88    <div class="box" style="flex: 2">89        <h3>βš™οΈ Controls</h3>90        <div style="display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin-bottom:10px">91            <select id="taskSelect">92                <option value="">🎲 Random Task</option>93                <option value="detect_missing">🟒 detect_missing (easy)</option>94                <option value="find_correlation">🟑 find_correlation (medium)</option>95                <option value="generate_insight">πŸ”΄ generate_insight (hard)</option>96            </select>97            <button onclick="resetEnv()" class="btn-green">πŸ”„ Reset</button>98            <button onclick="autoPlay()" class="btn-orange">⚑ Auto Play</button>99            <button onclick="stopAuto()" class="btn-gray">⏹ Stop</button>100            <span id="spinner">⏳ Running...</span>101        </div>102        <div style="margin-bottom:8px">103            <select id="actionSelect">104                <option value="clean_data">clean_data</option>105                <option value="eda">eda</option>106                <option value="feature_engineering">feature_engineering</option>107                <option value="train_model">train_model</option>108                <option value="missing">missing</option>109                <option value="correlation">correlation</option>110                <option value="insight">insight</option>111            </select>112            <button onclick="takeStep()" class="btn-blue" style="background:#4fc3f7">▢️ Step</button>113        </div>114    </div>115 116    <!-- Task Info -->117    <div class="box">118        <h3>🎯 Current Task</h3>119        <div id="taskBadge" class="task-badge easy">β€”</div>120        <p style="font-size:12px; color:#aaa; margin-top:8px" id="taskObjective">Reset to start a new episode</p>121    </div>122 123    <!-- Score -->124    <div class="box">125        <h3>πŸ† Score</h3>126        <div class="row" style="gap:0; margin:0">127            <div class="metric">128                <div class="metric-val" id="totalReward">β€”</div>129                <div class="metric-label">Cumulative Reward</div>130            </div>131            <div class="metric">132                <div class="metric-val" id="stepCount">0</div>133                <div class="metric-label">Steps Taken</div>134            </div>135        </div>136        <div class="reward-bar"><div class="reward-fill" id="rewardBar" style="width:0%"></div></div>137    </div>138</div>139 140<!-- Pipeline Progress -->141<div class="box" style="margin-bottom:16px">142    <h3>πŸ—ΊοΈ Pipeline Progress</h3>143    <div class="pipeline" id="pipeline">144        <div class="step-box step-next" id="pipe_clean_data">clean_data</div>145        <div class="arrow">β†’</div>146        <div class="step-box step-pending" id="pipe_eda">eda</div>147        <div class="arrow">β†’</div>148        <div class="step-box step-pending" id="pipe_feature_engineering">feature_engineering</div>149        <div class="arrow">β†’</div>150        <div class="step-box step-pending" id="pipe_train_model">train_model</div>151        <div class="arrow">β†’</div>152        <div class="step-box step-pending" id="pipe_task_action">task action</div>153    </div>154</div>155 156<!-- Main content -->157<div class="row">158    <!-- Dataset -->159    <div class="box" style="flex:2">160        <h3>πŸ“Š Dataset Preview</h3>161        <div id="colsList" class="cols-list"></div>162        <div style="overflow-x:auto; margin-top:10px">163            <table class="dataset-table" id="dataTable">164                <tr><td colspan="5" style="color:#555; text-align:center; padding:20px">Reset to load dataset</td></tr>165            </table>166        </div>167    </div>168 169    <!-- Step History -->170    <div class="box">171        <h3>πŸ“œ Step History</h3>172        <div id="historyList" style="max-height:220px; overflow-y:auto">173            <p style="color:#555; font-size:12px; text-align:center; padding:20px">No steps yet</p>174        </div>175    </div>176</div>177 178<!-- Log -->179<div class="box">180    <h3>πŸ“‹ Log</h3>181    <div class="log" id="log">Waiting for reset...\n</div>182</div>183 184<script>185const PIPELINE = ['clean_data','eda','feature_engineering','train_model'];186const TASK_ACTIONS = {detect_missing:'missing', find_correlation:'correlation', generate_insight:'insight'};187let history = [];188let autoTimer = null;189let stepNum = 0;190let currentTask = '';191let totalReward = 0;192 193function log(msg, cls='') {194    const el = document.getElementById('log');195    const line = cls ? `<span class="${cls}">${msg}</span>` : msg;196    el.innerHTML += line + '\\n';197    el.scrollTop = el.scrollHeight;198}199 200function getCompleted() {201    return history.filter(h => !h.is_penalty).map(h => h.action);202}203 204function updatePipeline() {205    const completed = getCompleted();206    const nextIdx = PIPELINE.findIndex(s => !completed.includes(s));207    const pipelineDone = nextIdx === -1;208 209    PIPELINE.forEach((s, i) => {210        const el = document.getElementById('pipe_' + s);211        if (!el) return;212        el.className = 'step-box';213        if (completed.includes(s)) el.classList.add('step-done');214        else if (i === nextIdx) el.classList.add('step-next');215        else el.classList.add('step-pending');216    });217 218    const taskEl = document.getElementById('pipe_task_action');219    const taskAction = TASK_ACTIONS[currentTask] || 'task action';220    taskEl.textContent = taskAction;221    if (pipelineDone && completed.includes(taskAction)) {222        taskEl.className = 'step-box step-done';223    } else if (pipelineDone) {224        taskEl.className = 'step-box step-next';225    } else {226        taskEl.className = 'step-box step-pending';227    }228 229    // Auto-select next action230    if (!pipelineDone) {231        document.getElementById('actionSelect').value = PIPELINE[nextIdx];232    } else {233        document.getElementById('actionSelect').value = taskAction;234    }235}236 237function renderDataset(obs) {238    if (!obs || !obs.columns) return;239 240    // Columns241    const colsEl = document.getElementById('colsList');242    colsEl.innerHTML = obs.columns.map(c => `<span class="col-tag">${c}</span>`).join('');243 244    // Table245    const table = document.getElementById('dataTable');246    const headers = obs.columns.map(c => `<th>${c}</th>`).join('');247    const rows = (obs.dataset_head || []).map(row => {248        const cells = obs.columns.map(c => {249            const v = row[c];250            const display = v === null || v === undefined ? '<span style="color:#ef5350">NaN</span>' : v;251            return `<td>${display}</td>`;252        }).join('');253        return `<tr>${cells}</tr>`;254    }).join('');255    table.innerHTML = `<tr>${headers}</tr>${rows}`;256}257 258function updateStats(reward, done) {259    stepNum++;260    totalReward += reward;261    const display = totalReward.toFixed(4);262    const el = document.getElementById('totalReward');263    el.textContent = display;264    el.className = 'metric-val ' + (totalReward > 0 ? 'good' : 'bad');265    document.getElementById('stepCount').textContent = stepNum;266    // Bar: normalise to 0-100% assuming max ~5267    const pct = Math.min(100, Math.max(0, (totalReward / 3) * 100));268    document.getElementById('rewardBar').style.width = pct + '%';269}270 271function addHistoryItem(action, reward, is_penalty, feedback) {272    const list = document.getElementById('historyList');273    if (list.querySelector('p')) list.innerHTML = '';274    const cls = is_penalty ? 'history-pen' : 'history-ok';275    const icon = is_penalty ? '⚠️' : 'βœ…';276    const item = document.createElement('div');277    item.className = 'history-item ' + cls;278    item.innerHTML = `<span>${icon} <b>${action}</b></span><span style="color:${is_penalty?'#ef5350':'#66bb6a'}">${reward.toFixed(4)}</span>`;279    list.appendChild(item);280    list.scrollTop = list.scrollHeight;281}282 283async function resetEnv() {284    stopAuto();285    history = []; stepNum = 0; totalReward = 0;286    document.getElementById('historyList').innerHTML = '<p style="color:#555; font-size:12px; text-align:center; padding:20px">No steps yet</p>';287    document.getElementById('totalReward').textContent = 'β€”';288    document.getElementById('stepCount').textContent = '0';289    document.getElementById('rewardBar').style.width = '0%';290    document.getElementById('log').innerHTML = '';291 292    const taskName = document.getElementById('taskSelect').value;293    const body = taskName ? JSON.stringify({task_name: taskName}) : JSON.stringify({});294 295    log('πŸ”„ Resetting environment...', 'info');296    try {297        const res = await fetch('/reset', {298            method: 'POST',299            headers: {'Content-Type':'application/json'},300            body: body301        });302        const data = await res.json();303        const obs = data.observation || data;304        currentTask = obs.task || '';305 306        // Task badge307        const diff = obs.difficulty || 'easy';308        const badge = document.getElementById('taskBadge');309        badge.textContent = (diff === 'easy' ? '🟒' : diff === 'medium' ? '🟑' : 'πŸ”΄') + ' ' + (obs.task || 'β€”');310        badge.className = 'task-badge ' + diff;311        document.getElementById('taskObjective').textContent = obs.objective || '';312 313        renderDataset(obs);314        updatePipeline();315        log(`βœ… Reset done! Task: ${obs.task} | Difficulty: ${obs.difficulty}`, 'success');316    } catch(e) {317        log('❌ Reset failed: ' + e, 'error');318    }319}320 321async function takeStep(autoAction) {322    const action = autoAction || document.getElementById('actionSelect').value;323    document.getElementById('spinner').style.display = 'inline';324    try {325        const res = await fetch('/step', {326            method: 'POST',327            headers: {'Content-Type':'application/json'},328            body: JSON.stringify({action: {action_type: action}})329        });330        const data = await res.json();331        const obs = data.observation || data;332        const reward = data.reward ?? obs.reward ?? 0;333        const done = data.done ?? obs.done ?? false;334 335        // Detect penalty (negative or small reward with wrong order)336        const is_penalty = reward < 0.1 && action !== TASK_ACTIONS[currentTask] && !PIPELINE.includes(action);337 338        history.push({action, reward, is_penalty});339        addHistoryItem(action, reward, is_penalty, '');340        updateStats(reward, done);341        renderDataset(obs);342        updatePipeline();343 344        const icon = done ? '🏁' : (reward >= 0.5 ? 'βœ…' : '⚠️');345        log(`${icon} Step ${stepNum}: ${action} β†’ reward=${reward.toFixed(4)} done=${done}`, reward < 0.1 ? 'warn' : 'success');346 347        if (done) {348            log(`πŸ† Episode complete! Total reward: ${totalReward.toFixed(4)}`, 'success');349            stopAuto();350        }351    } catch(e) {352        log('❌ Step failed: ' + e, 'error');353    }354    document.getElementById('spinner').style.display = 'none';355}356 357function getNextAction() {358    const completed = getCompleted();359    const nextPipe = PIPELINE.find(s => !completed.includes(s));360    if (nextPipe) return nextPipe;361    return TASK_ACTIONS[currentTask] || 'missing';362}363 364function autoPlay() {365    if (autoTimer) return;366    log('⚑ Auto-play started...', 'info');367    autoTimer = setInterval(() => takeStep(getNextAction()), 1200);368}369 370function stopAuto() {371    if (autoTimer) { clearInterval(autoTimer); autoTimer = null; log('⏹ Stopped.', 'warn'); }372}373 374window.onload = () => resetEnv();375</script>376</body>377</html>"""378 379 380@app.get("/dashboard", response_class=HTMLResponse)381def dashboard():382    return HTMLResponse(content=DASHBOARD_HTML)383 384 385def main(host: str = "0.0.0.0", port: int = 8000):386    import uvicorn387    uvicorn.run(app, host=host, port=port)388 389 390if __name__ == "__main__":391    import argparse392    parser = argparse.ArgumentParser()393    parser.add_argument("--port", type=int, default=8000)394    args = parser.parse_args()395    main(port=args.port)