Spaces:
Sleeping
Sleeping
New UI animations!
Browse files
app.py
CHANGED
|
@@ -8,6 +8,7 @@ import json
|
|
| 8 |
import time
|
| 9 |
import base64
|
| 10 |
import tempfile
|
|
|
|
| 11 |
from datetime import datetime, timedelta
|
| 12 |
from openai import OpenAI
|
| 13 |
|
|
@@ -46,7 +47,12 @@ SESSION_TIMEOUT_SEC = 15 * 60
|
|
| 46 |
def clean_thought_process(text):
|
| 47 |
"""Removes the <think>...</think> blocks from the text to prevent leaks."""
|
| 48 |
if not text: return ""
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
def export_script(code):
|
| 52 |
if not code.strip(): return None
|
|
@@ -67,44 +73,37 @@ def detect_language(filename):
|
|
| 67 |
return "python"
|
| 68 |
|
| 69 |
def robust_search(query):
|
| 70 |
-
if not SEARCH_AVAILABLE: return
|
| 71 |
try:
|
| 72 |
results = []
|
| 73 |
with DDGS() as ddgs:
|
| 74 |
-
# Fetch 5 results
|
| 75 |
ddg_gen = ddgs.text(query, max_results=5)
|
| 76 |
if ddg_gen:
|
| 77 |
for r in ddg_gen:
|
| 78 |
-
results.append({
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
})
|
| 83 |
-
return json.dumps(results, indent=2)
|
| 84 |
except Exception as e:
|
| 85 |
-
return
|
| 86 |
|
| 87 |
# ==================== TOOL: E2B SANDBOX (POLYGLOT) ====================
|
| 88 |
|
| 89 |
def execute_code_e2b(project_state, mode="Code Mode"):
|
| 90 |
"""
|
| 91 |
Polymorphic execution engine with Mode-Gated Internet Access.
|
| 92 |
-
- Web Mode: Internet ON
|
| 93 |
-
- Other Modes: Internet OFF (Air-gapped)
|
| 94 |
"""
|
| 95 |
if not E2B_AVAILABLE or not E2B_API_KEY:
|
| 96 |
return "❌ Error: E2B API Key missing. Cannot execute code."
|
| 97 |
|
| 98 |
-
# Gate Internet Access based on Mode
|
| 99 |
enable_internet = (mode == "Web Mode")
|
| 100 |
-
|
| 101 |
logger.info(f"⚡ Executing in E2B Sandbox (Mode: {mode}, Internet: {enable_internet})...")
|
| 102 |
|
| 103 |
try:
|
| 104 |
with Sandbox.create(allow_internet_access=enable_internet) as sandbox:
|
| 105 |
# 1. Write all auxiliary files to the sandbox filesystem
|
| 106 |
for filename, content in project_state.items():
|
| 107 |
-
if filename not in ["main.py", "main.cpp"]:
|
| 108 |
sandbox.files.write(filename, content)
|
| 109 |
|
| 110 |
output_log = ""
|
|
@@ -115,7 +114,7 @@ def execute_code_e2b(project_state, mode="Code Mode"):
|
|
| 115 |
if "main.cpp" in project_state:
|
| 116 |
logger.info("⚙️ Detected C++ Project. Compiling via Python wrapper...")
|
| 117 |
|
| 118 |
-
# Write C++ source
|
| 119 |
sandbox.files.write("main.cpp", project_state["main.cpp"])
|
| 120 |
|
| 121 |
# Trojan Horse: Use Python to manage the compilation process reliably
|
|
@@ -140,7 +139,7 @@ else:
|
|
| 140 |
"""
|
| 141 |
execution = sandbox.run_code(cpp_runner_script)
|
| 142 |
|
| 143 |
-
#
|
| 144 |
if execution.logs.stdout:
|
| 145 |
output_log += "".join(execution.logs.stdout) + "\n"
|
| 146 |
if execution.logs.stderr:
|
|
@@ -155,7 +154,6 @@ else:
|
|
| 155 |
|
| 156 |
execution = sandbox.run_code(code_to_run)
|
| 157 |
|
| 158 |
-
# FIXED: Properly join list of strings
|
| 159 |
if execution.logs.stdout:
|
| 160 |
log_str = "".join(execution.logs.stdout)
|
| 161 |
output_log += f"📄 **STDOUT**:\n```\n{log_str}\n```"
|
|
@@ -202,7 +200,7 @@ CRITICAL INSTRUCTIONS:
|
|
| 202 |
elif mode == "Visualization Mode":
|
| 203 |
return base_prompt + "\n\nMODE: VISUALIZATION\n- Focus on matplotlib/seaborn.\n- Create visually striking plots.\n- NO INTERNET ACCESS."
|
| 204 |
elif mode == "Web Mode":
|
| 205 |
-
return base_prompt + "\n\nMODE: WEB ARCHITECT\n- Focus on modern web technologies (Flask, HTML, CSS).\n- **YOU HAVE INTERNET ACCESS**.
|
| 206 |
elif mode == "C++ Mode":
|
| 207 |
return base_prompt + "\n\nMODE: C++ DEVELOPER\n- Focus on modern C++ (17/20).\n- Use iostream, vector, string.\n- Ensure code compiles with g++.\n- NO INTERNET ACCESS."
|
| 208 |
else: # Code Mode
|
|
@@ -215,7 +213,8 @@ def parse_code_update(text, current_project, active_file):
|
|
| 215 |
"""
|
| 216 |
clean_text = clean_thought_process(text)
|
| 217 |
|
| 218 |
-
#
|
|
|
|
| 219 |
pattern = (
|
| 220 |
r"```" # Opening backticks
|
| 221 |
r"(?:python|cpp|c\+\+|javascript|html|css)?" # Optional language identifier
|
|
@@ -247,11 +246,14 @@ def process_query(user_input, session_data, project_state, active_file, mode):
|
|
| 247 |
yield history, project_state, project_state[active_file], session_data
|
| 248 |
return
|
| 249 |
|
|
|
|
| 250 |
history.append({"role": "user", "content": user_input})
|
| 251 |
history.append({"role": "assistant", "content": f"🧠 *Fyodor is thinking in {mode}...*"})
|
| 252 |
|
|
|
|
| 253 |
yield history, project_state, project_state[active_file], session_data
|
| 254 |
|
|
|
|
| 255 |
sys_prompt = get_system_prompt(mode)
|
| 256 |
|
| 257 |
project_context = "\n\n=== CURRENT PROJECT FILES ===\n"
|
|
@@ -260,6 +262,7 @@ def process_query(user_input, session_data, project_state, active_file, mode):
|
|
| 260 |
|
| 261 |
messages = [{"role": "system", "content": sys_prompt + project_context}]
|
| 262 |
|
|
|
|
| 263 |
for msg in history[:-2][-8:]:
|
| 264 |
if isinstance(msg, dict):
|
| 265 |
if msg['role'] == 'user':
|
|
@@ -312,7 +315,6 @@ def manual_run_project(project_state, session_data, mode):
|
|
| 312 |
if session_data is None: session_data = init_session()
|
| 313 |
history = session_data["history"]
|
| 314 |
history.append({"role": "user", "content": "▶️ **Run Project (Manual)**"})
|
| 315 |
-
# PASS MODE TO EXECUTOR
|
| 316 |
result = execute_code_e2b(project_state, mode=mode)
|
| 317 |
history.append({"role": "assistant", "content": f"**Execution Result:**\n\n{result}"})
|
| 318 |
return history, session_data
|
|
@@ -324,7 +326,7 @@ def run_code_review(code, session_data):
|
|
| 324 |
history.append({"role": "assistant", "content": "🤔 *Reviewing...*"})
|
| 325 |
|
| 326 |
messages = [
|
| 327 |
-
{"role": "system", "content": "
|
| 328 |
{"role": "user", "content": code}
|
| 329 |
]
|
| 330 |
try:
|
|
@@ -336,6 +338,11 @@ def run_code_review(code, session_data):
|
|
| 336 |
history[-1]["content"] = f"❌ Review Failed: {e}"
|
| 337 |
return history, session_data
|
| 338 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
def update_active_file(selected_file, project_data):
|
| 340 |
lang = detect_language(selected_file)
|
| 341 |
return gr.update(value=project_data.get(selected_file, ""), language=lang)
|
|
@@ -379,10 +386,11 @@ body, .gradio-container { background-color: var(--bg-dark) !important; color: va
|
|
| 379 |
.chatbot .bot.message { background-color: transparent !important; border-left: 2px solid #333 !important; }
|
| 380 |
textarea, input[type="text"] { background-color: #3c3c3c !important; border: 1px solid #3c3c3c !important; color: #fff !important; border-radius: 2px !important; }
|
| 381 |
textarea:focus, input[type="text"]:focus { border-color: var(--accent) !important; box-shadow: 0 0 0 1px var(--accent) !important; }
|
| 382 |
-
button { border-radius: 2px !important; text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; font-size: 12px !important; }
|
| 383 |
button.primary { background: var(--accent) !important; color: #fff !important; border: none !important; }
|
|
|
|
| 384 |
button.secondary { background: #333 !important; color: #fff !important; border: 1px solid #444 !important; }
|
| 385 |
-
button:hover {
|
| 386 |
.cm-editor { border: 1px solid var(--border-col) !important; border-radius: 0 !important; }
|
| 387 |
#top-bar { background-color: var(--sidebar-bg); border-bottom: 1px solid var(--border-col); min-height: 50px; padding: 0 10px !important; display: flex; align-items: center; justify-content: space-between; }
|
| 388 |
h1 { font-size: 1.2rem !important; color: var(--text-main) !important; font-weight: normal !important; margin: 0 !important; padding: 0 !important; background-color: transparent !important; border: none !important; display: flex; align-items: center; }
|
|
@@ -404,14 +412,16 @@ def run_app():
|
|
| 404 |
sidebar_visible = gr.State(True)
|
| 405 |
|
| 406 |
with gr.Column(elem_classes="main-panel"):
|
|
|
|
| 407 |
with gr.Row(elem_id="top-bar"):
|
| 408 |
with gr.Row(scale=1): gr.Markdown("# FYODOR IDE // PRO")
|
| 409 |
with gr.Row(scale=1):
|
| 410 |
sidebar_toggle_btn = gr.Button("👁️ Toggle Sidebar", size="sm", variant="secondary")
|
| 411 |
timer_display = gr.Textbox(value="READY", show_label=False, interactive=False, container=False, elem_classes="status-label")
|
| 412 |
|
|
|
|
| 413 |
with gr.Row():
|
| 414 |
-
#
|
| 415 |
with gr.Column(scale=4):
|
| 416 |
with gr.Row(elem_classes="file-tabs"):
|
| 417 |
file_dropdown = gr.Dropdown(choices=["main.py"], value="main.py", show_label=False, container=False, scale=2)
|
|
@@ -425,13 +435,14 @@ def run_app():
|
|
| 425 |
run_manual_btn = gr.Button("▶ EXECUTE SCRIPT", variant="primary")
|
| 426 |
review_btn = gr.Button("🕵 REVIEW CODE", size="sm", variant="secondary")
|
| 427 |
|
| 428 |
-
#
|
| 429 |
with gr.Column(scale=2):
|
| 430 |
mode_radio = gr.Radio(choices=["Code Mode", "C++ Mode", "Data Mode", "Web Mode"], value="Code Mode", label="SYSTEM MODE", elem_classes="mode-radio")
|
| 431 |
chatbot = gr.Chatbot(label="TERMINAL", height=600, render_markdown=True, elem_classes="chatbot", show_label=False)
|
| 432 |
with gr.Row():
|
| 433 |
msg_input = gr.Textbox(placeholder="Type command...", show_label=False, scale=4, container=False)
|
| 434 |
run_btn = gr.Button("RUN", variant="primary", scale=1)
|
|
|
|
| 435 |
|
| 436 |
# RIGHT: SIDEBAR
|
| 437 |
with gr.Column(scale=1, min_width=250, visible=True) as sidebar_col:
|
|
@@ -465,17 +476,16 @@ def run_app():
|
|
| 465 |
run_btn.click(process_query, [msg_input, session_state, project_state, active_file_state, mode_radio], [chatbot, project_state, code_editor, session_state])
|
| 466 |
|
| 467 |
file_dropdown.change(update_active_file, [file_dropdown, project_state], [code_editor]).then(lambda f: f, [file_dropdown], [active_file_state])
|
| 468 |
-
|
| 469 |
code_editor.change(save_file_change, [code_editor, active_file_state, project_state], [project_state])
|
| 470 |
save_btn.click(manual_save_file, [code_editor, active_file_state, project_state], [project_state])
|
| 471 |
-
|
| 472 |
-
# New File: Updates Dropdown, Project State, and Code Editor (Value+Lang)
|
| 473 |
new_file_btn.click(create_new_file, [new_file_txt, project_state], [file_dropdown, project_state, code_editor])
|
| 474 |
|
| 475 |
-
# PASS MODE RADIO TO MANUAL RUN
|
| 476 |
run_manual_btn.click(manual_run_project, [project_state, session_state, mode_radio], [chatbot, session_state])
|
| 477 |
review_btn.click(run_code_review, [code_editor, session_state], [chatbot, session_state])
|
| 478 |
|
|
|
|
|
|
|
|
|
|
| 479 |
mini_input.submit(lambda m, h: (h or []) + [{"role": "user", "content": m}, {"role": "assistant", "content": robust_search(m)}], [mini_input, mini_chat], [mini_chat])
|
| 480 |
mini_btn.click(lambda m, h: (h or []) + [{"role": "user", "content": m}, {"role": "assistant", "content": robust_search(m)}], [mini_input, mini_chat], [mini_chat])
|
| 481 |
|
|
|
|
| 8 |
import time
|
| 9 |
import base64
|
| 10 |
import tempfile
|
| 11 |
+
import subprocess
|
| 12 |
from datetime import datetime, timedelta
|
| 13 |
from openai import OpenAI
|
| 14 |
|
|
|
|
| 47 |
def clean_thought_process(text):
|
| 48 |
"""Removes the <think>...</think> blocks from the text to prevent leaks."""
|
| 49 |
if not text: return ""
|
| 50 |
+
# Remove completed blocks
|
| 51 |
+
text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
|
| 52 |
+
# Remove pending/unclosed blocks
|
| 53 |
+
if "<think>" in text:
|
| 54 |
+
text = text.split("<think>")[0]
|
| 55 |
+
return text.strip()
|
| 56 |
|
| 57 |
def export_script(code):
|
| 58 |
if not code.strip(): return None
|
|
|
|
| 73 |
return "python"
|
| 74 |
|
| 75 |
def robust_search(query):
|
| 76 |
+
if not SEARCH_AVAILABLE: return "Error: Missing duckduckgo-search"
|
| 77 |
try:
|
| 78 |
results = []
|
| 79 |
with DDGS() as ddgs:
|
|
|
|
| 80 |
ddg_gen = ddgs.text(query, max_results=5)
|
| 81 |
if ddg_gen:
|
| 82 |
for r in ddg_gen:
|
| 83 |
+
results.append(f"### [{r.get('title')}]({r.get('href')})\n{r.get('body')}\n")
|
| 84 |
+
|
| 85 |
+
if not results: return "⚠️ No results found."
|
| 86 |
+
return "\n".join(results)
|
|
|
|
|
|
|
| 87 |
except Exception as e:
|
| 88 |
+
return f"❌ Search Error: {str(e)}"
|
| 89 |
|
| 90 |
# ==================== TOOL: E2B SANDBOX (POLYGLOT) ====================
|
| 91 |
|
| 92 |
def execute_code_e2b(project_state, mode="Code Mode"):
|
| 93 |
"""
|
| 94 |
Polymorphic execution engine with Mode-Gated Internet Access.
|
|
|
|
|
|
|
| 95 |
"""
|
| 96 |
if not E2B_AVAILABLE or not E2B_API_KEY:
|
| 97 |
return "❌ Error: E2B API Key missing. Cannot execute code."
|
| 98 |
|
|
|
|
| 99 |
enable_internet = (mode == "Web Mode")
|
|
|
|
| 100 |
logger.info(f"⚡ Executing in E2B Sandbox (Mode: {mode}, Internet: {enable_internet})...")
|
| 101 |
|
| 102 |
try:
|
| 103 |
with Sandbox.create(allow_internet_access=enable_internet) as sandbox:
|
| 104 |
# 1. Write all auxiliary files to the sandbox filesystem
|
| 105 |
for filename, content in project_state.items():
|
| 106 |
+
if filename not in ["main.py", "main.cpp"]:
|
| 107 |
sandbox.files.write(filename, content)
|
| 108 |
|
| 109 |
output_log = ""
|
|
|
|
| 114 |
if "main.cpp" in project_state:
|
| 115 |
logger.info("⚙️ Detected C++ Project. Compiling via Python wrapper...")
|
| 116 |
|
| 117 |
+
# Write C++ source explicitly ensures it's fresh
|
| 118 |
sandbox.files.write("main.cpp", project_state["main.cpp"])
|
| 119 |
|
| 120 |
# Trojan Horse: Use Python to manage the compilation process reliably
|
|
|
|
| 139 |
"""
|
| 140 |
execution = sandbox.run_code(cpp_runner_script)
|
| 141 |
|
| 142 |
+
# Properly join list of strings into a single string
|
| 143 |
if execution.logs.stdout:
|
| 144 |
output_log += "".join(execution.logs.stdout) + "\n"
|
| 145 |
if execution.logs.stderr:
|
|
|
|
| 154 |
|
| 155 |
execution = sandbox.run_code(code_to_run)
|
| 156 |
|
|
|
|
| 157 |
if execution.logs.stdout:
|
| 158 |
log_str = "".join(execution.logs.stdout)
|
| 159 |
output_log += f"📄 **STDOUT**:\n```\n{log_str}\n```"
|
|
|
|
| 200 |
elif mode == "Visualization Mode":
|
| 201 |
return base_prompt + "\n\nMODE: VISUALIZATION\n- Focus on matplotlib/seaborn.\n- Create visually striking plots.\n- NO INTERNET ACCESS."
|
| 202 |
elif mode == "Web Mode":
|
| 203 |
+
return base_prompt + "\n\nMODE: WEB ARCHITECT\n- Focus on modern web technologies (Flask, HTML, CSS).\n- **YOU HAVE INTERNET ACCESS**. Use `requests` to fetch real data.\n- Structure code for web servers or API clients."
|
| 204 |
elif mode == "C++ Mode":
|
| 205 |
return base_prompt + "\n\nMODE: C++ DEVELOPER\n- Focus on modern C++ (17/20).\n- Use iostream, vector, string.\n- Ensure code compiles with g++.\n- NO INTERNET ACCESS."
|
| 206 |
else: # Code Mode
|
|
|
|
| 213 |
"""
|
| 214 |
clean_text = clean_thought_process(text)
|
| 215 |
|
| 216 |
+
# Robust Regex for code blocks (Python, C++, JS, HTML, CSS)
|
| 217 |
+
# Using multi-line string construction to prevent truncation errors
|
| 218 |
pattern = (
|
| 219 |
r"```" # Opening backticks
|
| 220 |
r"(?:python|cpp|c\+\+|javascript|html|css)?" # Optional language identifier
|
|
|
|
| 246 |
yield history, project_state, project_state[active_file], session_data
|
| 247 |
return
|
| 248 |
|
| 249 |
+
# Update Internal State
|
| 250 |
history.append({"role": "user", "content": user_input})
|
| 251 |
history.append({"role": "assistant", "content": f"🧠 *Fyodor is thinking in {mode}...*"})
|
| 252 |
|
| 253 |
+
# Yield UI Update
|
| 254 |
yield history, project_state, project_state[active_file], session_data
|
| 255 |
|
| 256 |
+
# Context Construction
|
| 257 |
sys_prompt = get_system_prompt(mode)
|
| 258 |
|
| 259 |
project_context = "\n\n=== CURRENT PROJECT FILES ===\n"
|
|
|
|
| 262 |
|
| 263 |
messages = [{"role": "system", "content": sys_prompt + project_context}]
|
| 264 |
|
| 265 |
+
# Build Chat History for API
|
| 266 |
for msg in history[:-2][-8:]:
|
| 267 |
if isinstance(msg, dict):
|
| 268 |
if msg['role'] == 'user':
|
|
|
|
| 315 |
if session_data is None: session_data = init_session()
|
| 316 |
history = session_data["history"]
|
| 317 |
history.append({"role": "user", "content": "▶️ **Run Project (Manual)**"})
|
|
|
|
| 318 |
result = execute_code_e2b(project_state, mode=mode)
|
| 319 |
history.append({"role": "assistant", "content": f"**Execution Result:**\n\n{result}"})
|
| 320 |
return history, session_data
|
|
|
|
| 326 |
history.append({"role": "assistant", "content": "🤔 *Reviewing...*"})
|
| 327 |
|
| 328 |
messages = [
|
| 329 |
+
{"role": "system", "content": "Senior Architect Code Review. Check for security and efficiency."},
|
| 330 |
{"role": "user", "content": code}
|
| 331 |
]
|
| 332 |
try:
|
|
|
|
| 338 |
history[-1]["content"] = f"❌ Review Failed: {e}"
|
| 339 |
return history, session_data
|
| 340 |
|
| 341 |
+
def clear_session_chat(session_data):
|
| 342 |
+
if session_data is None: session_data = init_session()
|
| 343 |
+
session_data["history"] = []
|
| 344 |
+
return [], session_data
|
| 345 |
+
|
| 346 |
def update_active_file(selected_file, project_data):
|
| 347 |
lang = detect_language(selected_file)
|
| 348 |
return gr.update(value=project_data.get(selected_file, ""), language=lang)
|
|
|
|
| 386 |
.chatbot .bot.message { background-color: transparent !important; border-left: 2px solid #333 !important; }
|
| 387 |
textarea, input[type="text"] { background-color: #3c3c3c !important; border: 1px solid #3c3c3c !important; color: #fff !important; border-radius: 2px !important; }
|
| 388 |
textarea:focus, input[type="text"]:focus { border-color: var(--accent) !important; box-shadow: 0 0 0 1px var(--accent) !important; }
|
| 389 |
+
button { border-radius: 2px !important; text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; font-size: 12px !important; transition: all 0.2s ease-in-out !important; }
|
| 390 |
button.primary { background: var(--accent) !important; color: #fff !important; border: none !important; }
|
| 391 |
+
button.primary:hover { background-color: #4DA2E5 !important; box-shadow: 0 0 8px rgba(58, 150, 221, 0.4); }
|
| 392 |
button.secondary { background: #333 !important; color: #fff !important; border: 1px solid #444 !important; }
|
| 393 |
+
button.secondary:hover { background-color: #444 !important; border-color: #555 !important; }
|
| 394 |
.cm-editor { border: 1px solid var(--border-col) !important; border-radius: 0 !important; }
|
| 395 |
#top-bar { background-color: var(--sidebar-bg); border-bottom: 1px solid var(--border-col); min-height: 50px; padding: 0 10px !important; display: flex; align-items: center; justify-content: space-between; }
|
| 396 |
h1 { font-size: 1.2rem !important; color: var(--text-main) !important; font-weight: normal !important; margin: 0 !important; padding: 0 !important; background-color: transparent !important; border: none !important; display: flex; align-items: center; }
|
|
|
|
| 412 |
sidebar_visible = gr.State(True)
|
| 413 |
|
| 414 |
with gr.Column(elem_classes="main-panel"):
|
| 415 |
+
# Top Bar
|
| 416 |
with gr.Row(elem_id="top-bar"):
|
| 417 |
with gr.Row(scale=1): gr.Markdown("# FYODOR IDE // PRO")
|
| 418 |
with gr.Row(scale=1):
|
| 419 |
sidebar_toggle_btn = gr.Button("👁️ Toggle Sidebar", size="sm", variant="secondary")
|
| 420 |
timer_display = gr.Textbox(value="READY", show_label=False, interactive=False, container=False, elem_classes="status-label")
|
| 421 |
|
| 422 |
+
# Workspace
|
| 423 |
with gr.Row():
|
| 424 |
+
# Editor (Left)
|
| 425 |
with gr.Column(scale=4):
|
| 426 |
with gr.Row(elem_classes="file-tabs"):
|
| 427 |
file_dropdown = gr.Dropdown(choices=["main.py"], value="main.py", show_label=False, container=False, scale=2)
|
|
|
|
| 435 |
run_manual_btn = gr.Button("▶ EXECUTE SCRIPT", variant="primary")
|
| 436 |
review_btn = gr.Button("🕵 REVIEW CODE", size="sm", variant="secondary")
|
| 437 |
|
| 438 |
+
# Terminal (Right)
|
| 439 |
with gr.Column(scale=2):
|
| 440 |
mode_radio = gr.Radio(choices=["Code Mode", "C++ Mode", "Data Mode", "Web Mode"], value="Code Mode", label="SYSTEM MODE", elem_classes="mode-radio")
|
| 441 |
chatbot = gr.Chatbot(label="TERMINAL", height=600, render_markdown=True, elem_classes="chatbot", show_label=False)
|
| 442 |
with gr.Row():
|
| 443 |
msg_input = gr.Textbox(placeholder="Type command...", show_label=False, scale=4, container=False)
|
| 444 |
run_btn = gr.Button("RUN", variant="primary", scale=1)
|
| 445 |
+
clear_btn = gr.Button("🗑️", variant="secondary", scale=0, min_width=40)
|
| 446 |
|
| 447 |
# RIGHT: SIDEBAR
|
| 448 |
with gr.Column(scale=1, min_width=250, visible=True) as sidebar_col:
|
|
|
|
| 476 |
run_btn.click(process_query, [msg_input, session_state, project_state, active_file_state, mode_radio], [chatbot, project_state, code_editor, session_state])
|
| 477 |
|
| 478 |
file_dropdown.change(update_active_file, [file_dropdown, project_state], [code_editor]).then(lambda f: f, [file_dropdown], [active_file_state])
|
|
|
|
| 479 |
code_editor.change(save_file_change, [code_editor, active_file_state, project_state], [project_state])
|
| 480 |
save_btn.click(manual_save_file, [code_editor, active_file_state, project_state], [project_state])
|
|
|
|
|
|
|
| 481 |
new_file_btn.click(create_new_file, [new_file_txt, project_state], [file_dropdown, project_state, code_editor])
|
| 482 |
|
|
|
|
| 483 |
run_manual_btn.click(manual_run_project, [project_state, session_state, mode_radio], [chatbot, session_state])
|
| 484 |
review_btn.click(run_code_review, [code_editor, session_state], [chatbot, session_state])
|
| 485 |
|
| 486 |
+
clear_btn.click(clear_session_chat, [session_state], [chatbot, session_state])
|
| 487 |
+
|
| 488 |
+
# Mini Agent: DICT FORMAT (Gradio 6)
|
| 489 |
mini_input.submit(lambda m, h: (h or []) + [{"role": "user", "content": m}, {"role": "assistant", "content": robust_search(m)}], [mini_input, mini_chat], [mini_chat])
|
| 490 |
mini_btn.click(lambda m, h: (h or []) + [{"role": "user", "content": m}, {"role": "assistant", "content": robust_search(m)}], [mini_input, mini_chat], [mini_chat])
|
| 491 |
|