kimhyunwoo commited on
Commit
e0c0af8
ยท
verified ยท
1 Parent(s): 963f5f3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -138
app.py CHANGED
@@ -1,15 +1,11 @@
1
  # /app.py
2
 
 
3
  import os
4
  import subprocess
5
- from fastapi import FastAPI, Request
6
- from fastapi.responses import HTMLResponse
7
- from pydantic import BaseModel
8
  from mistralai.client import MistralClient
9
 
10
- # --- 1. FastAPI ์•ฑ ๋ฐ Mistral ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” ---
11
- app = FastAPI()
12
-
13
  API_KEY = os.environ.get("MISTRAL_API_KEY")
14
  CLIENT = None
15
  if API_KEY:
@@ -23,7 +19,6 @@ else:
23
 
24
  # --- 2. ๋ฐฑ์—”๋“œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ํ•จ์ˆ˜ ---
25
  def generate_c_code(description: str) -> str:
26
- """Generates C code based on a natural language description."""
27
  if not CLIENT: return "Error: Mistral API key not configured."
28
  prompt = f"You are a C programming expert. Generate a complete, compilable C code for this request: '{description}'. ONLY output the raw C code within a single ```c code block."
29
  messages = [{"role": "user", "content": prompt}]
@@ -36,7 +31,6 @@ def generate_c_code(description: str) -> str:
36
  return code
37
 
38
  def compile_and_run_c_code(code: str) -> str:
39
- """Compiles and runs a given C code snippet and returns its output or any errors."""
40
  try:
41
  with open("main.c", "w", encoding='utf-8') as f:
42
  f.write(code)
@@ -58,144 +52,66 @@ def compile_and_run_c_code(code: str) -> str:
58
  except Exception as e:
59
  return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
60
 
61
- # --- 3. HTML, CSS, JavaScript ํ”„๋ก ํŠธ์—”๋“œ ---
62
- HTML_TEMPLATE = """
63
- <!DOCTYPE html>
64
- <html lang="en">
65
- <head>
66
- <meta charset="UTF-8">
67
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
68
- <title>C-Codestral Agent</title>
69
- <style>
70
- body { font-family: sans-serif; background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
71
- #app-container { width: 100%; max-width: 800px; height: 90vh; background: white; border-radius: 8px; box-shadow: 0 0 20px rgba(0,0,0,0.1); display: flex; flex-direction: column; }
72
- h1 { text-align: center; color: #333; padding: 20px; margin: 0; border-bottom: 1px solid #eee; }
73
- #chat-box { flex-grow: 1; padding: 20px; overflow-y: auto; }
74
- .message { margin-bottom: 15px; }
75
- .user-msg { text-align: right; }
76
- .bot-msg { text-align: left; }
77
- .msg-bubble { display: inline-block; padding: 10px 15px; border-radius: 18px; max-width: 80%; }
78
- .user-msg .msg-bubble { background-color: #007bff; color: white; }
79
- .bot-msg .msg-bubble { background-color: #e9e9eb; color: black; }
80
- pre { background-color: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 5px; white-space: pre-wrap; word-wrap: break-word; }
81
- #input-area { display: flex; padding: 20px; border-top: 1px solid #eee; }
82
- #user-input { flex-grow: 1; padding: 10px; border: 1px solid #ccc; border-radius: 20px; outline: none; }
83
- #send-btn { background: #007bff; color: white; border: none; padding: 10px 20px; margin-left: 10px; border-radius: 20px; cursor: pointer; }
84
- </style>
85
- </head>
86
- <body>
87
- <div id="app-container">
88
- <h1>๐Ÿš€ C-Codestral Agent</h1>
89
- <div id="chat-box"></div>
90
- <div id="input-area">
91
- <input type="text" id="user-input" placeholder="Ask me to generate or run C code...">
92
- <button id="send-btn">Send</button>
93
- </div>
94
- </div>
95
- <script>
96
- const chatBox = document.getElementById('chat-box');
97
- const userInput = document.getElementById('user-input');
98
- const sendBtn = document.getElementById('send-btn');
99
- let chatHistory = [];
100
-
101
- function addMessage(sender, text) {
102
- const msgDiv = document.createElement('div');
103
- msgDiv.classList.add('message', sender === 'user' ? 'user-msg' : 'bot-msg');
104
-
105
- const bubble = document.createElement('div');
106
- bubble.classList.add('msg-bubble');
107
-
108
- // Convert ```c ... ``` to <pre><code>...</code>
109
- if (text.includes('```')) {
110
- const parts = text.split(/```c|```/);
111
- parts.forEach((part, index) => {
112
- if (index % 2 === 1) { // Code block
113
- const pre = document.createElement('pre');
114
- const code = document.createElement('code');
115
- code.textContent = part.trim();
116
- pre.appendChild(code);
117
- bubble.appendChild(pre);
118
- } else { // Regular text
119
- const textNode = document.createTextNode(part);
120
- bubble.appendChild(textNode);
121
- }
122
- });
123
- } else {
124
- bubble.textContent = text;
125
- }
126
-
127
- msgDiv.appendChild(bubble);
128
- chatBox.appendChild(msgDiv);
129
- chatBox.scrollTop = chatBox.scrollHeight;
130
- }
131
-
132
- async function sendMessage() {
133
- const message = userInput.value.trim();
134
- if (!message) return;
135
-
136
- addMessage('user', message);
137
- chatHistory.push({ "role": "user", "content": message });
138
- userInput.value = '';
139
-
140
- const response = await fetch('/chat', {
141
- method: 'POST',
142
- headers: { 'Content-Type': 'application/json' },
143
- body: JSON.stringify({ message: message, history: chatHistory })
144
- });
145
- const data = await response.json();
146
- const botResponse = data.response;
147
-
148
- addMessage('bot', botResponse);
149
- chatHistory.push({ "role": "assistant", "content": botResponse });
150
- }
151
 
152
- sendBtn.addEventListener('click', sendMessage);
153
- userInput.addEventListener('keypress', (e) => {
154
- if (e.key === 'Enter') sendMessage();
155
- });
156
- </script>
157
- </body>
158
- </html>
159
- """
160
-
161
- # --- 4. FastAPI ์—”๋“œํฌ์ธํŠธ ---
162
- class ChatRequest(BaseModel):
163
- message: str
164
- history: list
165
-
166
- @app.get("/", response_class=HTMLResponse)
167
- async def get_home():
168
- return HTML_TEMPLATE
169
-
170
- @app.post("/chat")
171
- async def handle_chat(request: ChatRequest):
172
- message = request.message
173
- history = request.history
174
  lower_message = message.lower()
175
-
176
- response_text = ""
177
-
178
  if "compile" in lower_message or "run" in lower_message or "์‹คํ–‰" in lower_message:
179
  code_to_run = ""
180
- for item in reversed(history):
181
- if item['role'] == 'assistant' and "```c" in item['content']:
182
- code_to_run = item['content'].split("```c")[1].split("```")[0].strip()
183
  break
184
  if not code_to_run:
185
- response_text = "์ปดํŒŒ์ผํ•  ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”."
186
- else:
187
- response_text = compile_and_run_c_code(code_to_run)
 
 
 
188
 
189
  elif "generate" in lower_message or "create" in lower_message or "๋งŒ๋“ค์–ด์ค˜" in lower_message or "์งœ์ค˜" in lower_message:
 
190
  generated_code = generate_c_code(message)
191
- response_text = f"์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 'run this code'๋ผ๊ณ  ์ž…๋ ฅํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.\n\n```c\n{generated_code}\n```"
192
 
193
  else:
194
- if not CLIENT:
195
- response_text = "MISTRAL_API_KEY๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
196
- else:
197
- messages = history + [{"role": "user", "content": message}]
198
- response = CLIENT.chat(model="codestral-latest", messages=messages)
199
- response_text = response.choices[0].message.content
200
-
201
- return {"response": response_text}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # /app.py
2
 
3
+ import gradio as gr
4
  import os
5
  import subprocess
 
 
 
6
  from mistralai.client import MistralClient
7
 
8
+ # --- 1. ํ™˜๊ฒฝ ์„ค์ • ๋ฐ ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” ---
 
 
9
  API_KEY = os.environ.get("MISTRAL_API_KEY")
10
  CLIENT = None
11
  if API_KEY:
 
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 within a single ```c code block."
24
  messages = [{"role": "user", "content": prompt}]
 
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)
 
52
  except Exception as e:
53
  return f"--- SYSTEM ERROR ---\nAn unexpected error occurred: {str(e)}"
54
 
55
+ # --- 3. Gradio ์ฑ—๋ด‡ ๋กœ์ง ---
56
+ def agent_chat(message, history):
57
+ if not CLIENT:
58
+ yield "MISTRAL_API_KEY๋ฅผ Space Secrets์— ์„ค์ •ํ•ด์ฃผ์„ธ์š”."
59
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  lower_message = message.lower()
62
+
 
 
63
  if "compile" in lower_message or "run" in lower_message or "์‹คํ–‰" in lower_message:
64
  code_to_run = ""
65
+ for h_user, h_ai in reversed(history):
66
+ if "```c" in h_ai:
67
+ code_to_run = h_ai.split("```c")[1].split("```")[0].strip()
68
  break
69
  if not code_to_run:
70
+ yield "์ปดํŒŒ์ผํ•  ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”."
71
+ return
72
+
73
+ yield f"```c\n{code_to_run}\n```\n\n--- COMPILING & RUNNING ---"
74
+ result = compile_and_run_c_code(code_to_run)
75
+ yield result
76
 
77
  elif "generate" in lower_message or "create" in lower_message or "๋งŒ๋“ค์–ด์ค˜" in lower_message or "์งœ์ค˜" in lower_message:
78
+ yield "C ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ค‘..."
79
  generated_code = generate_c_code(message)
80
+ yield f"์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.\n\n```c\n{generated_code}\n```"
81
 
82
  else:
83
+ history_messages = []
84
+ for human, ai in history:
85
+ history_messages.append({"role": "user", "content": human})
86
+ history_messages.append({"role": "assistant", "content": ai})
87
+ history_messages.append({"role": "user", "content": message})
88
+
89
+ response = CLIENT.chat(model="codestral-latest", messages=history_messages)
90
+ yield response.choices[0].message.content
91
+
92
+ # --- 4. Gradio UI ๊ตฌ์„ฑ ---
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
+ chatbot = gr.Chatbot(label="C-Agent", height=600, bubble_full_width=False, render_markdown=True)
99
+ msg = gr.Textbox(placeholder="Ask me to generate or run C code...", show_label=False, container=False, scale=10)
100
+ btn = gr.Button("Send", scale=1)
101
+
102
+ btn.click(agent_chat, [msg, chatbot], chatbot)
103
+ msg.submit(agent_chat, [msg, chatbot], chatbot)
104
+
105
+ # Clear input after submit
106
+ clear_event = btn.click(lambda: None, None, msg, queue=False)
107
+ clear_event2 = msg.submit(lambda: None, None, msg, queue=False)
108
+
109
+ with gr.TabItem("๐Ÿ› ๏ธ MCP Tools API"):
110
+ gr.Markdown("## Available MCP Tools\nThese APIs can be used by any MCP-compliant client.")
111
+ with gr.Accordion("Tool: Generate C Code", open=False):
112
+ gr.Interface(fn=generate_c_code, inputs="text", outputs=gr.Code(language="c", label="Generated C Code"))
113
+ with gr.Accordion("Tool: Compile & Run C Code", open=False):
114
+ gr.Interface(fn=compile_and_run_c_code, inputs=gr.Code(language="c", label="C Code to Run"), outputs=gr.Textbox(label="Output/Error"))
115
+
116
+ if __name__ == "__main__":
117
+ demo.queue().launch()