Spaces:
Running
Running
import gradio as gr | |
import os | |
import subprocess | |
from mistralai.client import MistralClient | |
# --- 1. νκ²½ μ€μ --- | |
API_KEY = os.environ.get("MISTRAL_API_KEY") | |
CLIENT = None | |
CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1" | |
if API_KEY: | |
try: | |
CLIENT = MistralClient(api_key=API_KEY, endpoint=CODESTRAL_ENDPOINT) | |
print("Mistral API Client for Codestral initialized successfully.") | |
except Exception as e: | |
print(f"Error initializing Mistral Client: {e}") | |
else: | |
print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.") | |
# --- 2. λ°±μλ ν΅μ¬ κΈ°λ₯ ν¨μ --- | |
def generate_c_code(description: str) -> str: | |
if not CLIENT: return "Error: Mistral API key not configured." | |
prompt = f"You are a C programming expert. Generate a complete, compilable C code for this request: '{description}'. ONLY output the raw C code, without any markdown formatting or explanations." | |
messages = [{"role": "user", "content": prompt}] | |
response = CLIENT.chat(model="codestral-latest", messages=messages) | |
return response.choices[0].message.content.strip() | |
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: | |
if not CLIENT: return "Error: Mistral API key not configured." | |
prompt = f"""You are a senior C code reviewer. Analyze the following C code based on the user's instruction. | |
Provide a clear, concise response. If refactoring, provide the complete improved code in a C code block. | |
Instruction: '{instruction}' | |
C Code to Analyze: | |
```c | |
{code} | |
```""" | |
messages = [{"role": "user", "content": prompt}] | |
response = CLIENT.chat(model="codestral-latest", messages=messages) | |
return response.choices[0].message.content | |
# --- 3. λ©μΈ μ΄λ²€νΈ νΈλ€λ¬ --- | |
def handle_instruction(code: str, instruction: str): | |
if not instruction: | |
return code, "Error: Instruction cannot be empty." | |
lower_instruction = instruction.lower() | |
# 'generate' λλ 'create'κ° ν¬ν¨λ κ²½μ°, μ½λ μλν°κ° λΉμ΄μμ΄λ 무쑰건 μμ± | |
if "generate" in lower_instruction or "create" in lower_instruction or "λ§λ€μ΄μ€" in lower_instruction: | |
yield code, "Generating new code..." | |
new_code = generate_c_code(instruction) | |
yield new_code, "Code generation successful. New code is in the editor." | |
return | |
# κ·Έ μΈμ κ²½μ°, μ½λ μλν°κ° λΉμ΄μμΌλ©΄ μλ¬ | |
if not code: | |
yield code, "Error: Code editor is empty. Please provide code to work with, or ask to 'generate' new code." | |
return | |
if "compile" in lower_instruction or "run" in lower_instruction: | |
yield code, "Compiling and running..." | |
result = compile_and_run_c_code(code) | |
yield code, result | |
else: # Refactor, analyze, add comments, etc. | |
yield code, f"Analyzing code with instruction: '{instruction}'..." | |
analysis_result = analyze_and_refactor_code(code, instruction) | |
yield code, analysis_result | |
# --- 4. Gradio UI κ΅¬μ± (IDE νν) --- | |
with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo: | |
gr.Markdown("# π» The C-Codestral IDE Agent") | |
with gr.Tabs(): | |
with gr.TabItem("π¨βπ» IDE"): | |
with gr.Row(): | |
with gr.Column(scale=2): | |
code_editor = gr.Code(label="C Code Editor", language="c", lines=25, interactive=True) | |
with gr.Column(scale=1): | |
instruction_box = gr.Textbox( | |
label="Instruction", | |
placeholder="e.g., 'Compile and run', 'Find bugs', 'Generate a factorial function'...", | |
lines=3 | |
) | |
execute_btn = gr.Button("Execute Instruction", variant="primary") | |
output_box = gr.Textbox(label="Output / Console", lines=15, interactive=False, show_copy_button=True) | |
execute_btn.click( | |
fn=handle_instruction, | |
inputs=[code_editor, instruction_box], | |
outputs=[code_editor, output_box] | |
) | |
with gr.TabItem("π οΈ MCP Tools API"): | |
gr.Markdown("## Available MCP Tools\nThese APIs can be used by any MCP-compliant client.") | |
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() |