kimhyunwoo commited on
Commit
db2f9f4
Β·
verified Β·
1 Parent(s): a5c7603

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -76
app.py CHANGED
@@ -1,46 +1,35 @@
1
  import gradio as gr
2
  import os
3
  import subprocess
4
- import requests # mistralai λŒ€μ‹  requests μ‚¬μš©
5
  import json
 
6
 
7
- # --- 1. ν™˜κ²½ μ„€μ • ---
8
  API_KEY = os.environ.get("MISTRAL_API_KEY")
9
- CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1/chat/completions" # 직접 ν˜ΈμΆœν•  μ—”λ“œν¬μΈνŠΈ
10
- HEADERS = {
11
- "Authorization": f"Bearer {API_KEY}",
12
- "Content-Type": "application/json"
13
- }
14
 
15
  if not API_KEY:
16
  print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.")
17
 
18
- # --- 2. λ°±μ—”λ“œ 핡심 κΈ°λŠ₯ ν•¨μˆ˜ (requests μ‚¬μš©) ---
19
  def call_mistral_api(messages):
20
  if not API_KEY: return "Error: MISTRAL_API_KEY is not configured."
21
-
22
- data = {
23
- "model": "codestral-latest",
24
- "messages": messages
25
- }
26
-
27
  try:
28
  response = requests.post(CODESTRAL_ENDPOINT, headers=HEADERS, data=json.dumps(data), timeout=30)
29
- response.raise_for_status() # 2xxκ°€ μ•„λ‹Œ μƒνƒœ μ½”λ“œμ— λŒ€ν•΄ μ—λŸ¬ λ°œμƒ
30
  return response.json()["choices"][0]["message"]["content"]
31
  except requests.exceptions.RequestException as e:
32
  return f"API Call Error: {e}"
33
 
34
- def generate_c_code(description: str) -> str:
35
- 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."
36
- messages = [{"role": "user", "content": prompt}]
37
- code = call_mistral_api(messages)
38
-
39
- if "```c" in code:
40
- code = code.split("```c")[1].split("```")[0].strip()
41
- elif "```" in code:
42
- code = code.split("```")[1].split("```")[0].strip()
43
- return code
44
 
45
  def compile_and_run_c_code(code: str) -> str:
46
  try:
@@ -53,70 +42,73 @@ def compile_and_run_c_code(code: str) -> str:
53
  return f"--- EXECUTION SUCCEEDED ---\n{output}" if output.strip() else "--- EXECUTION SUCCEEDED ---\n(No output was produced)"
54
  except Exception as e: return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
55
 
56
- def analyze_and_refactor_code(code: str, instruction: str) -> str:
57
- prompt = f"""You are a senior C code reviewer. Analyze the following C code based on the user's instruction.
58
- Provide a clear, concise response. If refactoring, provide the complete improved code in a C code block.
59
-
60
- Instruction: '{instruction}'
61
-
62
- C Code to Analyze:
63
- ```c
64
- {code}
65
- ```"""
66
- messages = [{"role": "user", "content": prompt}]
67
- return call_mistral_api(messages)
68
-
69
- # --- 3. 메인 이벀트 ν•Έλ“€λŸ¬ ---
70
- def handle_instruction(code: str, instruction: str):
71
  if not instruction:
72
- return code, "Error: Instruction cannot be empty."
 
73
 
74
  lower_instruction = instruction.lower()
75
-
 
76
  if "generate" in lower_instruction or "create" in lower_instruction or "λ§Œλ“€μ–΄μ€˜" in lower_instruction:
77
- yield code, "Generating new code..."
78
- new_code = generate_c_code(instruction)
79
- yield new_code, "Code generation successful. New code is in the editor."
 
80
  return
81
 
82
  if not code:
83
- yield code, "Error: Code editor is empty. Please provide code to work with, or ask to 'generate' new code."
84
  return
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  if "compile" in lower_instruction or "run" in lower_instruction:
87
- yield code, "Compiling and running..."
88
  result = compile_and_run_c_code(code)
89
- yield code, result
90
-
91
- else:
92
- yield code, f"Analyzing code with instruction: '{instruction}'..."
93
- analysis_result = analyze_and_refactor_code(code, instruction)
94
- yield code, analysis_result
95
 
96
- # --- 4. Gradio UI ꡬ성 ---
97
  with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo:
98
- gr.Markdown("# πŸ’» The C-Codestral IDE Agent (Library-Free)")
99
-
100
- with gr.Tabs():
101
- with gr.TabItem("πŸ‘¨β€πŸ’» IDE"):
102
- with gr.Row():
103
- with gr.Column(scale=2):
104
- code_editor = gr.Code(label="C Code Editor", language="c", lines=25, interactive=True)
105
- with gr.Column(scale=1):
106
- instruction_box = gr.Textbox(label="Instruction", placeholder="e.g., 'Compile and run', 'Find bugs', 'Generate a factorial function'...", lines=3)
107
- execute_btn = gr.Button("Execute Instruction", variant="primary")
108
- output_box = gr.Textbox(label="Output / Console", lines=15, interactive=False, show_copy_button=True)
109
-
110
- execute_btn.click(fn=handle_instruction, inputs=[code_editor, instruction_box], outputs=[code_editor, output_box])
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"), outputs=gr.Textbox(label="Output"))
118
- with gr.Accordion("Tool: Analyze & Refactor C Code", open=False):
119
- gr.Interface(fn=analyze_and_refactor_code, inputs=[gr.Code(language="c"), "text"], outputs=gr.Markdown())
120
 
121
  if __name__ == "__main__":
122
  demo.queue().launch()
 
1
  import gradio as gr
2
  import os
3
  import subprocess
4
+ import requests
5
  import json
6
+ import re
7
 
8
+ # --- 1. ν™˜κ²½ μ„€μ • 및 API 호좜 ν•¨μˆ˜ ---
9
  API_KEY = os.environ.get("MISTRAL_API_KEY")
10
+ CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1/chat/completions"
11
+ HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
 
 
 
12
 
13
  if not API_KEY:
14
  print("FATAL: MISTRAL_API_KEY is not set in Space Secrets.")
15
 
 
16
  def call_mistral_api(messages):
17
  if not API_KEY: return "Error: MISTRAL_API_KEY is not configured."
18
+ data = {"model": "codestral-latest", "messages": messages}
 
 
 
 
 
19
  try:
20
  response = requests.post(CODESTRAL_ENDPOINT, headers=HEADERS, data=json.dumps(data), timeout=30)
21
+ response.raise_for_status()
22
  return response.json()["choices"][0]["message"]["content"]
23
  except requests.exceptions.RequestException as e:
24
  return f"API Call Error: {e}"
25
 
26
+ # --- 2. λ°±μ—”λ“œ 핡심 κΈ°λŠ₯ (νŒŒμ„œ μΆ”κ°€) ---
27
+ def parse_code_from_response(response_text: str) -> str | None:
28
+ """LLM μ‘λ‹΅μ—μ„œ C μ½”λ“œ 블둝을 μΆ”μΆœν•©λ‹ˆλ‹€."""
29
+ match = re.search(r'```c\n(.*?)\n```', response_text, re.DOTALL)
30
+ if match:
31
+ return match.group(1).strip()
32
+ return None
 
 
 
33
 
34
  def compile_and_run_c_code(code: str) -> str:
35
  try:
 
42
  return f"--- EXECUTION SUCCEEDED ---\n{output}" if output.strip() else "--- EXECUTION SUCCEEDED ---\n(No output was produced)"
43
  except Exception as e: return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
44
 
45
+ # --- 3. μ§„μ§œ 'μ§€λŠ₯ν˜•' μ—μ΄μ „νŠΈ 둜직 ---
46
+ def intelligent_agent(code: str, instruction: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  if not instruction:
48
+ yield code, "Error: Instruction cannot be empty."
49
+ return
50
 
51
  lower_instruction = instruction.lower()
52
+
53
+ # 1. 생성 (Generation)
54
  if "generate" in lower_instruction or "create" in lower_instruction or "λ§Œλ“€μ–΄μ€˜" in lower_instruction:
55
+ yield code, "1. Generating new code..."
56
+ prompt = f"You are a C programming expert. Generate a complete, compilable C code for this request: '{instruction}'. ONLY output the raw C code, without any markdown formatting or explanations."
57
+ new_code = call_mistral_api([{"role": "user", "content": prompt}])
58
+ yield new_code, "2. Code generation successful. The new code is now in the editor."
59
  return
60
 
61
  if not code:
62
+ yield code, "Error: Code editor is empty. Please provide code or ask to 'generate' it."
63
  return
64
 
65
+ # 2. 뢄석/λ¦¬νŒ©ν† λ§ (Analyze/Refactor)
66
+ if any(keyword in lower_instruction for keyword in ["analyze", "refactor", "explain", "comment", "review", "κ°œμ„ ", "μ„€λͺ…", "버그"]):
67
+ yield code, f"1. Analyzing code with instruction: '{instruction}'..."
68
+ prompt = f"You are a senior C code reviewer. Fulfill this instruction: '{instruction}'. If you refactor the code, YOU MUST provide the complete, improved code in a ```c code block. \n\nC Code to Analyze:\n```c\n{code}\n```"
69
+ analysis_result = call_mistral_api([{"role": "user", "content": prompt}])
70
+
71
+ # μ§€λŠ₯ν˜• νŒŒμ‹±: λ¦¬νŒ©ν† λ§λœ μ½”λ“œκ°€ μžˆλŠ”μ§€ 확인
72
+ refactored_code = parse_code_from_response(analysis_result)
73
+ if refactored_code:
74
+ yield refactored_code, f"2. Refactoring successful. Code editor updated.\n\n{analysis_result}"
75
+ # 'and compile' 같은 후속 λͺ…령이 μžˆλŠ”μ§€ 확인
76
+ if "compile" in lower_instruction or "run" in lower_instruction:
77
+ yield refactored_code, "3. Compiling the new code..."
78
+ compile_result = compile_and_run_c_code(refactored_code)
79
+ yield refactored_code, f"4. Compilation finished.\n\n{compile_result}"
80
+ else:
81
+ # λ¦¬νŒ©ν† λ§λœ μ½”λ“œκ°€ μ—†μœΌλ©΄, 뢄석 결과만 λ³΄μ—¬μ€Œ
82
+ yield code, f"2. Analysis complete.\n\n{analysis_result}"
83
+ return
84
+
85
+ # 3. 컴파일 및 μ‹€ν–‰ (Compile & Run)
86
  if "compile" in lower_instruction or "run" in lower_instruction:
87
+ yield code, "1. Compiling and running..."
88
  result = compile_and_run_c_code(code)
89
+ yield code, f"2. Process finished.\n\n{result}"
90
+ return
91
+
92
+ # 4. κ·Έ μ™Έ
93
+ yield code, "Error: Could not understand the instruction. Please be more specific (e.g., 'generate', 'compile', 'refactor')."
 
94
 
95
+ # --- 4. ν†΅ν•©λœ Gradio UI ---
96
  with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo:
97
+ gr.Markdown("# πŸ’» The True C-Codestral IDE Agent")
98
+
99
+ with gr.Row():
100
+ with gr.Column(scale=2):
101
+ code_editor = gr.Code(label="C Code Editor", language="c", lines=25, interactive=True, value='#include <stdio.h>\n\nint main() {\n printf("Hello, World!\\n");\n return 0;\n}')
102
+ with gr.Column(scale=1):
103
+ instruction_box = gr.Textbox(label="Instruction", placeholder="e.g., 'Refactor this code and run it', 'Generate a factorial function', 'Find bugs'...", lines=4)
104
+ execute_btn = gr.Button("Execute", variant="primary", size="lg")
105
+ output_box = gr.Markdown(label="Console / Output", value="Welcome! Enter an instruction and press 'Execute'.")
106
+
107
+ execute_btn.click(
108
+ fn=intelligent_agent,
109
+ inputs=[code_editor, instruction_box],
110
+ outputs=[code_editor, output_box]
111
+ )
 
 
 
 
 
 
 
112
 
113
  if __name__ == "__main__":
114
  demo.queue().launch()