kimhyunwoo commited on
Commit
bb4dd6d
ยท
verified ยท
1 Parent(s): bfe9258

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -81
app.py CHANGED
@@ -17,104 +17,98 @@ if API_KEY:
17
  else:
18
  print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.")
19
 
20
- # --- 2. ๋ฐฑ์—”๋“œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ---
21
  def generate_c_code(description: str) -> str:
22
  if not CLIENT: return "Error: Mistral API key not configured."
23
- prompt = f"Generate a complete, compilable C code for this request: '{description}'. ONLY output the raw C code within a single ```c code block."
24
  messages = [{"role": "user", "content": prompt}]
25
  response = CLIENT.chat(model="codestral-latest", messages=messages)
26
- code = response.choices[0].message.content
27
- if "```c" in code:
28
- code = code.split("```c")[1].split("```")[0].strip()
29
- elif "```" in code:
30
- code = code.split("```")[1].split("```")[0].strip()
31
- return code
32
 
33
  def compile_and_run_c_code(code: str) -> str:
34
  try:
35
- with open("main.c", "w", encoding='utf-8') as f:
36
- f.write(code)
37
- compile_proc = subprocess.run(
38
- ["gcc", "main.c", "-o", "main.out", "-lm", "-w"],
39
- capture_output=True, text=True, timeout=15
40
- )
41
- if compile_proc.returncode != 0:
42
- return f"--- COMPILATION FAILED ---\n{compile_proc.stderr}"
43
- run_proc = subprocess.run(
44
- ["./main.out"], capture_output=True, text=True, timeout=15
45
- )
46
- if run_proc.returncode != 0:
47
- return f"--- RUNTIME ERROR ---\n{run_proc.stderr}"
48
  output = run_proc.stdout
49
- if not output.strip():
50
- return "--- EXECUTION SUCCEEDED ---\n(No output was produced)"
51
- return f"--- EXECUTION SUCCEEDED ---\n{output}"
52
- except Exception as e:
53
- return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
54
-
55
- # --- 3. Gradio ์ฑ—๋ด‡ ๋กœ์ง (Gradio 5.x+ ํ˜ธํ™˜) ---
56
- def agent_chat(history: list[dict[str, str]]):
57
- if not CLIENT:
58
- history.append({"role": "assistant", "content": "MISTRAL_API_KEY๊ฐ€ Space Secrets์— ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."})
59
- return history
60
-
61
- # ์‚ฌ์šฉ์ž์˜ ๋งˆ์ง€๋ง‰ ๋ฉ”์‹œ์ง€๊ฐ€ history์˜ ๋งˆ์ง€๋ง‰์— ์žˆ์Šต๋‹ˆ๋‹ค.
62
- message = history[-1]["content"]
63
- lower_message = message.lower()
64
- bot_response = ""
65
-
66
- # API์— ๋ณด๋‚ผ ๋ฉ”์‹œ์ง€๋Š” ํ˜„์žฌ ๋Œ€ํ™” ์ „์ฒด์ž…๋‹ˆ๋‹ค.
67
- messages_for_api = history
68
-
69
- if "compile" in lower_message or "run" in lower_message or "์‹คํ–‰" in lower_message:
70
- code_to_run = ""
71
- # ์ž์‹ ์„ ์ œ์™ธํ•œ ์ด์ „ ๋Œ€ํ™”์—์„œ ์ฝ”๋“œ ์ฐพ๊ธฐ
72
- for item in reversed(history[:-1]):
73
- if item.get("role") == "assistant" and "```c" in item.get("content", ""):
74
- code_to_run = item["content"].split("```c")[1].split("```")[0].strip()
75
- break
76
- if not code_to_run:
77
- bot_response = "์ปดํŒŒ์ผํ•  ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”."
78
- else:
79
- bot_response = compile_and_run_c_code(code_to_run)
80
-
81
- elif "generate" in lower_message or "create" in lower_message or "๋งŒ๋“ค์–ด์ค˜" in lower_message or "์งœ์ค˜" in lower_message:
82
- generated_code = generate_c_code(message)
83
- bot_response = f"์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.\n\n```c\n{generated_code}\n```"
84
-
85
- else:
86
- response = CLIENT.chat(model="codestral-latest", messages=messages_for_api)
87
- bot_response = response.choices[0].message.content
88
 
89
- history.append({"role": "assistant", "content": bot_response})
90
- return history
 
 
 
 
 
 
 
91
 
92
- # --- 4. Gradio UI ๊ตฌ์„ฑ (Gradio 5.x+ ํ˜ธํ™˜) ---
93
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="gray"), css="footer {visibility: hidden}") as demo:
94
- gr.Markdown("# ๐Ÿš€ C-Codestral Agent")
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  with gr.Tabs():
97
- with gr.TabItem("๐Ÿค– Agent Chat"):
98
- # Gradio 5.x ์—์„œ๋Š” 'type' ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
99
- chatbot = gr.Chatbot(label="C-Agent", height=600, render_markdown=True)
100
- msg = gr.Textbox(placeholder="Ask me to generate or run C code...", show_label=False, container=False)
101
-
102
- def add_user_message(message, history):
103
- # ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋ฅผ ๋จผ์ € history์— ์ถ”๊ฐ€ํ•˜๊ณ , ์ž…๋ ฅ์ฐฝ์„ ๋น„์›๋‹ˆ๋‹ค.
104
- return history + [{"role": "user", "content": message}], ""
105
-
106
- # 1. ์‚ฌ์šฉ์ž๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด, add_user_message๊ฐ€ ๋จผ์ € ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
107
- # 2. .then()์„ ํ†ตํ•ด, ์—…๋ฐ์ดํŠธ๋œ history๋ฅผ agent_chat์œผ๋กœ ๋„˜๊ฒจ ๋ด‡ ์‘๋‹ต์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.
108
- msg.submit(add_user_message, [msg, chatbot], [chatbot, msg], queue=False).then(
109
- agent_chat, chatbot, chatbot
110
- )
 
 
 
 
 
 
 
111
 
112
  with gr.TabItem("๐Ÿ› ๏ธ MCP Tools API"):
113
  gr.Markdown("## Available MCP Tools\nThese APIs can be used by any MCP-compliant client.")
114
  with gr.Accordion("Tool: Generate C Code", open=False):
115
  gr.Interface(fn=generate_c_code, inputs="text", outputs=gr.Code(language="c", label="Generated C Code"))
116
  with gr.Accordion("Tool: Compile & Run C Code", open=False):
117
- gr.Interface(fn=compile_and_run_c_code, inputs=gr.Code(language="c", label="C Code to Run"), outputs=gr.Textbox(label="Output/Error"))
 
 
118
 
119
  if __name__ == "__main__":
120
- demo.queue().launch()
 
17
  else:
18
  print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.")
19
 
20
+ # --- 2. ๋ฐฑ์—”๋“œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ํ•จ์ˆ˜ ---
21
  def generate_c_code(description: str) -> str:
22
  if not CLIENT: return "Error: Mistral API key not configured."
23
+ 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."
24
  messages = [{"role": "user", "content": prompt}]
25
  response = CLIENT.chat(model="codestral-latest", messages=messages)
26
+ return response.choices[0].message.content.strip()
 
 
 
 
 
27
 
28
  def compile_and_run_c_code(code: str) -> str:
29
  try:
30
+ with open("main.c", "w", encoding='utf-8') as f: f.write(code)
31
+ compile_proc = subprocess.run(["gcc", "main.c", "-o", "main.out", "-lm", "-w"], capture_output=True, text=True, timeout=15)
32
+ if compile_proc.returncode != 0: return f"--- COMPILATION FAILED ---\n{compile_proc.stderr}"
33
+ run_proc = subprocess.run(["./main.out"], capture_output=True, text=True, timeout=15)
34
+ if run_proc.returncode != 0: return f"--- RUNTIME ERROR ---\n{run_proc.stderr}"
 
 
 
 
 
 
 
 
35
  output = run_proc.stdout
36
+ return f"--- EXECUTION SUCCEEDED ---\n{output}" if output.strip() else "--- EXECUTION SUCCEEDED ---\n(No output was produced)"
37
+ except Exception as e: return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
38
+
39
+ def analyze_and_refactor_code(code: str, instruction: str) -> str:
40
+ if not CLIENT: return "Error: Mistral API key not configured."
41
+ prompt = f"""You are a senior C code reviewer. Analyze the following C code based on the user's instruction.
42
+ Provide a clear, concise response. If refactoring, provide the complete improved code in a C code block.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ Instruction: '{instruction}'
45
+
46
+ C Code to Analyze:
47
+ ```c
48
+ {code}
49
+ ```"""
50
+ messages = [{"role": "user", "content": prompt}]
51
+ response = CLIENT.chat(model="codestral-latest", messages=messages)
52
+ return response.choices[0].message.content
53
 
54
+ # --- 3. ๋ฉ”์ธ ์—์ด์ „ํŠธ ๋กœ์ง ---
55
+ def agent_logic(code: str, instruction: str):
56
+ if not instruction: return "Error: Instruction cannot be empty."
57
 
58
+ lower_instruction = instruction.lower()
59
+
60
+ if "compile" in lower_instruction or "run" in lower_instruction:
61
+ if not code: return "Error: Code editor is empty. Nothing to compile."
62
+ return compile_and_run_c_code(code)
63
+
64
+ elif "generate" in lower_instruction or "create" in lower_instruction or "๋งŒ๋“ค์–ด์ค˜" in lower_instruction:
65
+ # ์ƒˆ๋กœ์šด ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ฝ”๋“œ ์—๋””ํ„ฐ์— ์ง์ ‘ ๋ฐ˜ํ™˜
66
+ new_code = generate_c_code(instruction)
67
+ # ์ถœ๋ ฅ์€ ์ฝ”๋“œ ์—๋””ํ„ฐ๋กœ, ๊ฒฐ๊ณผ์ฐฝ์—๋Š” ์„ฑ๊ณต ๋ฉ”์‹œ์ง€
68
+ return new_code, f"Code generation successful. The new code is now in the editor."
69
+
70
+ else: # Refactor, analyze, add comments, etc.
71
+ if not code: return "Error: Code editor is empty. Nothing to analyze."
72
+ # ๋ถ„์„/๋ฆฌํŒฉํ† ๋ง ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐ๊ณผ์ฐฝ์— ๋ฐ˜ํ™˜
73
+ analysis_result = analyze_and_refactor_code(code, instruction)
74
+ # ์ฝ”๋“œ ์—๋””ํ„ฐ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ๊ฒฐ๊ณผ์ฐฝ๋งŒ ์—…๋ฐ์ดํŠธ
75
+ return code, analysis_result
76
+
77
+ # --- 4. Gradio UI ๊ตฌ์„ฑ (IDE ํ˜•ํƒœ) ---
78
+ with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo:
79
+ gr.Markdown("# ๐Ÿ’ป The C-Codestral IDE Agent")
80
+
81
  with gr.Tabs():
82
+ with gr.TabItem("๐Ÿ‘จโ€๐Ÿ’ป IDE"):
83
+ with gr.Row():
84
+ with gr.Column(scale=2):
85
+ code_editor = gr.Code(label="C Code Editor", language="c", lines=25, interactive=True)
86
+ with gr.Column(scale=1):
87
+ instruction_box = gr.Textbox(label="Instruction", placeholder="e.g., 'Compile and run', 'Find bugs', 'Add comments', 'Generate a factorial function'...")
88
+ execute_btn = gr.Button("Execute Instruction", variant="primary")
89
+ output_box = gr.Markdown(label="Output / Console")
90
+
91
+ def handle_ide_submit(code, instruction):
92
+ # ์ƒ์„ฑ ์š”์ฒญ ์‹œ ๋™์ž‘์„ ๋ถ„๊ธฐ
93
+ if "generate" in instruction.lower() or "create" in instruction.lower():
94
+ new_code, message = agent_logic(code, instruction)
95
+ return new_code, message
96
+ else:
97
+ # ์ปดํŒŒ์ผ ๋˜๋Š” ๋ถ„์„
98
+ result = agent_logic(code, instruction)
99
+ # ์ด ๊ฒฝ์šฐ, agent_logic์€ ํ•˜๋‚˜์˜ ๊ฐ’๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ์ฝ”๋“œ ์—๋””ํ„ฐ๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€
100
+ return code, result
101
+
102
+ execute_btn.click(handle_ide_submit, inputs=[code_editor, instruction_box], outputs=[code_editor, output_box])
103
 
104
  with gr.TabItem("๐Ÿ› ๏ธ MCP Tools API"):
105
  gr.Markdown("## Available MCP Tools\nThese APIs can be used by any MCP-compliant client.")
106
  with gr.Accordion("Tool: Generate C Code", open=False):
107
  gr.Interface(fn=generate_c_code, inputs="text", outputs=gr.Code(language="c", label="Generated C Code"))
108
  with gr.Accordion("Tool: Compile & Run C Code", open=False):
109
+ gr.Interface(fn=compile_and_run_c_code, inputs=gr.Code(language="c"), outputs=gr.Textbox(label="Output"))
110
+ with gr.Accordion("Tool: Analyze & Refactor C Code", open=False):
111
+ gr.Interface(fn=analyze_and_refactor_code, inputs=[gr.Code(language="c"), "text"], outputs=gr.Markdown())
112
 
113
  if __name__ == "__main__":
114
+ demo.launch()