Spaces:
Running
Running
File size: 6,936 Bytes
e0c0af8 f75669b db2f9f4 a5c7603 db2f9f4 c1ec9e7 f75669b db2f9f4 9ebbf81 db2f9f4 fbae41a a5c7603 9e50a0d f75669b a5c7603 db2f9f4 a5c7603 c1ec9e7 db2f9f4 a5c7603 c1ec9e7 db2f9f4 f75669b 302b980 f75669b bb4dd6d f75669b bb4dd6d 302b980 bb4dd6d c1ec9e7 db2f9f4 c1ec9e7 302b980 c1ec9e7 302b980 c1ec9e7 b328beb c1ec9e7 b328beb c1ec9e7 db2f9f4 b328beb c1ec9e7 b328beb c1ec9e7 b328beb c1ec9e7 b328beb 302b980 b328beb 302b980 e0c0af8 9c4c102 |
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
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() |