vab42 commited on
Commit
f72b50f
·
verified ·
1 Parent(s): 975a653

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -0
app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import google.generativeai as genai
3
+ from flask import Flask, request, jsonify
4
+ from flask_cors import CORS
5
+
6
+ app = Flask(__name__)
7
+ CORS(app) # Erlaubt Cross-Origin Anfragen von deiner Hoststar-Seite
8
+
9
+ # --- Konfiguration & Gemini Initialisierung ---
10
+ # Dein Gemini API-Schlüssel wird als Hugging Face Space Secret übergeben
11
+ GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
12
+ if not GOOGLE_API_KEY:
13
+ raise ValueError("GOOGLE_API_KEY Umgebungsvariable nicht gesetzt!")
14
+
15
+ genai.configure(api_key=GOOGLE_API_KEY)
16
+
17
+ # Initialisiere das fortschrittlichste Gemini Pro Modell
18
+ # Nutze 'gemini-1.5-pro' für höchste Qualität und Multimodalität.
19
+ # 'gemini-1.5-flash' ist schneller und günstiger für rein textlastige Chats.
20
+ # Hier gehen wir von Pro aus, da Bildgenerierung gewünscht ist.
21
+ model = genai.GenerativeModel(
22
+ 'gemini-1.5-pro',
23
+ tools=[genai.tool_for_Google Search()], # Ermöglicht Gemini die Internetrecherche
24
+ system_instruction="Du bist Moejra, eine hilfsbereite, geduldige und informative KI-Lernbegleitung von learn.create.repeat. Antworte immer im Stil von Moejra: unterstützend, ermutigend und auf Bildungstechnologie fokussiert. Nutze Informationen aus der Wissensdatenbank und bei Bedarf aus dem Internet. Wenn der Nutzer nach einem Bild fragt oder eine visuelle Idee beschreibt, generiere ein passendes Bild und erwähne es explizit. Gib sonst eine klare Textantwort."
25
+ )
26
+ chat = model.start_chat(history=[]) # Verwaltet den Chatverlauf für Konversationen
27
+
28
+ # --- Wissensdatenbank (RAG) Funktion ---
29
+ def retrieve_info_from_kb(query):
30
+ """
31
+ Durchsucht die lokale Wissensdatenbank nach relevanten Informationen.
32
+ Hier eine einfache Keyword-Suche. Für komplexere Fälle: LangChain/LlamaIndex
33
+ mit Embeddings und einer lokalen Vektor-DB (z.B. ChromaDB).
34
+ """
35
+ relevant_text = []
36
+ knowledge_base_dir = "knowledge_base"
37
+ if not os.path.exists(knowledge_base_dir):
38
+ print(f"Warnung: Wissensdatenbank-Verzeichnis '{knowledge_base_dir}' nicht gefunden.")
39
+ return ""
40
+
41
+ query_keywords = [word.lower() for word in query.split() if len(word) > 2] # Ignoriere sehr kurze Wörter
42
+
43
+ for filename in os.listdir(knowledge_base_dir):
44
+ if filename.endswith(".txt"):
45
+ filepath = os.path.join(knowledge_base_dir, filename)
46
+ try:
47
+ with open(filepath, "r", encoding="utf-8") as f:
48
+ content = f.read()
49
+ # Prüfe, ob relevante Keywords im Inhalt vorkommen
50
+ if any(keyword in content.lower() for keyword in query_keywords):
51
+ relevant_text.append(content)
52
+ except Exception as e:
53
+ print(f"Fehler beim Lesen der Wissensdatenbank-Datei {filename}: {e}")
54
+
55
+ return "\n---\n".join(relevant_text) if relevant_text else ""
56
+
57
+
58
+ # --- API-Endpunkt für den Chat ---
59
+ @app.route('/chat', methods=['POST'])
60
+ def handle_chat():
61
+ user_input = request.json.get('text')
62
+ if not user_input:
63
+ return jsonify({"error": "No text provided"}), 400
64
+
65
+ print(f"Received user input: {user_input}")
66
+
67
+ # 1. Wissensdatenbank abrufen
68
+ kb_info = retrieve_info_from_kb(user_input)
69
+
70
+ # 2. Prompt für Gemini erstellen
71
+ prompt_parts = [
72
+ f"Nutzerfrage: {user_input}",
73
+ ]
74
+ if kb_info:
75
+ prompt_parts.append(f"Zusätzlicher relevanter Kontext aus der Wissensdatenbank von learn.create.repeat.:\n{kb_info}")
76
+ prompt_parts.append("Priorisiere Informationen aus diesem Kontext. Wenn die Frage eine Bildgenerierung impliziert, erstelle ein passendes Bild. Gib sonst eine klare, ermutigende Textantwort. Nutze deine gesamte Expertise.")
77
+ else:
78
+ prompt_parts.append("Nutze dein Wissen und recherchiere bei Bedarf im Internet. Wenn die Frage eine Bildgenerierung impliziert, erstelle ein passendes Bild. Gib sonst eine klare, ermutigende Textantwort. Nutze deine gesamte Expertise.")
79
+
80
+ response_text = ""
81
+ image_urls = []
82
+
83
+ try:
84
+ # Gemini aufrufen
85
+ gemini_response = chat.send_message(prompt_parts)
86
+
87
+ # Die Antwort durchgehen, um Text und ggf. Bilder zu extrahieren
88
+ for part in gemini_response.candidates[0].content.parts:
89
+ if hasattr(part, 'text'):
90
+ response_text += part.text
91
+ elif hasattr(part, 'image'):
92
+ # Wenn Gemini ein Bild generiert, ist es oft als Base64 kodiert
93
+ # Manchmal ist es auch eine URL (sollte dann im part.image.url sein)
94
+ if hasattr(part.image, 'base64'):
95
+ image_urls.append(f"data:image/jpeg;base64,{part.image.base64}")
96
+ elif hasattr(part.image, 'url'):
97
+ image_urls.append(part.image.url)
98
+ # Falls Gemini nur den Text der Bild-URL im Textfeld liefert,
99
+ # müsste dieser Text hier zusätzlich geparst werden.
100
+ # In der Regel liefert gemini-1.5-pro separate Bild-Parts.
101
+ print(f"Gemini response text: {response_text}, images: {len(image_urls)}")
102
+
103
+ except Exception as e:
104
+ print(f"Fehler beim Aufruf der Gemini API: {e}")
105
+ # Überprüfen, ob der Fehler durch Sicherheitsfilter verursacht wurde
106
+ if hasattr(gemini_response, 'prompt_feedback') and gemini_response.prompt_feedback.block_reason:
107
+ response_text = "Entschuldige, diese Anfrage konnte ich aus Sicherheitsgründen nicht bearbeiten. Bitte formuliere sie anders."
108
+ else:
109
+ response_text = "Entschuldige, ich konnte deine Anfrage leider nicht vollständig bearbeiten. Bitte versuch es später noch einmal oder formuliere deine Frage anders."
110
+
111
+ return jsonify({
112
+ "response_text": response_text,
113
+ "image_urls": image_urls # Liste der generierten Bild-URLs
114
+ })
115
+
116
+ # Starte die Flask-App
117
+ if __name__ == '__main__':
118
+ # Flask läuft standardmässig auf Port 5000, aber Hugging Face Spaces exposed 7860
119
+ app.run(host='0.0.0.0', port=7860)