| import os |
| import gradio as gr |
| import mimetypes |
| from google import genai |
| from google.genai import types |
|
|
| |
| client = genai.Client( |
| api_key=os.environ.get("GEMINI_API_KEY"), |
| ) |
|
|
| MAX_FILE_SIZE_MB = 2 |
|
|
| def model_chat(message, history): |
| try: |
| contents = [] |
| last_role = None |
| |
| |
| for msg in history: |
| if isinstance(msg, dict): |
| role = msg.get("role") |
| content = msg.get("content", "") |
| else: |
| role = getattr(msg, "role", "") |
| content = getattr(msg, "content", "") |
| |
| text_val = content if isinstance(content, str) else "[Datei]" |
| |
| if role == "user": |
| if last_role == "user": |
| contents.append(types.Content(role="model", parts=[types.Part.from_text(text="[Keine Antwort erhalten]")])) |
| contents.append(types.Content(role="user", parts=[types.Part.from_text(text=text_val)])) |
| last_role = "user" |
| elif role in ["assistant", "model"]: |
| contents.append(types.Content(role="model", parts=[types.Part.from_text(text=text_val)])) |
| last_role = "model" |
|
|
| if last_role == "user": |
| contents.append(types.Content(role="model", parts=[types.Part.from_text(text="[Keine Antwort erhalten]")])) |
|
|
| |
| current_parts = [] |
| |
| |
| if message["text"]: |
| current_parts.append(types.Part.from_text(text=message["text"])) |
| |
| |
| for file_path in message["files"]: |
| file_size = os.path.getsize(file_path) / (1024 * 1024) |
| |
| if file_size > MAX_FILE_SIZE_MB: |
| yield f"⚠️ Datei '{os.path.basename(file_path)}' überspringt das 2 MB Limit ({file_size:.2f} MB)." |
| continue |
|
|
| mime_type, _ = mimetypes.guess_type(file_path) |
| mime_type = mime_type or "application/octet-stream" |
|
|
| |
| if mime_type.startswith("text/"): |
| try: |
| with open(file_path, "r", encoding="utf-8", errors="replace") as f: |
| content_str = f.read() |
| current_parts.append(types.Part.from_text(text=f"Dateiinhalt ({os.path.basename(file_path)}):\n\n{content_str}")) |
| except Exception: |
| |
| with open(file_path, "rb") as f: |
| current_parts.append(types.Part.from_bytes(data=f.read(), mime_type=mime_type)) |
| else: |
| with open(file_path, "rb") as f: |
| current_parts.append(types.Part.from_bytes(data=f.read(), mime_type=mime_type)) |
|
|
| if not current_parts: |
| yield "Bitte gib eine Nachricht ein oder lade eine passende Datei hoch." |
| return |
|
|
| contents.append(types.Content(role="user", parts=current_parts)) |
|
|
| |
| model_id = "gemini-3.1-flash-lite-preview" |
| |
| tools = [types.Tool(googleSearch=types.GoogleSearch())] |
| |
| generate_content_config = types.GenerateContentConfig( |
| thinking_config=types.ThinkingConfig(thinking_level="MINIMAL"), |
| tools=tools, |
| ) |
|
|
| |
| response_text = "" |
| for chunk in client.models.generate_content_stream( |
| model=model_id, |
| contents=contents, |
| config=generate_content_config, |
| ): |
| if chunk.text: |
| response_text += chunk.text |
| yield response_text |
| |
| except Exception as e: |
| yield f"❌ Fehler: {str(e)}" |
|
|
| |
| demo = gr.ChatInterface( |
| fn=model_chat, |
| title="Gemini Thinking AI", |
| description="KI mit Suche und universellem Datei-Upload (max. 2 MB).", |
| multimodal=True, |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |