kimhyunwoo commited on
Commit
c1ec9e7
·
verified ·
1 Parent(s): b328beb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -46
app.py CHANGED
@@ -4,6 +4,7 @@ import subprocess
4
  import requests
5
  import json
6
  import re
 
7
 
8
  # --- 1. 환경 설정 및 API 호출 함수 ---
9
  API_KEY = os.environ.get("MISTRAL_API_KEY")
@@ -17,24 +18,19 @@ 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 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
- return call_mistral_api([{"role": "user", "content": prompt}])
37
-
38
  def compile_and_run_c_code(code: str) -> str:
39
  try:
40
  with open("main.c", "w", encoding='utf-8') as f: f.write(code)
@@ -46,55 +42,97 @@ def compile_and_run_c_code(code: str) -> str:
46
  return f"--- EXECUTION SUCCEEDED ---\n{output}" if output.strip() else "--- EXECUTION SUCCEEDED ---\n(No output was produced)"
47
  except Exception as e: return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
48
 
49
- def analyze_and_refactor_code(code: str, instruction: str):
50
- 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```""
51
- analysis_result = call_mistral_api([{"role": "user", "content": prompt}])
 
 
 
 
 
52
 
53
- # 지능형 파싱: 리팩토링된 코드가 있는지 확인
54
- refactored_code = parse_code_from_response(analysis_result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- if refactored_code:
57
- # 리팩토링된 코드가 있으면, 그 코드를 에디터에, 전체 응답을 결과창에 반환
58
- return refactored_code, analysis_result
59
- else:
60
- # 리팩토링된 코드가 없으면, 원래 코드는 그대로 두고, 분석 결과만 반환
61
- return code, analysis_result
62
-
63
- # --- 3. Gradio UI 구성 (안정적인 탭 구조 + 지능형 파싱) ---
64
  with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo:
65
- gr.Markdown("# 💻 The C-Codestral IDE Agent (Stable Tabbed Version)")
66
 
67
  with gr.Tabs():
68
- with gr.TabItem("👨‍💻 IDE"):
69
- with gr.Row():
70
  with gr.Column(scale=2):
71
- code_editor = gr.Code(label="C Code Editor", language="c", lines=20, interactive=True, value='#include <stdio.h>\n\nint main() {\n printf("Hello, World!\\n");\n return 0;\n}')
72
 
73
  with gr.Column(scale=1):
74
- # 명령어 구성
75
- with gr.Tabs():
76
- with gr.TabItem("Generate"):
77
- gen_instr = gr.Textbox(label="Generation Instruction", placeholder="e.g., 'a program that calculates factorial'")
78
- gen_btn = gr.Button("Generate Code", variant="primary")
79
- with gr.TabItem("Analyze / Refactor"):
80
- ana_instr = gr.Textbox(label="Analysis Instruction", placeholder="e.g., 'add comments', 'refactor for efficiency'")
81
- ana_btn = gr.Button("Analyze / Refactor", variant="primary")
82
- with gr.TabItem("Compile / Run"):
83
- run_btn = gr.Button("Compile and Run", variant="stop")
84
-
85
- output_box = gr.Textbox(label="Output / Console", lines=8, interactive=False, show_copy_button=True)
86
-
87
- # 이벤트 핸들러 연결
88
- gen_btn.click(fn=generate_c_code, inputs=[gen_instr], outputs=[code_editor])
89
- ana_btn.click(fn=analyze_and_refactor_code, inputs=[code_editor, ana_instr], outputs=[code_editor, output_box])
90
- run_btn.click(fn=compile_and_run_c_code, inputs=[code_editor], outputs=[output_box])
91
-
92
- with gr.TabItem("🛠️ MCP Tools"):
93
- gr.Markdown("## Available MCP Tools for other Agents")
94
  with gr.Accordion("Tool: Generate C Code", open=False):
95
- gr.Interface(fn=generate_c_code, inputs="text", outputs=gr.Code(language="c", label="Generated C Code"))
 
 
 
96
  with gr.Accordion("Tool: Compile & Run C Code", open=False):
97
- gr.Interface(fn=compile_and_run_c_code, inputs=gr.Code(language="c"), outputs=gr.Textbox(label="Output"))
 
 
98
 
99
  if __name__ == "__main__":
100
  demo.queue().launch()
 
4
  import requests
5
  import json
6
  import re
7
+ import time
8
 
9
  # --- 1. 환경 설정 및 API 호출 함수 ---
10
  API_KEY = os.environ.get("MISTRAL_API_KEY")
 
18
  if not API_KEY: return "Error: MISTRAL_API_KEY is not configured."
19
  data = {"model": "codestral-latest", "messages": messages}
20
  try:
21
+ response = requests.post(CODESTRAL_ENDPOINT, headers=HEADERS, data=json.dumps(data), timeout=45)
22
  response.raise_for_status()
23
  return response.json()["choices"][0]["message"]["content"]
24
  except requests.exceptions.RequestException as e:
25
  return f"API Call Error: {e}"
26
 
27
+ # --- 2. 백엔드 핵심 기능 (파서 포함) ---
28
  def parse_code_from_response(response_text: str) -> str | None:
 
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:
36
  with open("main.c", "w", encoding='utf-8') as f: f.write(code)
 
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_ide(initial_code: str, full_instruction: str):
47
+ if not full_instruction:
48
+ yield initial_code, "Error: Instruction cannot be empty."
49
+ return
50
+
51
+ # 'and', 'then', ',' 등을 기준으로 명령어를 여러 단계로 분리
52
+ tasks = [task.strip() for task in re.split(r'\s+and\s+|\s*,\s*then\s*|\s*그리고\s*', full_instruction, flags=re.IGNORECASE)]
53
 
54
+ current_code = initial_code
55
+ output_log = []
56
+ step = 1
57
+
58
+ for task in tasks:
59
+ lower_task = task.lower()
60
+ output_log.append(f"▶ Step {step}: Executing '{task}'...")
61
+ yield current_code, "\n".join(output_log)
62
+ time.sleep(0.5)
63
+
64
+ # 1. 생성 (Generation)
65
+ if "generate" in lower_task or "create" in lower_task or "만들어줘" in lower_task:
66
+ prompt = f"Generate a complete, compilable C code for this request: '{task}'. ONLY output the raw C code, without markdown or explanations."
67
+ new_code = call_mistral_api([{"role": "user", "content": prompt}])
68
+ current_code = new_code if new_code and "Error" not in new_code else current_code
69
+ output_log.append(f"✅ Code generated and updated in the editor.")
70
+ yield current_code, "\n".join(output_log)
71
+
72
+ # 2. 컴파일 및 실행 (Compile & Run)
73
+ elif "compile" in lower_task or "run" in lower_task or "실행" in lower_task:
74
+ if not current_code:
75
+ output_log.append("❌ Error: Code is empty. Cannot compile.")
76
+ yield current_code, "\n".join(output_log)
77
+ break
78
+ result = compile_and_run_c_code(current_code)
79
+ output_log.append(result)
80
+ yield current_code, "\n".join(output_log)
81
+
82
+ # 3. 분석/리팩토링 (Analyze/Refactor)
83
+ else:
84
+ if not current_code:
85
+ output_log.append("❌ Error: Code is empty. Cannot analyze.")
86
+ yield current_code, "\n".join(output_log)
87
+ break
88
+ prompt = f"You are a senior C code reviewer. Fulfill this instruction: '{task}'. 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{current_code}\n```"
89
+ analysis_result = call_mistral_api([{"role": "user", "content": prompt}])
90
+
91
+ refactored_code = parse_code_from_response(analysis_result)
92
+ if refactored_code:
93
+ current_code = refactored_code
94
+ output_log.append(f"✅ Code refactored and updated in the editor.")
95
+ output_log.append(f"🔎 Analysis Result:\n{analysis_result}")
96
+ yield current_code, "\n".join(output_log)
97
+
98
+ step += 1
99
 
100
+ output_log.append("\n--- All tasks complete. ---")
101
+ yield current_code, "\n".join(output_log)
102
+
103
+
104
+ # --- 4. 통합된 Gradio UI ---
 
 
 
105
  with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="indigo", secondary_hue="blue"), css="footer {visibility: hidden}") as demo:
106
+ gr.Markdown("# 💻 The True C-Codestral IDE Agent")
107
 
108
  with gr.Tabs():
109
+ with gr.TabItem("👨‍💻 IDE Agent"):
110
+ with gr.Row(equal_height=True):
111
  with gr.Column(scale=2):
112
+ 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}')
113
 
114
  with gr.Column(scale=1):
115
+ instruction_box = gr.Textbox(label="Instruction", placeholder="e.g., 'Refactor this code for readability, and then compile it'", lines=4)
116
+ execute_btn = gr.Button("Execute", variant="primary", size="lg")
117
+ output_box = gr.Textbox(label="Console / Output", lines=21, interactive=False, show_copy_button=True, max_lines=50)
118
+
119
+ execute_btn.click(
120
+ fn=intelligent_agent_ide,
121
+ inputs=[code_editor, instruction_box],
122
+ outputs=[code_editor, output_box]
123
+ )
124
+
125
+ with gr.TabItem("🛠️ MCP Tools API"):
126
+ gr.Markdown("## Available MCP Tools for other Agents\nThese APIs are the building blocks of our IDE agent.")
 
 
 
 
 
 
 
 
127
  with gr.Accordion("Tool: Generate C Code", open=False):
128
+ # MCP용 툴은 'generate_c_code' 함수를 직접 노출
129
+ prompt_input = gr.Textbox(label="Description")
130
+ code_output = gr.Code(language="c", label="Generated C Code")
131
+ gr.Interface(fn=generate_c_code, inputs=prompt_input, outputs=code_output)
132
  with gr.Accordion("Tool: Compile & Run C Code", open=False):
133
+ code_input_run = gr.Code(language="c", label="C Code to Run")
134
+ text_output_run = gr.Textbox(label="Output")
135
+ gr.Interface(fn=compile_and_run_c_code, inputs=code_input_run, outputs=text_output_run)
136
 
137
  if __name__ == "__main__":
138
  demo.queue().launch()