simikkk commited on
Commit
2e64dd6
·
verified ·
1 Parent(s): 98417d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -61
app.py CHANGED
@@ -16,8 +16,9 @@ def patched_init(self, *args, **kwargs):
16
  tf.keras.layers.DepthwiseConv2D.__init__ = patched_init
17
  # ──────────────────────────────────────────────────────────────
18
 
19
- # Načtení API klíče pro OpenRouter z prostředí Hugging Face
20
- api_key = os.environ.get("OPENROUTER_API_KEY")
 
21
 
22
  # ── Funkce pro načtení všech CSV dat ──
23
  def nacti_vsechna_data():
@@ -71,7 +72,7 @@ def vyhodnot_strechu(obrazek):
71
 
72
  if skore < 70:
73
  vysledek += "⚠️ Závěr: Výsledek je nejednoznačný (spolehlivost je nižší než 70 %).\n"
74
- vysledek += "💡 Doporučení: Umělá inteligence si v tomto případě není dostatečně juris. Pro přesné posouzení doporučujeme fyzickou obhlídku střechy technikem."
75
  elif "nevhod" in label_lower or "2" in label_lower:
76
  vysledek += "❌ Závěr: Střecha NENÍ vhodná pro FVE"
77
  elif "vhod" in label_lower or "0" in label_lower:
@@ -82,79 +83,98 @@ def vyhodnot_strechu(obrazek):
82
  return vysledek
83
 
84
 
85
- # ── HLAVNÍ JÁDRO PRO AI KOMUNIKACI (OPRAVENO) ──
86
  def proved_api_volani(otazka, historie):
87
- if not api_key:
88
- historie.append([otazka, "Chyba: API klíč není nastaven ve Variables na Hugging Face."])
89
- yield historie, "### 🤖 Aktivní model: Žádný (Chyba klíče)"
90
- return
91
-
92
  data_text = nacti_vsechna_data()
93
 
94
  prompt = (
95
- "Jsi expert na energetiku a fotovoltaiku pro Ústecký kraj z firmy DAMR58H. "
96
- "Odpovídej vždy věcně, logicky a VÝHRADNĚ PERFEKTNÍ GRAMATICKOU ČEŠTINOU.\n"
97
- "STRIKTNÍ ZÁKAZ HALUCINACÍ A ZKOMOLENIN: Nikdy nepoužívej vymyšlená slova nebo anglicismy. "
98
- "Pokud nedokážeš vygenerovat stoprocentně gramaticky správný český text, odpověz pouze touto větou: 'Omlouvám se, vybraný záložní server momentálně nedokáže správně přečíst strukturovaná data v češtině.'\n\n"
99
- "Důležité firemní pravidlo: Pokud náš AI model vyhodnotí střechu s jistotou (skóre) nižší než 70 %, "
100
- "považujeme výsledek za nejednoznačný a doporučujeme uživateli fyzickou obhlídku střechy technikem.\n\n"
101
- f"Tady jsou data z mých souborů:\n{data_text}\n\n"
102
  f"Otázka: {otazka}"
103
  )
104
 
105
- # Aktualizovaný list ověřených funkčních free modelů z tvých screenshotů
106
- modely_k_vyzkouseni = [
107
- "meta-llama/llama-3.3-70b-instruct:free", # Špičková Llama 3.3
108
- "meta-llama/llama-3.2-3b-instruct:free", # Rychlá, stabilní menší Llama
109
- "openrouter/free" # Automatický router jako finální záchrana
110
- ]
111
-
112
- url = "https://openrouter.ai/api/v1/chat/completions" # Čistá, opravená adresa
113
- headers = {
114
- "Authorization": f"Bearer {api_key}",
115
- "Content-Type": "application/json",
116
- "HTTP-Referer": "https://huggingface.co",
117
- "X-Title": "Solar Advisor"
118
- }
119
-
120
- historie.append([otazka, "⏳ Vyhledávám volný server a generuji odpověď..."])
121
-
122
- uspech = False
123
- seznam_chyb = []
124
 
125
- for model in modely_k_vyzkouseni:
126
- model_short = model.split('/')[-1]
127
- yield historie, f"### 🤖 Aktivní model: Zkouším `{model_short}`..."
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
- payload = {
130
- "model": model,
131
- "messages": [{"role": "user", "content": prompt}],
132
- "temperature": 0.15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
134
 
135
  try:
136
- response = requests.post(url, headers=headers, json=payload, timeout=20)
137
-
138
- if response.status_code == 200:
139
- data = response.json()
140
- odpoved_text = data["choices"][0]["message"]["content"]
141
 
142
- historie[-1][1] = odpoved_text
143
- yield historie, f"### 🤖 Aktivní model: `{model_short}`"
144
- uspech = True
145
- break
146
  else:
147
- seznam_chyb.append(f"{model_short} (Status {response.status_code})")
148
- continue
149
-
150
  except Exception as e:
151
- seznam_chyb.append(f"{model_short} (Timeout/Síť)")
152
- continue
153
-
154
- if not uspech:
155
- podrobny_vypis = ", ".join(seznam_chyb)
156
- historie[-1][1] = f"⚠️ Všechny vybrané servery i nouzový router selhaly nebo jsou přetížené. Detaily: [{podrobny_vypis}]. Zkuste kliknout na tlačítko 'Znovu poslat (Resend)' za chvilku."
157
- yield historie, "### 🤖 Aktivní model: Žádný (Vše selhalo)"
158
 
159
 
160
  # ── LOGIKA OVLÁDACÍCH TLAČÍTEK ──
 
16
  tf.keras.layers.DepthwiseConv2D.__init__ = patched_init
17
  # ──────────────────────────────────────────────────────────────
18
 
19
+ # Načtení API klíčů z prostředí Hugging Face
20
+ api_key_openrouter = os.environ.get("OPENROUTER_API_KEY")
21
+ api_key_gemini = os.environ.get("GEMINI_API_KEY") # Nový sekundární štít
22
 
23
  # ── Funkce pro načtení všech CSV dat ──
24
  def nacti_vsechna_data():
 
72
 
73
  if skore < 70:
74
  vysledek += "⚠️ Závěr: Výsledek je nejednoznačný (spolehlivost je nižší než 70 %).\n"
75
+ vysledek += "💡 Doporučení: Umělá inteligence si v tomto případě není dostatečně jistá. Pro přesné posouzení doporučujeme fyzickou obhlídku střechy technikem."
76
  elif "nevhod" in label_lower or "2" in label_lower:
77
  vysledek += "❌ Závěr: Střecha NENÍ vhodná pro FVE"
78
  elif "vhod" in label_lower or "0" in label_lower:
 
83
  return vysledek
84
 
85
 
86
+ # ── HLAVNÍ JÁDRO PRO AI KOMUNIKACI S MULTI-TIER FALLBACKEM ──
87
  def proved_api_volani(otazka, historie):
 
 
 
 
 
88
  data_text = nacti_vsechna_data()
89
 
90
  prompt = (
91
+ "Jsi špičkový datový analytik a expert na fotovoltaiku pro firmu DAMR58H v Ústeckém kraji. "
92
+ "Odpovídej vždy věcně, logicky a VÝHRADNĚ PERFEKTNÍ GRAMATICKOU ČEŠTINOU.\n\n"
93
+ "Pravidla pro analýzu:\n"
94
+ "1. Pokud se uživatel ptá na data ze souborů CSV, NEKOPÍRUJ suše strukturu sloupců. "
95
+ "Místo toho se podívej na hodnoty, hledej trendy, porovnávej obce a dělej reálné energetické závěry.\n"
96
+ "2. Pravidlo o 70% jistotě a fyzické obhlídce technikem aplikuj POUZE tehdy, když vyhodnocuješ konkrétní skóre z analýzy FOTOGRAFIE střechy. Nemíchej to do tabulek.\n\n"
97
+ f"Tady jsou data z našich souborů k analýze:\n{data_text}\n\n"
98
  f"Otázka: {otazka}"
99
  )
100
 
101
+ historie.append([otazka, "⏳ Spouštím vyhledávání volného serveru..."])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ # KROK 1: Pokus o prémiové free modely na OpenRouteru
104
+ if api_key_openrouter:
105
+ url_or = "https://openrouter.ai/api/v1/chat/completions"
106
+ headers_or = {
107
+ "Authorization": f"Bearer {api_key_openrouter}",
108
+ "Content-Type": "application/json",
109
+ "HTTP-Referer": "https://huggingface.co",
110
+ "X-Title": "Solar Advisor"
111
+ }
112
+
113
+ modely_or = [
114
+ "meta-llama/llama-3.3-70b-instruct:free",
115
+ "meta-llama/llama-3.2-3b-instruct:free",
116
+ "openrouter/free" # Náhodný free jako poslední pokus v rámci OpenRouteru
117
+ ]
118
 
119
+ for model in modely_or:
120
+ model_short = model.split('/')[-1]
121
+ yield historie, f"### 🤖 OpenRouter: Zkouším `{model_short}`..."
122
+
123
+ payload = {
124
+ "model": model,
125
+ "messages": [{"role": "user", "content": prompt}],
126
+ "temperature": 0.5 # Zvednuto na optimální analytický střed
127
+ }
128
+
129
+ try:
130
+ res = requests.post(url_or, headers=headers_or, json=payload, timeout=18)
131
+ if res.status_code == 200:
132
+ data = res.json()
133
+ reálny_model = data.get("model", model)
134
+ odpoved = data["choices"][0]["message"]["content"]
135
+
136
+ # FILTR NA ŠPATNÉ MODELY: Pokud nám openrouter/free podstrčil slabý model, zahodíme ho
137
+ if model == "openrouter/free":
138
+ nevhodne_prazdne_modely = ["llama-3-8b", "pygmalion", "gemma-7b"]
139
+ if any(x in reálny_model.lower() for x in nevhodne_prazdne_modely):
140
+ yield historie, "### ⚠️ OpenRouter podstrčil slabý model. Přepínám na Google infrastrukturu..."
141
+ break # Vyskočí z OpenRouter smyčky a jde na KROK 2
142
+
143
+ historie[-1][1] = odpoved
144
+ yield historie, f"### 🤖 Aktivní model: `{reálny_model.split('/')[-1]}` (OpenRouter)"
145
+ return
146
+ except Exception:
147
+ continue
148
+
149
+ # KROK 2: Totální záchrana přes Google Gemini API (pokud OpenRouter selhal nebo dodal nepoužitelný model)
150
+ if api_key_gemini:
151
+ yield historie, "### 🚀 Nouzový režim: Připojuji se na Google Gemini API..."
152
+ url_gemini = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={api_key_gemini}"
153
+
154
+ payload_gemini = {
155
+ "contents": [{"parts": [{"text": prompt}]}],
156
+ "generationConfig": {"temperature": 0.4}
157
  }
158
 
159
  try:
160
+ res = requests.post(url_gemini, json=payload_gemini, timeout=20)
161
+ if res.status_code == 200:
162
+ data = res.json()
163
+ odpoved = data['candidates'][0]['content']['parts'][0]['text']
 
164
 
165
+ historie[-1][1] = odpoved
166
+ yield historie, "### ⚡ Aktivní model: `Gemini 1.5 Flash` (Google Cloud)"
167
+ return
 
168
  else:
169
+ status_g = res.status_code
 
 
170
  except Exception as e:
171
+ status_g = "Timeout/Network"
172
+ else:
173
+ status_g = "Klíč GEMINI_API_KEY chybí"
174
+
175
+ # Pokud selhalo úplně všechno
176
+ historie[-1][1] = f"❌ Selhal OpenRouter i záložní Google API. (Detaily: Gemini status: {status_g}). Zkus to poslat znovu za minutku."
177
+ yield historie, "### 🤖 Aktivní model: Žádný (Všechny sítě přetíženy)"
178
 
179
 
180
  # ── LOGIKA OVLÁDACÍCH TLAČÍTEK ──