File size: 4,987 Bytes
c89cc5d
c3b3cde
f313f73
d4507be
4eb1eda
c89cc5d
4eb1eda
 
 
f313f73
c2302aa
 
aba9687
 
3270d87
 
4eb1eda
 
 
f313f73
 
 
 
 
 
 
3270d87
4eb1eda
f313f73
4eb1eda
 
 
d4507be
 
4eb1eda
d4507be
4eb1eda
fc4d50b
1c2ae2e
4eb1eda
d4507be
 
 
 
 
 
f313f73
4eb1eda
 
3270d87
d4507be
3270d87
4eb1eda
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d4507be
3270d87
f313f73
4eb1eda
 
 
 
 
 
 
f313f73
4eb1eda
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f313f73
 
d4507be
b8b372f
fc4d50b
f313f73
f28460b
 
e5c4640
f313f73
fc4d50b
 
f28460b
4eb1eda
 
 
 
 
 
 
 
 
 
 
f313f73
 
1c2ae2e
 
 
4eb1eda
1c2ae2e
4eb1eda
1c2ae2e
 
 
 
 
4eb1eda
1c2ae2e
 
 
 
 
4eb1eda
1c2ae2e
4eb1eda
1c2ae2e
 
 
f313f73
4eb1eda
 
 
d4507be
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import gradio as gr
from gradio_client import Client
import random
import time
import threading

# -------------------------
# Backend HF clients
# -------------------------
backend_engines = [
    Client("ChocoLaboratory/SANDBOX_BACKEND"),
    Client("ChocoLaboratory/SANDBOXBACKEND2")
]

SANDBOX_TTL_SEC = 2 * 3600  # 2 hours

# -------------------------
# Helper functions
# -------------------------
def pick_engine():
    return random.choice(backend_engines)

def launch_sandbox(code):
    engine = pick_engine()
    result = engine.predict(code=code, api_name="/launch_sandbox")
    sandbox_id = result if isinstance(result, str) else result.get("sandbox_id", "unknown")
    start_time = time.time()
    return f"Sandbox launched! ID: {sandbox_id}\n", sandbox_id, start_time, engine

def fetch_logs(sandbox_id, engine):
    if not sandbox_id or not engine:
        return "No sandbox ID. Launch a sandbox first!"
    try:
        logs = engine.predict(api_name="/fetch_logs")
        return logs
    except Exception as e:
        return f"Error fetching logs: {e}"

def kill_sandbox(sandbox_id, engine):
    if not sandbox_id or not engine:
        return "No sandbox ID to kill."
    try:
        result = engine.predict(api_name="/kill_sandbox")
        return result
    except Exception as e:
        return f"Error: {e}"

def status_sandbox(sandbox_id, start_time, engine):
    if not sandbox_id or not engine:
        return "No sandbox ID.", "0:00"
    try:
        status = engine.predict(api_name="/status_sandbox")
    except:
        status = "Unknown"
    elapsed = int(time.time() - start_time)
    remaining = max(0, SANDBOX_TTL_SEC - elapsed)
    minutes, seconds = divmod(remaining, 60)
    time_str = f"{minutes:02d}:{seconds:02d}"
    return status, time_str

def run_command(cmd, sandbox_id, start_time, engine):
    if not sandbox_id or not engine:
        return "No sandbox ID. Launch a sandbox first!", "0:00"
    try:
        engine.predict(code=cmd, api_name="/launch_sandbox")  # ideally /run_command
        logs, time_str = status_and_logs(sandbox_id, start_time, engine)
        return logs, time_str
    except Exception as e:
        return f"Error: {e}", "0:00"

def status_and_logs(sandbox_id, start_time, engine):
    logs = fetch_logs(sandbox_id, engine)
    _, time_str = status_sandbox(sandbox_id, start_time, engine)
    return logs, time_str

# -------------------------
# Auto-update logs thread
# -------------------------
def start_auto_update(terminal_output, sandbox_id_box, start_time_state, sandbox_backend_state, time_remaining):
    def updater():
        while True:
            sandbox_id = sandbox_id_box.value
            start_time = start_time_state.value
            engine = sandbox_backend_state.value
            if sandbox_id and engine:
                logs, time_str = status_and_logs(sandbox_id, start_time, engine)
                terminal_output.value = logs
                time_remaining.value = time_str
            time.sleep(1)
    threading.Thread(target=updater, daemon=True).start()

# -------------------------
# Gradio UI
# -------------------------
with gr.Blocks() as demo:

    with gr.Row():
        # Terminal Column
        with gr.Column(scale=3):
            gr.Markdown("### 🖥 Sandbox Cloud Console")
            terminal_output = gr.Textbox(label="", lines=20, interactive=False)
            command_input = gr.Textbox(label="Command Input", placeholder="echo SandBox!", interactive=True)
            run_btn = gr.Button("Run Command")
        
        # Side Panel
        with gr.Column(scale=1):
            gr.Markdown("### Sandbox Controls")
            launch_btn = gr.Button("Launch Sandbox")
            kill_btn = gr.Button("Kill Sandbox")
            status_btn = gr.Button("Check Status")
            sandbox_id_box = gr.Textbox(label="Sandbox ID", interactive=False)
            time_remaining = gr.Textbox(label="Time Remaining", interactive=False)
            gr.Markdown("💡 Running on a Debian-based HF container!")

    # States
    start_time_state = gr.State(value=0)
    sandbox_backend_state = gr.State(value=None)

    # Callbacks
    launch_btn.click(
        launch_sandbox,
        inputs=command_input,
        outputs=[terminal_output, sandbox_id_box, start_time_state, sandbox_backend_state]
    )

    run_btn.click(
        run_command,
        inputs=[command_input, sandbox_id_box, start_time_state, sandbox_backend_state],
        outputs=[terminal_output, time_remaining]
    )

    kill_btn.click(
        kill_sandbox,
        inputs=[sandbox_id_box, sandbox_backend_state],
        outputs=terminal_output
    )

    status_btn.click(
        status_sandbox,
        inputs=[sandbox_id_box, start_time_state, sandbox_backend_state],
        outputs=[terminal_output, time_remaining]
    )

    # Start auto-update logs thread
    start_auto_update(terminal_output, sandbox_id_box, start_time_state, sandbox_backend_state, time_remaining)

demo.launch()