martinbrahm commited on
Commit
45dc038
·
verified ·
1 Parent(s): eeb5b5c

Upload main.py

Browse files
Files changed (1) hide show
  1. main.py +75 -88
main.py CHANGED
@@ -3,143 +3,130 @@ import json
3
  import os
4
  import firebase_admin
5
  from firebase_admin import credentials, firestore
 
6
 
7
  app = FastAPI()
8
 
9
- # ------------------------------------------------------
10
- # 1. VERBINDUNG ZU FIREBASE HERSTELLEN
11
- # ------------------------------------------------------
 
 
 
 
 
12
  try:
13
- # Wir holen den Schlüssel aus den Hugging Face Secrets
14
  firebase_key_json = os.environ.get("FIREBASE_KEY")
15
-
16
  if firebase_key_json:
17
- # Den String wieder in ein echtes JSON-Objekt verwandeln
18
  cred_dict = json.loads(firebase_key_json)
19
  cred = credentials.Certificate(cred_dict)
20
-
21
- # Prüfen, ob die App schon läuft, um Doppel-Start zu verhindern
22
  if not firebase_admin._apps:
23
  firebase_admin.initialize_app(cred)
24
-
25
  db = firestore.client()
26
- print("✅ Erfolgreich mit Firebase Firestore verbunden!")
 
27
  else:
28
- print("⚠️ WARNUNG: Kein FIREBASE_KEY in den Settings gefunden.")
29
- db = None
30
-
31
  except Exception as e:
32
- print(f"❌ Kritischer Firebase Fehler: {e}")
33
- db = None
34
-
35
- # ------------------------------------------------------
36
- # 2. KONFIGURATION
37
- # ------------------------------------------------------
38
-
39
- # Wie heißt deine Sammlung in Firebase?
40
- # Laut deinem Pfad '/knowledge_base/...' wahrscheinlich so:
41
- COLLECTION_NAME = "knowledge_base"
42
- # Falls du die Fragen in einer 'inbox' sammeln willst:
43
- INBOX_COLLECTION = "inbox"
44
-
45
 
46
  @app.get("/")
47
  def home():
48
- if db:
49
- return {"status": "Online & mit Firebase verbunden."}
50
- else:
51
- return {"status": "Online, aber KEINE Firebase-Verbindung (Key fehlt)."}
52
 
53
  @app.post("/search")
54
  async def search_knowledge(request: Request):
55
- # --- A. DATEN EMPFANGEN (Vapi) ---
 
 
 
 
56
  try:
57
  data = await request.json()
58
- print(f"📥 Vapi Anfrage: {json.dumps(data)}")
59
  except:
60
- return {"result": "Fehler: Kein JSON."}
61
 
62
  query_text = ""
63
- # Parsing Logik
64
  if "query" in data and isinstance(data["query"], str):
65
  query_text = data["query"]
66
  elif "message" in data and "toolCalls" in data["message"]:
67
  try:
68
  args = data["message"]["toolCalls"][0]["function"]["arguments"]
69
- if isinstance(args, str):
70
- query_text = json.loads(args).get("query", "")
71
- else:
72
- query_text = args.get("query", "")
73
- except:
74
- pass
75
  elif "toolCall" in data:
76
  try:
77
  args = data["toolCall"]["function"]["arguments"]
78
- if isinstance(args, str):
79
- query_text = json.loads(args).get("query", "")
80
- else:
81
- query_text = args.get("query", "")
82
- except:
83
- pass
84
 
85
- print(f"🔎 Suche in Firebase nach: '{query_text}'")
86
 
87
- if not query_text:
88
- return {"result": "Ich habe die Frage nicht verstanden."}
89
-
90
  if not db:
91
- return {"result": "Server-Fehler: Keine Datenbankverbindung."}
92
-
93
- # --- B. SUCHE IN FIREBASE ---
94
- antwort = "Dazu habe ich leider keine Informationen in meiner Datenbank. Ich habe die Frage für unser Team notiert."
95
- treffer_gefunden = False
96
 
 
 
 
 
97
  try:
98
- # Wir laden alle Dokumente aus der Knowledge Base
99
- # (Bei sehr vielen Daten > 1000 Einträge müsste man das optimieren, aber für jetzt reicht das)
100
- docs = db.collection(COLLECTION_NAME).stream()
 
101
 
 
 
 
 
 
102
  query_lower = query_text.lower()
103
 
104
- # Einfache Suche: Wir schauen, ob Keywords aus der DB in der Frage vorkommen
105
- # Oder ob die Frage in der DB der Frage des Users ähnelt.
106
-
107
  for doc in docs:
108
- doc_data = doc.to_dict()
109
-
110
- # Wir gehen davon aus, dass deine Dokumente Felder wie 'question', 'answer' oder 'keywords' haben
111
- db_answer = doc_data.get("answer") or doc_data.get("Antwort")
112
-
113
- # Check 1: Keywords Suche (Falls du ein Feld 'keywords' hast)
114
- keywords = doc_data.get("keywords") or []
115
- if keywords and isinstance(keywords, list):
116
- if any(k.lower() in query_lower for k in keywords):
117
- antwort = db_answer
118
- treffer_gefunden = True
119
- break
120
 
121
- # Check 2: Frage-Text Suche (Falls du ein Feld 'question' hast)
122
- db_question = doc_data.get("question") or doc_data.get("Frage") or ""
123
- if db_question and db_question.lower() in query_lower:
124
- antwort = db_answer
125
- treffer_gefunden = True
126
  break
127
 
128
- # --- C. LERN-MODUS (Inbox) ---
129
- if not treffer_gefunden:
130
- print(f"⚠️ Kein Treffer. Speichere '{query_text}' in {INBOX_COLLECTION}...")
131
  try:
132
- db.collection(INBOX_COLLECTION).add({
 
133
  "question": query_text,
134
  "status": "open",
135
- "timestamp": firestore.SERVER_TIMESTAMP
 
136
  })
137
- print("📩 Erfolgreich gespeichert.")
 
138
  except Exception as e:
139
- print(f"Fehler beim Speichern in Inbox: {e}")
140
 
141
  except Exception as e:
142
- print(f" Firebase Abfrage-Fehler: {e}")
143
- return {"result": "Es gab ein Problem beim Lesen der Datenbank."}
144
 
145
- return {"result": antwort}
 
 
 
 
 
 
 
 
3
  import os
4
  import firebase_admin
5
  from firebase_admin import credentials, firestore
6
+ from datetime import datetime
7
 
8
  app = FastAPI()
9
 
10
+ # --- SETUP ---
11
+ COLLECTION_KNOWLEDGE = "knowledge_base"
12
+ COLLECTION_INBOX = "inbox"
13
+
14
+ # --- FIREBASE START ---
15
+ db = None
16
+ project_id = "Unbekannt"
17
+
18
  try:
 
19
  firebase_key_json = os.environ.get("FIREBASE_KEY")
 
20
  if firebase_key_json:
 
21
  cred_dict = json.loads(firebase_key_json)
22
  cred = credentials.Certificate(cred_dict)
 
 
23
  if not firebase_admin._apps:
24
  firebase_admin.initialize_app(cred)
 
25
  db = firestore.client()
26
+ project_id = db.project # Das ist der Beweis!
27
+ print(f"✅ SYSTEM: Verbunden mit Projekt '{project_id}'")
28
  else:
29
+ print("⚠️ FEHLER: Kein Key.")
 
 
30
  except Exception as e:
31
+ print(f"❌ FEHLER: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  @app.get("/")
34
  def home():
35
+ return {"status": "Call Agent ist online", "connected_project": project_id}
 
 
 
36
 
37
  @app.post("/search")
38
  async def search_knowledge(request: Request):
39
+ # Debug-Liste für die Rückgabe an dich
40
+ debug_log = []
41
+ debug_log.append(f"Verbinde mit Projekt-ID: {project_id}")
42
+
43
+ # 1. Parsing
44
  try:
45
  data = await request.json()
 
46
  except:
47
+ return {"result": "Fehler: Kein JSON"}
48
 
49
  query_text = ""
50
+ # Robuste Extraktion
51
  if "query" in data and isinstance(data["query"], str):
52
  query_text = data["query"]
53
  elif "message" in data and "toolCalls" in data["message"]:
54
  try:
55
  args = data["message"]["toolCalls"][0]["function"]["arguments"]
56
+ query_text = json.loads(args).get("query", "") if isinstance(args, str) else args.get("query", "")
57
+ except: pass
 
 
 
 
58
  elif "toolCall" in data:
59
  try:
60
  args = data["toolCall"]["function"]["arguments"]
61
+ query_text = json.loads(args).get("query", "") if isinstance(args, str) else args.get("query", "")
62
+ except: pass
 
 
 
 
63
 
64
+ debug_log.append(f"Suche nach: '{query_text}'")
65
 
 
 
 
66
  if not db:
67
+ return {"result": "Datenbank-Fehler", "debug": debug_log}
 
 
 
 
68
 
69
+ # 2. DIAGNOSE: Was sehen wir wirklich?
70
+ antwort = "Keine Antwort gefunden."
71
+ treffer = False
72
+
73
  try:
74
+ # Wir zählen, wie viele Dokumente wir überhaupt sehen
75
+ docs_stream = db.collection(COLLECTION_KNOWLEDGE).stream()
76
+ docs = list(docs_stream) # Liste laden
77
+ debug_log.append(f"Anzahl Dokumente in '{COLLECTION_KNOWLEDGE}': {len(docs)}")
78
 
79
+ # Falls leer, zeigen wir die Collections an, die es gibt
80
+ if len(docs) == 0:
81
+ cols = [c.id for c in db.collections()]
82
+ debug_log.append(f"WARNUNG: Sammlung leer! Vorhandene Sammlungen: {cols}")
83
+
84
  query_lower = query_text.lower()
85
 
 
 
 
86
  for doc in docs:
87
+ d = doc.to_dict()
88
+ # Wir prüfen die Felder aus deinem Screenshot
89
+ t_answer = d.get("answer")
90
+ t_question = d.get("question")
91
+ t_keywords = d.get("keywords") or []
92
+
93
+ # Match Logik
94
+ if isinstance(t_keywords, list) and any(k.lower() in query_lower for k in t_keywords):
95
+ antwort = t_answer
96
+ treffer = True
97
+ debug_log.append(f"✅ TREFFER (Keyword) in Doc {doc.id}")
98
+ break
99
 
100
+ if t_question and t_question.lower() in query_lower:
101
+ antwort = t_answer
102
+ treffer = True
103
+ debug_log.append(f"✅ TREFFER (Frage) in Doc {doc.id}")
 
104
  break
105
 
106
+ # 3. SCHREIB-TEST (Inbox)
107
+ if not treffer:
108
+ debug_log.append("⚠️ Kein Treffer. Versuche Inbox-Write...")
109
  try:
110
+ # Wir schreiben einen echten Eintrag
111
+ ref = db.collection(COLLECTION_INBOX).add({
112
  "question": query_text,
113
  "status": "open",
114
+ "timestamp": firestore.SERVER_TIMESTAMP,
115
+ "debug_info": "Vom Detektiv-Skript"
116
  })
117
+ debug_log.append(f"📩 GESPEICHERT! ID: {ref[1].id}")
118
+ antwort = "Dazu habe ich keine Infos, habe es aber notiert."
119
  except Exception as e:
120
+ debug_log.append(f" SCHREIB-FEHLER: {str(e)}")
121
 
122
  except Exception as e:
123
+ debug_log.append(f"KRITISCHER FEHLER: {str(e)}")
 
124
 
125
+ # WICHTIG: Wir geben das Debug-Log in der Antwort zurück!
126
+ # Vapi liest das nicht vor, aber du siehst es im 'Curl' oder Browser-Test.
127
+ print(json.dumps(debug_log, indent=2))
128
+
129
+ return {
130
+ "result": antwort,
131
+ "system_debug": debug_log # <-- Schau hier rein!
132
+ }