import os, mimetypes, threading import gradio as gr from google import genai from google.genai import types client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) MODEL = "gemini-3.1-flash-lite-preview" def respond(message, history, state): # state bleibt server-side (darf Python-Objekte enthalten) if state is None: state = {"chat": client.chats.create(model=MODEL), "lock": threading.Lock()} text = (message or {}).get("text") or "" files = (message or {}).get("files") or [] parts = [] if text: parts.append(types.Part.from_text(text=text)) for file_path in files: mime, _ = mimetypes.guess_type(file_path) mime = mime or "application/octet-stream" with open(file_path, "rb") as f: parts.append(types.Part.from_bytes(data=f.read(), mime_type=mime)) if not parts: # nichts gesendet -> keine Änderung yield history, state return # User Nachricht in UI-Historie history = (history or []) + [[text if text else "[Datei]", ""]] with state["lock"]: out = "" for chunk in state["chat"].send_message_stream(parts): if getattr(chunk, "text", None): out += chunk.text history[-1][1] = out yield history, state with gr.Blocks() as demo: gr.Markdown("# Gemini Thinking AI") chatbot = gr.Chatbot(height=600) msg = gr.MultimodalTextbox(placeholder="Schreib was oder lade Dateien hoch…", file_count="multiple") state = gr.State(None) msg.submit(respond, inputs=[msg, chatbot, state], outputs=[chatbot, state]) gr.Button("Clear").click(lambda: ([], None), outputs=[chatbot, state]) demo.launch()