Spaces:
Running
Running
import gradio as gr | |
import os | |
import subprocess | |
import requests | |
import json | |
import re | |
import time | |
# --- 1. νκ²½ μ€μ λ° API νΈμΆ ν¨μ --- | |
API_KEY = os.environ.get("MISTRAL_API_KEY") | |
CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1/chat/completions" | |
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"} | |
if not API_KEY: | |
print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.") | |
def call_mistral_api(messages): | |
if not API_KEY: return "Error: MISTRAL_API_KEY is not configured." | |
data = {"model": "codestral-latest", "messages": messages} | |
try: | |
response = requests.post(CODESTRAL_ENDPOINT, headers=HEADERS, data=json.dumps(data), timeout=45) | |
response.raise_for_status() | |
return response.json()["choices"][0]["message"]["content"] | |
except requests.exceptions.RequestException as e: | |
return f"API Call Error: {e}" | |
# --- 2. λ°±μλ ν΅μ¬ κΈ°λ₯ (νμ ν¬ν¨) --- | |
def parse_code_from_response(response_text: str) -> str | None: | |
match = re.search(r'```c\n(.*?)\n```', response_text, re.DOTALL) | |
if match: | |
return match.group(1).strip() | |
return None | |
# --- MCP νκ³Ό μμ΄μ νΈκ° λͺ¨λ μ¬μ©ν μ μ ν¨μλ‘ μ μ --- | |
def generate_c_code(description: str) -> str: | |
prompt = f"Generate a complete, compilable C code for this request: '{description}'. ONLY output the raw C code, without markdown or explanations." | |
return call_mistral_api([{"role": "user", "content": prompt}]) | |
def compile_and_run_c_code(code: str) -> str: | |
try: | |
with open("main.c", "w", encoding='utf-8') as f: f.write(code) | |
compile_proc = subprocess.run(["gcc", "main.c", "-o", "main.out", "-lm", "-w"], capture_output=True, text=True, timeout=15) | |
if compile_proc.returncode != 0: return f"--- COMPILATION FAILED ---\n{compile_proc.stderr}" | |
run_proc = subprocess.run(["./main.out"], capture_output=True, text=True, timeout=15) | |
if run_proc.returncode != 0: return f"--- RUNTIME ERROR ---\n{run_proc.stderr}" | |
output = run_proc.stdout | |
return f"--- EXECUTION SUCCEEDED ---\n{output}" if output.strip() else "--- EXECUTION SUCCEEDED ---\n(No output was produced)" | |
except Exception as e: return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}" | |
def analyze_and_refactor_code(code: str, instruction: str) -> str: | |
prompt = f"You are a senior C code reviewer. Fulfill this instruction: '{instruction}'. If you refactor or change the code, YOU MUST provide the complete, new code in a ```c code block. \n\nC Code to Analyze:\n```c\n{code}\n```" | |
return call_mistral_api([{"role": "user", "content": prompt}]) | |
# --- 3. μ§μ§ 'μ§λ₯ν' μμ΄μ νΈ λ‘μ§ --- | |
def intelligent_agent_ide(initial_code: str, full_instruction: str): | |
if not full_instruction: | |
yield initial_code, "Error: Instruction cannot be empty." | |
return | |
tasks = [task.strip() for task in re.split(r'\s+and\s+|\s*,\s*then\s*|\s*κ·Έλ¦¬κ³ \s*', full_instruction, flags=re.IGNORECASE)] | |
current_code = initial_code | |
output_log = [] | |
step = 1 | |
for task in tasks: | |
lower_task = task.lower() | |
output_log.append(f"βΆ Step {step}: Executing '{task}'...") | |
yield current_code, "\n".join(output_log) | |
time.sleep(0.5) | |
if "generate" in lower_task or "create" in lower_task or "λ§λ€μ΄μ€" in lower_task: | |
new_code = generate_c_code(task) | |
current_code = new_code if new_code and "Error" not in new_code else current_code | |
output_log.append(f"β Code generated and updated in the editor.") | |
yield current_code, "\n".join(output_log) | |
elif "compile" in lower_task or "run" in lower_task or "μ€ν" in lower_task: | |
if not current_code: | |
output_log.append("β Error: Code is empty. Cannot compile.") | |
yield current_code, "\n".join(output_log) | |
break | |
result = compile_and_run_c_code(current_code) | |
output_log.append(result) | |
yield current_code, "\n".join(output_log) | |
else: | |
if not current_code: | |
output_log.append("β Error: Code is empty. Cannot analyze.") | |
yield current_code, "\n".join(output_log) | |
break | |
analysis_result = analyze_and_refactor_code(current_code, task) | |
refactored_code = parse_code_from_response(analysis_result) | |
if refactored_code: | |
current_code = refactored_code | |
output_log.append(f"β Code refactored and updated in the editor.") | |
output_log.append(f"π Analysis Result:\n{analysis_result}") | |
yield current_code, "\n".join(output_log) | |
step += 1 | |
output_log.append("\n--- All tasks complete. ---") | |
yield current_code, "\n".join(output_log) | |
# --- 4. ν΅ν©λ Gradio UI --- | |
with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo: | |
gr.Markdown("# π» The True C-Codestral IDE Agent") | |
with gr.Tabs(): | |
with gr.TabItem("π¨βπ» IDE Agent"): | |
with gr.Row(equal_height=True): | |
with gr.Column(scale=2): | |
code_editor = gr.Code(label="C Code Editor", language="c", lines=28, interactive=True, value='#include <stdio.h>\n\nint main() {\n printf("Hello, World!\\n");\n return 0;\n}') | |
with gr.Column(scale=1): | |
instruction_box = gr.Textbox(label="Instruction", placeholder="e.g., 'Refactor this code for readability, and then compile it'", lines=4) | |
execute_btn = gr.Button("Execute", variant="primary", size="lg") | |
output_box = gr.Textbox(label="Console / Output", lines=21, interactive=False, show_copy_button=True, max_lines=50) | |
execute_btn.click( | |
fn=intelligent_agent_ide, | |
inputs=[code_editor, instruction_box], | |
outputs=[code_editor, output_box] | |
) | |
with gr.TabItem("π οΈ MCP Tools API"): | |
gr.Markdown("## Available MCP Tools for other Agents\nThese APIs are the building blocks of our IDE agent.") | |
with gr.Accordion("Tool: Generate C Code", open=False): | |
gr.Interface(fn=generate_c_code, inputs="text", outputs=gr.Code(language="c", label="Generated C Code")) | |
with gr.Accordion("Tool: Compile & Run C Code", open=False): | |
gr.Interface(fn=compile_and_run_c_code, inputs=gr.Code(language="c"), outputs=gr.Textbox(label="Output")) | |
with gr.Accordion("Tool: Analyze & Refactor C Code", open=False): | |
gr.Interface(fn=analyze_and_refactor_code, inputs=[gr.Code(language="c"), "text"], outputs=gr.Markdown()) | |
if __name__ == "__main__": | |
demo.queue().launch() |