HumanPlusX / src /core /ai_client.py
FajarHidaa's picture
Update src/core/ai_client.py
9129632 verified
Raw History Blame Contribute Delete
2.18 kB
"""
Human+ AI Client
Singleton Gemini client dengan typed config & error handling terpusat.
"""
import os
import streamlit as st
from google import genai
from google.genai import types
# ── Model config ─────────────────────────────────────────────────────
MODEL_NAME = "gemini-2.5-flash-lite"
TEMP_EXTRACTION = 0.1 # PDF extraction β€” deterministik
TEMP_PROTOCOL = 0.4 # Protocol generation β€” sedikit kreatif
# PENTING: 4096 terlalu kecil untuk protocol lengkap (bisa 6000-10000 token).
# Naikkan ke 16000 agar semua section tidak terpotong.
MAX_TOKENS_EXTRACT = 10000
MAX_TOKENS_PROTOCOL = 65536
class GeminiClientError(Exception):
pass
@st.cache_resource(show_spinner=False)
def get_client() -> genai.Client:
api_key = os.getenv("GEMINI_API_KEY")
if not api_key:
raise GeminiClientError(
"GEMINI_API_KEY tidak ditemukan. "
"Tambahkan di HuggingFace Settings β†’ Repository Secrets."
)
try:
return genai.Client(api_key=api_key)
except Exception as e:
raise GeminiClientError(f"Gagal menginisialisasi Gemini client: {e}") from e
def call_gemini(
contents: list,
temperature: float = TEMP_EXTRACTION,
max_tokens: int = MAX_TOKENS_EXTRACT,
) -> str:
try:
client = get_client()
response = client.models.generate_content(
model=MODEL_NAME,
contents=contents,
config=types.GenerateContentConfig(
temperature=temperature,
max_output_tokens=max_tokens,
),
)
return response.text
except GeminiClientError:
raise
except Exception as e:
raise GeminiClientError(f"Gemini API call gagal: {e}") from e
def pdf_bytes_to_part(pdf_bytes: bytes) -> types.Part:
return types.Part.from_bytes(data=pdf_bytes, mime_type="application/pdf")
def check_client_health() -> tuple[bool, str]:
try:
get_client()
return True, "βœ… Gemini client siap"
except GeminiClientError as e:
return False, str(e)