c / app.py
kimhyunwoo's picture
Update app.py
9c4c102 verified
raw
history blame
5.74 kB
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()