VL_AI / app_2.py
dtometzki's picture
Handle thinking config per Gemini model
139b7ee verified
Raw History Blame
5.18 kB
import os
import shutil
import tempfile
import threading
import gradio as gr
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
DEFAULT_MODEL = "gemini-3.1-flash-lite-preview"
MODELS = [
"gemini-3.1-flash-lite-preview",
"gemini-3.1-pro-preview",
"gemini-3.1-flash-preview",
]
# Tools (einmalig)
tools = [
types.Tool(url_context=types.UrlContext()),
types.Tool(googleSearch=types.GoogleSearch(
)),
]
def build_generate_content_config(model_name):
config_kwargs = {"tools": tools}
# Pro-Modelle akzeptieren MINIMAL derzeit nicht.
if "pro" not in model_name:
config_kwargs["thinking_config"] = types.ThinkingConfig(
thinking_level="MINIMAL"
)
return types.GenerateContentConfig(**config_kwargs)
def create_chat_state(model_name):
return {
"model": model_name,
"chat": client.chats.create(
model=model_name,
config=build_generate_content_config(model_name),
),
"lock": threading.Lock(),
}
def respond(message, history, state, model_name):
if state is None:
state = create_chat_state(model_name)
elif state.get("model") != model_name:
state = create_chat_state(model_name)
history = history or []
text = (message or {}).get("text", "")
files = (message or {}).get("files", [])
parts = []
# 1. Dateien verarbeiten (Upload via API & UI-Vorbereitung)
for file_path in files:
# Reinen ASCII-Namen generieren (z.B. 'Lsungen-MP-4 1.pdf')
base_name = os.path.basename(file_path)
safe_name = base_name.encode('ascii', 'ignore').decode('ascii')
# Fallback, falls der Name nach der Filterung komplett leer sein sollte
if not safe_name.strip(". "):
safe_name = "upload_file.pdf"
# Temporären, komplett sicheren Pfad generieren
safe_temp_path = os.path.join(tempfile.gettempdir(), f"safe_{safe_name}")
try:
# Datei an den sicheren Ort kopieren
shutil.copy2(file_path, safe_temp_path)
# Upload mit dem sicheren Pfad durchführen
uploaded_file = client.files.upload(
file=safe_temp_path,
config=types.UploadFileConfig(display_name=safe_name)
)
parts.append(uploaded_file)
finally:
# Temporäre Kopie aufräumen, um Speicherplatz zu sparen
if os.path.exists(safe_temp_path):
os.remove(safe_temp_path)
# Datei in der Gradio UI anzeigen (hier nutzen wir den Originalpfad für die korrekte Anzeige)
history.append({"role": "user", "content": gr.FileData(path=file_path)})
# 2. Text verarbeiten
if text:
parts.append(text)
history.append({"role": "user", "content": text})
if not parts:
yield history, state
return
# 3. UI: Assistant Placeholder hinzufügen
history.append({"role": "assistant", "content": ""})
yield history, state
# 4. Gemini: Senden + Streamen
with state["lock"]:
out = ""
for chunk in state["chat"].send_message_stream(parts):
if getattr(chunk, "text", None):
out += chunk.text
history[-1]["content"] = out
yield history, state
def cleanup_gemini_files():
deleted_count = 0
# Holt alle Dateien, die mit deinem API-Key hochgeladen wurden
for f in client.files.list():
# Löscht die Datei über ihren eindeutigen Google-Ressourcennamen
client.files.delete(name=f.name)
deleted_count += 1
# Zeigt ein kleines Popup in der Gradio UI an
gr.Info(f"{deleted_count} Datei(en) erfolgreich gelöscht.")
def clear_msg():
return {"text": "", "files": []}
def reset_chat_for_model_change(_model_name):
return [], None, {"text": "", "files": []}
with gr.Blocks() as demo:
gr.Markdown("# Gemini AI Chat by Damian")
model_selector = gr.Dropdown(
choices=MODELS,
value=DEFAULT_MODEL,
label="Gemini-Modell",
info="Ein Modellwechsel startet einen neuen Chat.",
)
# Standard-Initialisierung für Gradio >= 6.0
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, model_selector], outputs=[chatbot, state]) \
.then(clear_msg, outputs=msg)
model_selector.change(
fn=reset_chat_for_model_change,
inputs=model_selector,
outputs=[chatbot, state, msg],
)
with gr.Row():
clear_btn = gr.Button("Clear Chat")
cleanup_btn = gr.Button("🗑️ Server-Dateien bereinigen")
clear_btn.click(
lambda: ([], None, {"text": "", "files": []}),
outputs=[chatbot, state, msg]
)
cleanup_btn.click(fn=cleanup_gemini_files)
if __name__ == "__main__":
demo.launch()