Spaces:
Running
Running
| import logging | |
| import json | |
| import re | |
| import os | |
| from pathlib import Path | |
| from typing import Dict, Any, List | |
| import google.generativeai as genai | |
| logger = logging.getLogger(__name__) | |
| def load_env_fallback(): | |
| """ | |
| Ręcznie wczytuje plik .env do os.environ z pełną diagnostyką w konsoli. | |
| """ | |
| if os.getenv("GEMINI_API_KEY"): | |
| return | |
| possible_paths = [ | |
| Path(".env"), # Bieżący folder roboczy # Folder backend | |
| Path(__file__).resolve().parent.parent.parent / ".env" # Ścieżka relatywna do serwisu | |
| ] | |
| print(f"\n🔍 [DIAGNOSTYKA .ENV] Bieżący katalog roboczy (CWD): {os.getcwd()}") | |
| found_any = False | |
| for path_obj in possible_paths: | |
| resolved_path = path_obj.resolve() | |
| exists = resolved_path.exists() | |
| print(f"👉 Sprawdzam ścieżkę: {resolved_path} -> [Znaleziono: {'TAK' if exists else 'NIE'}]") | |
| if exists: | |
| found_any = True | |
| print(f"📖 Próba wczytania pliku: {resolved_path}") | |
| try: | |
| loaded_keys = [] | |
| with open(resolved_path, "r", encoding="utf-8") as f: | |
| for line in f: | |
| line = line.strip() | |
| if line and not line.startswith("#") and "=" in line: | |
| key, val = line.split("=", 1) | |
| k_clean = key.strip() | |
| v_clean = val.strip().strip("'\"") | |
| os.environ[k_clean] = v_clean | |
| loaded_keys.append(k_clean) | |
| print(f"✅ Pomyślnie wczytano klucze z pliku: {loaded_keys}") | |
| break | |
| except Exception as e: | |
| print(f"❌ Błąd odczytu pliku .env: {e}") | |
| if not found_any: | |
| print("❌ Nie znaleziono pliku .env w żadnej z badanych lokalizacji!") | |
| final_key = os.getenv("GEMINI_API_KEY") | |
| print(f"🔑 Status GEMINI_API_KEY: {'ZNAJDZIONO (zaczyna się od: ' + final_key[:6] + '...)' if final_key else 'NIE ZNAJDZIONO!'}\n") | |
| # Uruchamiamy wczytywanie środowiska przy imporcie tego serwisu | |
| load_env_fallback() | |
| async def analyze_with_gemini_grounding(statement: str) -> Dict[str, Any]: | |
| """ | |
| Analizuje stwierdzenie, automatycznie przeszukując internet za pomocą | |
| wbudowanego w Gemini narzędzia Google Search Grounding. | |
| """ | |
| # Upewniamy się, że środowisko jest załadowane | |
| load_env_fallback() | |
| api_key = os.getenv("GEMINI_API_KEY") | |
| if not api_key: | |
| logger.error("Brak klucza GEMINI_API_KEY w środowisku systemowym!") | |
| return { | |
| "verdict": "SPORNE", | |
| "explanation": "Błąd backendu: Brak skonfigurowanego klucza GEMINI_API_KEY w pliku .env.", | |
| "confidence": 0.0, | |
| "sources": [] | |
| } | |
| genai.configure(api_key=api_key) | |
| prompt = f"""Jesteś zaawansowanym asystentem do weryfikacji faktów (fact-checking). | |
| Przeanalizuj poniższe stwierdzenie, korzystając z wyszukiwarki Google (masz do niej dostęp jako narzędzie), aby zweryfikować jego prawdziwość w czasie rzeczywistym. | |
| STWIERDZENIE DO WERYFIKACJI: | |
| "{statement}" | |
| Twoja odpowiedź musi być wyłącznie poprawnym obiektem JSON (bez bloków kodu typu ```json, bez dodatkowego tekstu na początku ani na końcu). | |
| Format JSON: | |
| {{ | |
| "verdict": "PRAWDA" lub "FAŁSZ" lub "SPORNE", | |
| "explanation": "Zwięzłe (2-4 zdania), merytoryczne i obiektywne uzasadnienie werdyktu w języku polskim, wyjaśniające co mówią fakty." | |
| }} | |
| Wskazówki do werdyktu: | |
| - "PRAWDA": Najnowsze fakty i wiarygodne źródła w pełni potwierdzają to stwierdzenie. | |
| - "FAŁSZ": Fakty jednoznacznie zaprzeczają temu stwierdzeniu. | |
| - "SPORNE": Informacje w sieci są sprzeczne, jest to kwestia opinii lub brak jednoznacznych dowodów. | |
| """ | |
| try: | |
| model = genai.GenerativeModel( | |
| model_name="gemini-2.5-flash", | |
| tools=[ | |
| genai.protos.Tool( | |
| google_search=genai.protos.Tool.GoogleSearch() | |
| ) | |
| ] | |
| ) | |
| response = model.generate_content( | |
| prompt, | |
| generation_config=genai.types.GenerationConfig( | |
| temperature=0.0 | |
| ) | |
| ) | |
| raw_text = response.text.strip() | |
| logger.info(f"Surowa odpowiedź Gemini: {raw_text}") | |
| if raw_text.startswith("```"): | |
| match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", raw_text, re.DOTALL) | |
| if match: | |
| raw_text = match.group(1) | |
| result_json = json.loads(raw_text) | |
| sources = [] | |
| candidate = response.candidates[0] | |
| metadata = getattr(candidate, "grounding_metadata", None) | |
| if metadata and getattr(metadata, "grounding_chunks", None): | |
| for chunk in metadata.grounding_chunks: | |
| if chunk.web: | |
| sources.append({ | |
| "title": chunk.web.title, | |
| "url": chunk.web.uri, | |
| "snippet": "Źródło zweryfikowane bezpośrednio przez wyszukiwarkę Google." | |
| }) | |
| return { | |
| "verdict": result_json.get("verdict", "SPORNE"), | |
| "explanation": result_json.get("explanation", "Brak uzasadnienia."), | |
| "confidence": 0.95 if result_json.get("verdict") in ["PRAWDA", "FAŁSZ"] else 0.5, | |
| "sources": sources | |
| } | |
| except Exception as e: | |
| logger.error(f"Błąd analizy Gemini Grounding API: {e}", exc_info=True) | |
| return { | |
| "verdict": "SPORNE", | |
| "explanation": f"Wystąpił błąd komunikacji z modelem językowym: {str(e)}", | |
| "confidence": 0.0, | |
| "sources": [] | |
| } |