Tim13ekd's picture
Update app.py
16aec25 verified
import gradio as gr
from groq import Groq
import os
import json
import datetime
import copy
# Ordner für lokale Projekte
PROJECT_DIR = "projects"
os.makedirs(PROJECT_DIR, exist_ok=True)
# Aktuelles Projekt
current_project = {"name": None, "code": "", "chat_history": [], "checkpoints": []}
# ------------------------------
# Hilfsfunktionen
# ------------------------------
def list_projects():
files = [f.replace(".json","") for f in os.listdir(PROJECT_DIR) if f.endswith(".json")]
return files if files else ["Keine Projekte"]
def create_checkpoint():
"""Speichert aktuellen Code + Chat als Checkpoint"""
global current_project
checkpoint = {
"timestamp": datetime.datetime.now().strftime("%Y%m%d_%H%M%S"),
"code": copy.deepcopy(current_project["code"]),
"chat_history": copy.deepcopy(current_project["chat_history"])
}
current_project["checkpoints"].append(checkpoint)
def update_checkpoint_list():
return [c["timestamp"] for c in current_project["checkpoints"]] if current_project["checkpoints"] else []
def new_project():
global current_project
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
current_project = {
"name": f"Projekt_{timestamp}",
"code": """<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Neues Spiel</title></head>
<body><canvas id="game"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let x=50,y=50;
function loop(){ctx.clearRect(0,0,canvas.width,canvas.height);ctx.fillStyle='lime';ctx.fillRect(x,y,50,50);x+=1;requestAnimationFrame(loop);}
loop();
</script></body></html>""",
"chat_history": [],
"checkpoints": []
}
create_checkpoint()
return current_project["code"], "<p>Live Vorschau</p>", list_projects(), "Neues Projekt erstellt: " + current_project["name"], update_checkpoint_list()
def load_project(project_name):
global current_project
filepath = os.path.join(PROJECT_DIR,f"{project_name}.json")
if os.path.exists(filepath):
with open(filepath,"r",encoding="utf-8") as f:
current_project = json.load(f)
html_escaped = current_project["code"].replace('"', "&quot;")
iframe_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"
return current_project["code"], iframe_html, list_projects(), f"Projekt geladen: {project_name}", update_checkpoint_list()
else:
return "", "<p>Keine Vorschau</p>", list_projects(), "Projekt nicht gefunden", []
def save_project():
global current_project
if not current_project["name"]:
return "Kein Projekt aktiv!"
filepath = os.path.join(PROJECT_DIR, f"{current_project['name']}.json")
with open(filepath,"w",encoding="utf-8") as f:
json.dump(current_project,f,indent=2,ensure_ascii=False)
return f"Projekt gespeichert: {current_project['name']}"
def save_code_local(code):
global current_project
current_project["code"] = code
create_checkpoint()
return save_project(), update_checkpoint_list()
def chat_generate(api_key, model_name, user_input, current_code):
global current_project
if not api_key:
return current_code, "<p>Keine Vorschau</p>", "Bitte API-Key eingeben!", update_checkpoint_list()
try:
client = Groq(api_key=api_key)
system_prompt = {"role":"system","content":(
"Du bist ein professioneller Game Developer und AI-Coding-Assistent. "
"Bearbeite oder erweitere den gegebenen HTML5-Code, nur gültiges HTML+JS, "
"Canvas-basiertes Spiel, sofort spielbar, keine Erklärungen."
)}
user_message = {"role":"user","content": f"Aktueller Code:\n{current_code}\n\nAnfrage:\n{user_input}"}
messages = [system_prompt] + current_project["chat_history"] + [user_message]
completion = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8
)
model_response = completion.choices[0].message.content
current_project["code"] = model_response
current_project["chat_history"].append(user_message)
current_project["chat_history"].append({"role":"assistant","content":model_response})
create_checkpoint()
html_escaped = model_response.replace('"', "&quot;")
preview_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"
return model_response, preview_html, "✅ KI Update fertig", update_checkpoint_list()
except Exception as e:
return current_code, "<p>Fehler bei der Vorschau</p>", f"Fehler: {e}", update_checkpoint_list()
def load_checkpoint(checkpoint_time):
for c in current_project["checkpoints"]:
if c["timestamp"] == checkpoint_time:
current_project["code"] = c["code"]
current_project["chat_history"] = c["chat_history"]
html_escaped = c["code"].replace('"', "&quot;")
iframe_html = f"<iframe srcdoc='{html_escaped}' width='100%' height='400px' style='border:none;'></iframe>"
return current_project["code"], iframe_html, "✅ Checkpoint geladen"
return current_project["code"], "<p>Keine Vorschau</p>", "Checkpoint nicht gefunden"
def delete_checkpoint(checkpoint_time):
global current_project
current_project["checkpoints"] = [c for c in current_project["checkpoints"] if c["timestamp"] != checkpoint_time]
return update_checkpoint_list(), "✅ Checkpoint gelöscht"
# ------------------------------
# Gradio UI
# ------------------------------
with gr.Blocks() as demo:
gr.Markdown("# 🕹️ HTML5 Game Studio mit AI & Checkpoints")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### KI Beschreibung / Hinweise")
ki_desc = gr.HTML("<p>Hier erscheinen Hinweise der KI und aktuelle Anfrage</p>")
api_key_input = gr.Textbox(label="GROQ API-Key", placeholder="Hier API-Key einfügen", type="password")
model_input = gr.Textbox(label="AI Modell", placeholder="Beispiel: llama3-70b-8192 oder gpt-os", value="llama3-70b-8192")
user_input = gr.Textbox(label="Spielidee / Follow-up", placeholder="Beispiel: Gegner hinzufügen", lines=3)
with gr.Row():
btn_new = gr.Button("🆕 New Project")
btn_save_code = gr.Button("💾 Save Code")
btn_ai = gr.Button("🤖 Mit AI aktualisieren")
project_dropdown = gr.Dropdown(list_projects(), label="Projekt laden")
btn_load = gr.Button("📂 Load Project")
btn_save_project = gr.Button("💾 Save Project")
gr.Markdown("### Checkpoints")
checkpoint_dropdown = gr.Dropdown([], label="Checkpoint auswählen")
btn_load_checkpoint = gr.Button("⬅️ Wiederherstellen")
btn_delete_checkpoint = gr.Button("❌ Löschen")
code_editor = gr.Code(language="html", label="HTML5 Game Code", lines=20, value="")
status_output = gr.Textbox(label="Status", interactive=False)
with gr.Column(scale=1):
gr.Markdown("### Live Vorschau")
preview_output = gr.HTML("<p>Vorschau erscheint hier</p>")
# ------------------------------
# Events
# ------------------------------
btn_new.click(new_project, outputs=[code_editor, preview_output, project_dropdown, status_output, checkpoint_dropdown])
btn_load.click(load_project, inputs=[project_dropdown], outputs=[code_editor, preview_output, project_dropdown, status_output, checkpoint_dropdown])
btn_save_code.click(save_code_local, inputs=[code_editor], outputs=[status_output, checkpoint_dropdown])
btn_save_project.click(save_project, outputs=[status_output])
btn_ai.click(chat_generate, inputs=[api_key_input, model_input, user_input, code_editor], outputs=[code_editor, preview_output, status_output, checkpoint_dropdown])
btn_load_checkpoint.click(load_checkpoint, inputs=[checkpoint_dropdown], outputs=[code_editor, preview_output, status_output])
btn_delete_checkpoint.click(delete_checkpoint, inputs=[checkpoint_dropdown], outputs=[checkpoint_dropdown, status_output])
demo.launch()