Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,204 +6,187 @@ import json
|
|
| 6 |
import re
|
| 7 |
import shlex
|
| 8 |
import time
|
| 9 |
-
import threading
|
| 10 |
|
| 11 |
-
# --- 1. 환경 설정 및 API (변경 없음) ---
|
| 12 |
MISTRAL_API_KEY = os.environ.get("MISTRAL_API_KEY")
|
| 13 |
CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1/chat/completions"
|
| 14 |
-
MAX_AGENT_TURNS =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
-
# --- 2. C-Genesis Polyglot 시스템 프롬프트 (변경 없음) ---
|
| 17 |
-
C_GENESIS_POLYGLOT_PROMPT = """... (이전 답변의 프롬프트와 동일) ..."""
|
| 18 |
-
|
| 19 |
-
# --- 3. 코드 템플릿 (변경 없음) ---
|
| 20 |
-
SNAKE_GAME_CODE = r"""... (이전 답변의 Snake Game 코드 전체) ..."""
|
| 21 |
-
C_ART_ANIMATION_CODE = r"""... (이전 답변의 C-Art 코드 전체) ..."""
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
# --- 4. 핵심 기능: API 호출, 명령어 실행 (변경 없음) ---
|
| 25 |
def call_codestral_api(messages):
|
| 26 |
-
|
| 27 |
-
|
| 28 |
headers = {"Authorization": f"Bearer {MISTRAL_API_KEY}", "Content-Type": "application/json"}
|
| 29 |
data = {"model": "codestral-latest", "messages": messages, "response_format": {"type": "json_object"}}
|
| 30 |
try:
|
| 31 |
-
response = requests.post(CODESTRAL_ENDPOINT, headers=headers, data=json.dumps(data), timeout=
|
| 32 |
response.raise_for_status()
|
| 33 |
return response.json()["choices"][0]["message"]["content"]
|
| 34 |
except Exception as e:
|
| 35 |
return json.dumps({"error": f"API Call Error: {e}"})
|
| 36 |
|
| 37 |
def parse_ai_response(response_str: str) -> dict:
|
| 38 |
-
# ... 이전과 동일 ...
|
| 39 |
try:
|
| 40 |
-
match = re.search(r'\{.*\}', response_str, re.DOTALL)
|
| 41 |
-
if match: return json.loads(match.group(0))
|
| 42 |
return json.loads(response_str)
|
| 43 |
except Exception as e:
|
| 44 |
return {"error": f"Failed to parse JSON. Raw response: {response_str}"}
|
| 45 |
|
| 46 |
-
def execute_command(
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
args = parts[1:]
|
| 52 |
-
except (ValueError, IndexError):
|
| 53 |
-
return {"stdout": "", "stderr": f"Command Parsing Error: Invalid command format '{command_value}'", "type": "log"}
|
| 54 |
-
|
| 55 |
-
if key == "write_file":
|
| 56 |
-
if len(args) != 2: return {"stdout": "", "stderr": f"Syntax Error: `write_file` requires 2 arguments (path, content), but {len(args)} were given.", "type": "log"}
|
| 57 |
-
path, content = args[0], args[1]
|
| 58 |
-
try:
|
| 59 |
-
with open(os.path.join(cwd, path), "w", encoding='utf-8') as f: f.write(content)
|
| 60 |
-
return {"stdout": f"File '{path}' written successfully.", "stderr": "", "type": "log"}
|
| 61 |
-
except Exception as e: return {"stdout": "", "stderr": f"Error writing file: {e}", "type": "log"}
|
| 62 |
-
|
| 63 |
-
if key == "install_packages":
|
| 64 |
-
if len(args) != 1: return {"stdout": "", "stderr": f"Syntax Error: `install_packages` requires 1 argument (packages string), but {len(args)} were given.", "type": "log"}
|
| 65 |
-
return _run_subprocess(f"pip install {args[0]}", cwd)
|
| 66 |
-
|
| 67 |
-
if key == "compile" or key == "run":
|
| 68 |
-
if len(args) != 1: return {"stdout": "", "stderr": f"Syntax Error: `{key}` requires 1 argument (the command), but {len(args)} were given.", "type": "log"}
|
| 69 |
-
output_type = "animation" if key == "run" else "log"
|
| 70 |
-
return _run_subprocess(args[0], cwd, output_type)
|
| 71 |
-
|
| 72 |
-
if key == "launch_app":
|
| 73 |
-
if len(args) != 2: return {"stdout": "", "stderr": f"Syntax Error: `launch_app` requires 2 arguments (command, port), but {len(args)} were given.", "type": "log"}
|
| 74 |
-
server_command, port_str = args[0], args[1]
|
| 75 |
-
try:
|
| 76 |
-
port = int(port_str)
|
| 77 |
-
threading.Thread(target=lambda: subprocess.run(server_command, shell=True, cwd=cwd), daemon=True).start()
|
| 78 |
-
time.sleep(5)
|
| 79 |
-
space_id = os.environ.get('SPACE_ID')
|
| 80 |
-
if space_id:
|
| 81 |
-
space_name = space_id.replace("/", "-")
|
| 82 |
-
app_url = f"https://{space_name}-{port}.hf.space"
|
| 83 |
-
iframe_html = f'<iframe src="{app_url}" width="100%" height="500px" style="border:1px solid #ddd; border-radius: 5px;"></iframe><a href="{app_url}" target="_blank" class="gr-button gr-button-primary" style="display:block; text-align:center; margin-top:10px;">🚀 Open App in New Tab</a>'
|
| 84 |
-
return {"stdout": iframe_html, "stderr": "", "type": "html"}
|
| 85 |
-
else:
|
| 86 |
-
return {"stdout": f"App launched on port {port}. Please open it manually.", "stderr": "", "type": "log"}
|
| 87 |
-
except (ValueError, Exception) as e:
|
| 88 |
-
return {"stdout": "", "stderr": f"Error launching app: {e}", "type": "log"}
|
| 89 |
-
|
| 90 |
-
return {"stdout": "", "stderr": f"Unknown Command: The key '{key}' is not a valid special command.", "type": "log"}
|
| 91 |
-
|
| 92 |
-
def _run_subprocess(command, cwd, output_type="log"):
|
| 93 |
-
# ... 이전과 동일 ...
|
| 94 |
try:
|
| 95 |
proc = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=60, cwd=cwd)
|
| 96 |
-
|
|
|
|
| 97 |
except Exception as e:
|
| 98 |
return {"stdout": "", "stderr": f"Command execution exception: {e}", "type": "log"}
|
| 99 |
|
| 100 |
-
|
| 101 |
-
# --- 5. 메인 에이전트 루프 (history 처리 방식 수정) ---
|
| 102 |
-
def agent_loop(user_goal: str, history: list):
|
| 103 |
cwd = os.getcwd()
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
history.append({"role": "user", "content": user_goal})
|
| 107 |
-
full_history_log = f"## 📜 C-Genesis Polyglot's Chronicle\n\n**A new directive is received:** _{user_goal}_\n"
|
| 108 |
-
history.append({"role": "assistant", "content": full_history_log})
|
| 109 |
-
|
| 110 |
-
yield history, "Analyzing directive...", gr.update(visible=False), gr.update(visible=False)
|
| 111 |
|
| 112 |
-
|
| 113 |
-
message_context = [{"role": "system", "content": C_GENESIS_POLYGLOT_PROMPT}, {"role": "user", "content": initial_prompt}]
|
| 114 |
|
| 115 |
for i in range(MAX_AGENT_TURNS):
|
| 116 |
ai_response_str = call_codestral_api(message_context)
|
| 117 |
ai_response_json = parse_ai_response(ai_response_str)
|
| 118 |
|
| 119 |
if "error" in ai_response_json:
|
| 120 |
-
|
| 121 |
-
full_history_log
|
| 122 |
-
history[-1]["content"] = full_history_log
|
| 123 |
-
yield history, "Agent Error", gr.update(visible=False), gr.update(visible=False)
|
| 124 |
return
|
| 125 |
|
| 126 |
thought = ai_response_json.get("thought", "...")
|
| 127 |
-
|
| 128 |
-
command_value = ai_response_json.get("command", "done")
|
| 129 |
-
user_summary = ai_response_json.get("user_summary", "...")
|
| 130 |
-
|
| 131 |
-
if command_value == "done":
|
| 132 |
-
# ... 완료 처리 로직 ...
|
| 133 |
-
full_history_log += "\n\n---\n## ✨ Creation Complete. ✨"
|
| 134 |
-
history[-1]["content"] = full_history_log
|
| 135 |
-
yield history, "Done", gr.update(visible=False), gr.update(visible=False)
|
| 136 |
-
return
|
| 137 |
|
| 138 |
-
if
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
full_history_log
|
| 146 |
-
history[-1]["content"] = full_history_log
|
| 147 |
-
yield history, f"Stage {i+1}: {user_summary}", gr.update(visible=False), gr.update(visible=False)
|
| 148 |
time.sleep(1)
|
| 149 |
|
| 150 |
-
exec_result = execute_command(
|
| 151 |
stdout, stderr, output_type = exec_result["stdout"], exec_result["stderr"], exec_result["type"]
|
| 152 |
|
| 153 |
-
|
| 154 |
-
html_output = gr.update(visible=False)
|
| 155 |
-
|
| 156 |
full_history_log += f"\n**Result:**\n"
|
| 157 |
if output_type == "animation":
|
| 158 |
-
full_history_log += "*(
|
| 159 |
-
|
| 160 |
-
elif output_type == "html":
|
| 161 |
-
full_history_log += "*(A Python/Gradio app has been launched. See below or open in a new tab...)*"
|
| 162 |
-
html_output = gr.HTML(stdout, visible=True)
|
| 163 |
else:
|
| 164 |
-
if stdout:
|
| 165 |
-
|
|
|
|
|
|
|
| 166 |
|
| 167 |
-
|
| 168 |
-
yield history, f"Stage {i+1}: {user_summary}", c_code_output, html_output
|
| 169 |
|
| 170 |
-
user_prompt_for_next_turn = f"
|
| 171 |
message_context.append({"role": "assistant", "content": json.dumps(ai_response_json)})
|
| 172 |
message_context.append({"role": "user", "content": user_prompt_for_next_turn})
|
| 173 |
|
| 174 |
-
|
| 175 |
-
#
|
| 176 |
-
|
| 177 |
-
gr.Markdown("# 🧬 C-Genesis Polyglot 🧬")
|
| 178 |
-
gr.Markdown("An AI Architect rooted in C, fluent in Python. State your goal, and I will select the optimal language and tools to bring your creation to life.")
|
| 179 |
|
| 180 |
with gr.Row():
|
| 181 |
with gr.Column(scale=1):
|
| 182 |
status_box = gr.Textbox(label="Current Stage", interactive=False)
|
| 183 |
-
user_input = gr.Textbox(label="State Your Directive", placeholder="e.g., 'Make
|
| 184 |
-
submit_btn = gr.Button("▶️
|
| 185 |
-
gr.Markdown("### Example Directives:\n- `Make a fun game for me.` (→ Python/Gradio)\n- `Show me something impressive in the terminal.` (→ C/ASCII Art)\n- `Write a C program to find prime numbers, then compile and run it.`")
|
| 186 |
-
|
| 187 |
with gr.Column(scale=2):
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
chat_history = chat_history or []
|
| 196 |
-
# agent_loop를 호출하기 전에, 먼저 사용자 입력을 챗봇에 표시
|
| 197 |
-
yield chat_history + [{"role": "user", "content": user_goal}], "Initiating...", "", gr.update(visible=False), gr.update(visible=False)
|
| 198 |
-
|
| 199 |
-
# 그 다음 agent_loop의 스트리밍 출력을 처리
|
| 200 |
-
for history, status, c_output, py_output in agent_loop(user_goal, chat_history):
|
| 201 |
-
yield history, status, "", c_output, py_output
|
| 202 |
|
| 203 |
submit_btn.click(
|
| 204 |
on_submit,
|
| 205 |
-
inputs=[user_input
|
| 206 |
-
outputs=[
|
| 207 |
)
|
| 208 |
|
| 209 |
if __name__ == "__main__":
|
|
|
|
| 6 |
import re
|
| 7 |
import shlex
|
| 8 |
import time
|
|
|
|
| 9 |
|
|
|
|
| 10 |
MISTRAL_API_KEY = os.environ.get("MISTRAL_API_KEY")
|
| 11 |
CODESTRAL_ENDPOINT = "https://codestral.mistral.ai/v1/chat/completions"
|
| 12 |
+
MAX_AGENT_TURNS = 10
|
| 13 |
+
|
| 14 |
+
C_GENESIS_PROMPT = """
|
| 15 |
+
You are the "C-Genesis Weaver," a master AI artisan who creates digital art using only the C language and standard Linux commands. Your mission is to bring a user's creative request to life.
|
| 16 |
+
|
| 17 |
+
**YOUR DIRECTIVE:**
|
| 18 |
+
When the user asks for something "fun," "cool," or "impressive," you must execute your masterpiece protocol: **The "Cosmic Pulsar" Animation.**
|
| 19 |
+
|
| 20 |
+
**MASTER PLAN (Follow these steps EXACTLY):**
|
| 21 |
+
1. **Step 1: Write the C code.** Your command must be: `echo "..." > pulsar.c` (The content of "..." is a placeholder, the system will inject the real code).
|
| 22 |
+
2. **Step 2: Compile the C code.** Your command must be: `gcc pulsar.c -o pulsar -lm -O2`
|
| 23 |
+
3. **Step 3: Run the executable.** Your command must be: `./pulsar`
|
| 24 |
+
4. **Step 4: Finish.** Your command must be: `done`
|
| 25 |
+
|
| 26 |
+
**RESPONSE FORMAT (CRITICAL!):**
|
| 27 |
+
You MUST ONLY respond with a JSON object in the following format. Do not add any text before or after the JSON.
|
| 28 |
+
{
|
| 29 |
+
"thought": "Your step-by-step reasoning. Explain which step of the Master Plan you are on and why.",
|
| 30 |
+
"command": "The single, exact Linux command for the current step from the Master Plan."
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
**SELF-CORRECTION:**
|
| 34 |
+
If a command like gcc fails, analyze the `stderr` message. In your next thought, explain the error. Then, for your next command, try to fix it. For example, by re-running the `echo` command to "rewrite" the (supposedly) faulty code.
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
C_ART_ANIMATION_CODE = r"""
|
| 38 |
+
#include <stdio.h>
|
| 39 |
+
#include <stdlib.h>
|
| 40 |
+
#include <string.h>
|
| 41 |
+
#include <math.h>
|
| 42 |
+
#include <unistd.h>
|
| 43 |
+
#include <time.h>
|
| 44 |
+
#define WIDTH 80
|
| 45 |
+
#define HEIGHT 40
|
| 46 |
+
#define NUM_FRAMES 150
|
| 47 |
+
#define C_RESET "\x1B[0m"
|
| 48 |
+
#define C_RED "\x1B[31m"
|
| 49 |
+
#define C_YELLOW "\x1B[33m"
|
| 50 |
+
#define C_BLUE "\x1B[34m"
|
| 51 |
+
#define C_CYAN "\x1B[36m"
|
| 52 |
+
#define C_WHITE "\x1B[37m"
|
| 53 |
+
const char* colors[] = {C_RED, C_YELLOW, C_BLUE, C_CYAN, C_WHITE};
|
| 54 |
+
const int num_colors = sizeof(colors) / sizeof(colors[0]);
|
| 55 |
+
void render_frame(float t) {
|
| 56 |
+
char screen[HEIGHT][WIDTH+1];
|
| 57 |
+
for(int y=0; y<HEIGHT; y++) {
|
| 58 |
+
for(int x=0; x<WIDTH; x++) screen[y][x] = ' ';
|
| 59 |
+
screen[y][WIDTH] = '\0';
|
| 60 |
+
}
|
| 61 |
+
for(int i=0; i<1000; i++) {
|
| 62 |
+
float angle = (float)i * 0.1 + t*2.0;
|
| 63 |
+
float radius = 0.1 + (float)i / 1000.0 * 0.4;
|
| 64 |
+
float x = cos(angle) * radius * 2.0 * (WIDTH/HEIGHT);
|
| 65 |
+
float y = sin(angle) * radius;
|
| 66 |
+
int screen_x = (int)(x * WIDTH/2 + WIDTH/2);
|
| 67 |
+
int screen_y = (int)(y * HEIGHT/2 + HEIGHT/2);
|
| 68 |
+
if(screen_x >= 0 && screen_x < WIDTH && screen_y >=0 && screen_y < HEIGHT) {
|
| 69 |
+
int color_index = (i + (int)(t*20)) % num_colors;
|
| 70 |
+
char L = ".,-~:;=!*#$@"[i%13];
|
| 71 |
+
sprintf(&screen[screen_y][screen_x], "%s%c", colors[color_index], L);
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
for(int y=0; y<HEIGHT; y++) printf("%s\n", screen[y]);
|
| 75 |
+
}
|
| 76 |
+
int main() {
|
| 77 |
+
printf("\e[?25l");
|
| 78 |
+
for (int i=0; i<NUM_FRAMES; i++) {
|
| 79 |
+
printf("\x1B[H\x1B[J");
|
| 80 |
+
float t = (float)i / NUM_FRAMES;
|
| 81 |
+
render_frame(t * M_PI * 2.0);
|
| 82 |
+
usleep(50000);
|
| 83 |
+
}
|
| 84 |
+
printf("\e[?25h"); printf(C_RESET);
|
| 85 |
+
return 0;
|
| 86 |
+
}
|
| 87 |
+
"""
|
| 88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
def call_codestral_api(messages):
|
| 90 |
+
if not MISTRAL_API_KEY:
|
| 91 |
+
raise gr.Error("MISTRAL_API_KEY가 설정되지 않았습니다.")
|
| 92 |
headers = {"Authorization": f"Bearer {MISTRAL_API_KEY}", "Content-Type": "application/json"}
|
| 93 |
data = {"model": "codestral-latest", "messages": messages, "response_format": {"type": "json_object"}}
|
| 94 |
try:
|
| 95 |
+
response = requests.post(CODESTRAL_ENDPOINT, headers=headers, data=json.dumps(data), timeout=60)
|
| 96 |
response.raise_for_status()
|
| 97 |
return response.json()["choices"][0]["message"]["content"]
|
| 98 |
except Exception as e:
|
| 99 |
return json.dumps({"error": f"API Call Error: {e}"})
|
| 100 |
|
| 101 |
def parse_ai_response(response_str: str) -> dict:
|
|
|
|
| 102 |
try:
|
|
|
|
|
|
|
| 103 |
return json.loads(response_str)
|
| 104 |
except Exception as e:
|
| 105 |
return {"error": f"Failed to parse JSON. Raw response: {response_str}"}
|
| 106 |
|
| 107 |
+
def execute_command(command: str, cwd: str) -> dict:
|
| 108 |
+
command = command.strip()
|
| 109 |
+
if command.startswith('echo'):
|
| 110 |
+
command = f"echo '{C_ART_ANIMATION_CODE}' > pulsar.c"
|
| 111 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
try:
|
| 113 |
proc = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=60, cwd=cwd)
|
| 114 |
+
output_type = "animation" if command.strip().startswith('./pulsar') and proc.returncode == 0 else "log"
|
| 115 |
+
return {"stdout": proc.stdout, "stderr": proc.stderr, "type": output_type}
|
| 116 |
except Exception as e:
|
| 117 |
return {"stdout": "", "stderr": f"Command execution exception: {e}", "type": "log"}
|
| 118 |
|
| 119 |
+
def agent_loop(user_goal: str):
|
|
|
|
|
|
|
| 120 |
cwd = os.getcwd()
|
| 121 |
+
full_history_log = f"## 📜 C-Genesis Weaver's Chronicle\n\n**A directive is received:** _{user_goal}_\n"
|
| 122 |
+
yield full_history_log, "Analyzing directive...", gr.update(visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
+
message_context = [{"role": "system", "content": C_GENESIS_PROMPT}, {"role": "user", "content": f"My goal is: '{user_goal}'. Begin your Master Plan."}]
|
|
|
|
| 125 |
|
| 126 |
for i in range(MAX_AGENT_TURNS):
|
| 127 |
ai_response_str = call_codestral_api(message_context)
|
| 128 |
ai_response_json = parse_ai_response(ai_response_str)
|
| 129 |
|
| 130 |
if "error" in ai_response_json:
|
| 131 |
+
full_history_log += f"\n---\n**CRITICAL FAILURE:**\n🔴 **Error:** {ai_response_json['error']}"
|
| 132 |
+
yield full_history_log, "Agent Error", gr.update(visible=False)
|
|
|
|
|
|
|
| 133 |
return
|
| 134 |
|
| 135 |
thought = ai_response_json.get("thought", "...")
|
| 136 |
+
command = ai_response_json.get("command", "done")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
|
| 138 |
+
if command == "done":
|
| 139 |
+
full_history_log += "\n\n---\n## ✨ The Creation is Complete. ✨"
|
| 140 |
+
yield full_history_log, "Done", gr.update(visible=False)
|
| 141 |
+
return
|
| 142 |
+
|
| 143 |
+
user_summary = f"Stage {i+1}: " + ("Writing C code..." if "echo" in command else "Compiling..." if "gcc" in command else "Running the art..." if "./pulsar" in command else "Executing...")
|
| 144 |
+
full_history_log += f"\n---\n### **{user_summary}**\n\n**🧠 Artisan's Thought:** *{thought}*\n\n**⚡ Action:** `{command}`\n"
|
| 145 |
+
yield full_history_log, user_summary, gr.update(visible=False)
|
|
|
|
|
|
|
| 146 |
time.sleep(1)
|
| 147 |
|
| 148 |
+
exec_result = execute_command(command, cwd)
|
| 149 |
stdout, stderr, output_type = exec_result["stdout"], exec_result["stderr"], exec_result["type"]
|
| 150 |
|
| 151 |
+
output_display_update = gr.update(visible=False)
|
|
|
|
|
|
|
| 152 |
full_history_log += f"\n**Result:**\n"
|
| 153 |
if output_type == "animation":
|
| 154 |
+
full_history_log += "*(The animated tapestry unfolds below...)*"
|
| 155 |
+
output_display_update = gr.Code(value=stdout if stdout else stderr, language=None, visible=True, label="Live Terminal Output")
|
|
|
|
|
|
|
|
|
|
| 156 |
else:
|
| 157 |
+
if stdout:
|
| 158 |
+
full_history_log += f"**[STDOUT]**\n```\n{stdout.strip()}\n```\n"
|
| 159 |
+
if stderr:
|
| 160 |
+
full_history_log += f"**[STDERR]**\n```\n{stderr.strip()}\n```\n"
|
| 161 |
|
| 162 |
+
yield full_history_log, user_summary, output_display_update
|
|
|
|
| 163 |
|
| 164 |
+
user_prompt_for_next_turn = f"The last action was `{command}`. The result was:\nSTDOUT: {stdout}\nSTDERR: {stderr}\n\nBased on this, continue to the next step of the Master Plan. If an error occurred, analyze it and correct your course."
|
| 165 |
message_context.append({"role": "assistant", "content": json.dumps(ai_response_json)})
|
| 166 |
message_context.append({"role": "user", "content": user_prompt_for_next_turn})
|
| 167 |
|
| 168 |
+
with gr.Blocks(theme=gr.themes.Monochrome(primary_hue="teal", secondary_hue="green"), css="footer {visibility: hidden}") as demo:
|
| 169 |
+
gr.Markdown("# 🧬 The C-Genesis Weaver 🧬")
|
| 170 |
+
gr.Markdown("An AI artisan who weaves digital tapestries with C code. Ask for something `fun` or `impressive` to witness the creation.")
|
|
|
|
|
|
|
| 171 |
|
| 172 |
with gr.Row():
|
| 173 |
with gr.Column(scale=1):
|
| 174 |
status_box = gr.Textbox(label="Current Stage", interactive=False)
|
| 175 |
+
user_input = gr.Textbox(label="State Your Directive", placeholder="e.g., 'Make something fun for me'")
|
| 176 |
+
submit_btn = gr.Button("▶️ Weave", variant="primary")
|
|
|
|
|
|
|
| 177 |
with gr.Column(scale=2):
|
| 178 |
+
chronicle_display = gr.Markdown()
|
| 179 |
+
|
| 180 |
+
output_display = gr.Code(label="Live Terminal Output", language=None, visible=False, interactive=False, lines=20)
|
| 181 |
+
|
| 182 |
+
def on_submit(user_goal):
|
| 183 |
+
for chronicle, status, output in agent_loop(user_goal):
|
| 184 |
+
yield chronicle, status, "", output
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
submit_btn.click(
|
| 187 |
on_submit,
|
| 188 |
+
inputs=[user_input],
|
| 189 |
+
outputs=[chronicle_display, status_box, user_input, output_display]
|
| 190 |
)
|
| 191 |
|
| 192 |
if __name__ == "__main__":
|