File size: 3,829 Bytes
4a5e2ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05ca0fc
4a5e2ac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05ca0fc
 
 
 
 
 
 
 
 
 
 
e63fc5a
 
 
0fa978f
 
 
 
 
 
 
 
 
 
 
e63fc5a
 
 
 
 
 
 
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
import streamlit as st
from src.main import run_sandbox


st.set_page_config(
    page_title="Agentic Coding Sandbox",
    page_icon=":zap:",
    layout="wide",
)

st.title("Self-Correcting Agentic Coding Sandbox")
st.markdown(
    "Submit a coding task. The system generates, executes, and autonomously debugs "
    "Python code in an isolated sandbox environment."
)

with st.sidebar:
    st.header("About")
    st.markdown(
        """
**Architecture:**
1. **Coder Agent** - generates Python code via LLM
2. **Sandbox Executor** - runs code in isolated environment
3. **Critic Agent** - analyzes errors and suggests fixes
4. **Retry Loop** - up to 3 self-healing attempts
"""
    )
    st.caption("Running on Hugging Face Spaces")

col1, col2 = st.columns([3, 2])

with col1:
    prompt = st.text_area(
        "Describe what you want the code to do:",
        height=150,
        key="prompt_input",
        placeholder="e.g., Plot a bar chart of the top 5 most frequent words in this text.",
    )

    if st.button("Run", type="primary", disabled=not prompt):
        with st.spinner("Generating code..."):
            try:
                result = run_sandbox(prompt)
                st.session_state["result"] = result
            except Exception as e:
                st.error(f"Error: {e}")

with col2:
    st.subheader("Result")

    if "result" in st.session_state:
        result = st.session_state["result"]
        retries = result.get("retries_used", 0)

        if result.get("success"):
            st.success(f"Succeeded ({retries} retries)")
        else:
            st.error(f"Failed ({retries} retries)")

        files = result.get("files", {})
        if files:
            for name, b64 in files.items():
                st.image(f"data:image/png;base64,{b64}", caption=name, use_container_width=True)

        output = result.get("output") or result.get("error") or "No output"
        if output.strip():
            st.code(output, language="text", line_numbers=True)
    else:
        st.info("Submit a prompt to see results here.")

st.divider()

st.subheader("Execution Trace")

if "result" in st.session_state:
    trace = st.session_state["result"].get("trace", [])
    if trace:
        for i, entry in enumerate(trace):
            node = entry.get("node", "?")
            retry = entry.get("retry", 0)

            with st.expander(f"Attempt {retry + 1} - {node}", expanded=True):
                st.json(entry)
    else:
        st.caption("No trace data available.")
else:
    st.caption("Run a prompt to see the execution trace.")

st.divider()

st.subheader("Try a Sample Prompt")

PRESET_PROMPTS = [
    "Use asyncio and aiohttp to fetch JSON from https://jsonplaceholder.typicode.com/todos/1 and print the title field.",
    "Generate a NumPy array of shape (5, 5) filled with random integers between 0 and 100, then compute the row-wise means.",
    "Plot a sine wave and a cosine wave on the same chart using matplotlib, add a legend, and save it to /tmp/waves.png.",
]

def _set_prompt(value: str):
    st.session_state.prompt_input = value

for i, p in enumerate(PRESET_PROMPTS):
    is_selected = st.session_state.get("prompt_input") == p
    border = "1px solid #6366f1" if is_selected else "1px solid #e2e8f0"
    st.markdown(
        f"<div style='border:{border};border-radius:8px;padding:12px 16px;margin-bottom:8px;display:flex;align-items:center;justify-content:space-between;'>"
        f"<span style='font-size:14px;flex:1;margin-right:12px;'>{p}</span>"
        f"</div>",
        unsafe_allow_html=True,
    )
    use_col1, use_col2, _ = st.columns([1, 1, 4])
    with use_col1:
        st.button(
            "Use this prompt",
            key=f"use_prompt_{i}",
            use_container_width=True,
            on_click=_set_prompt,
            args=(p,),
        )