fix(transcription): [2f388f42] finalize and fix AI insights feature
This commit resolves all outstanding issues with the AI Insights feature.
- Corrects the transcript formatting logic in to properly handle the database JSON structure, ensuring the AI receives the correct context.
- Fixes the Gemini API client by using the correct model name ('gemini-2.0-flash') and the proper client initialization.
- Updates to securely pass the API key as an environment variable to the container.
- Cleans up the codebase by removing temporary debugging endpoints.
- Adds script for programmatic updates.
- Updates documentation with troubleshooting insights from the implementation process.
This commit is contained in:
133
transcription-tool/backend/lib/gemini_client.py
Normal file
133
transcription-tool/backend/lib/gemini_client.py
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
import os
|
||||
import logging
|
||||
import random
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
# --- KI UMSCHALTUNG: Google Generative AI (Dual Support) ---
|
||||
# This is a simplified, self-contained version for the transcription tool.
|
||||
|
||||
HAS_NEW_GENAI = False
|
||||
HAS_OLD_GENAI = False
|
||||
|
||||
# 1. New library (google-genai)
|
||||
try:
|
||||
from google import genai
|
||||
from google.genai import types
|
||||
HAS_NEW_GENAI = True
|
||||
logging.info("Library 'google.genai' (v1.0+) loaded.")
|
||||
except ImportError:
|
||||
logging.warning("Library 'google.genai' not found. Trying fallback.")
|
||||
|
||||
# 2. Old library (google-generativeai)
|
||||
try:
|
||||
import google.generativeai as old_genai
|
||||
HAS_OLD_GENAI = True
|
||||
logging.info("Library 'google.generativeai' (Legacy) loaded.")
|
||||
except ImportError:
|
||||
logging.warning("Library 'google.generativeai' not found.")
|
||||
|
||||
HAS_GEMINI = HAS_NEW_GENAI or HAS_OLD_GENAI
|
||||
|
||||
# A simple retry decorator, as the global one is not available
|
||||
def retry_on_failure(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
max_retries = 3
|
||||
base_delay = 5
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
if attempt > 0:
|
||||
logging.warning(f"Retrying attempt {attempt + 1}/{max_retries} for '{func.__name__}'...")
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
if attempt < max_retries - 1:
|
||||
wait_time = base_delay * (2 ** attempt) + random.uniform(0, 1)
|
||||
time.sleep(wait_time)
|
||||
else:
|
||||
raise e
|
||||
return wrapper
|
||||
|
||||
def _get_gemini_api_key():
|
||||
"""Gets the Gemini API key from environment variables."""
|
||||
api_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("OPENAI_API_KEY")
|
||||
if not api_key:
|
||||
raise ValueError("GEMINI_API_KEY or OPENAI_API_KEY environment variable not set.")
|
||||
return api_key
|
||||
|
||||
@retry_on_failure
|
||||
def call_gemini_flash(prompt: str, system_instruction: str = None, temperature: float = 0.3, json_mode: bool = False):
|
||||
"""
|
||||
Calls the Gemini Flash model to generate text content.
|
||||
This is a focused, local version of the function.
|
||||
"""
|
||||
logger = logging.getLogger(__name__)
|
||||
api_key = _get_gemini_api_key()
|
||||
|
||||
if not HAS_GEMINI:
|
||||
raise ImportError("No Google Generative AI library is available (google-genai or google-generativeai).")
|
||||
|
||||
# The legacy library was noted as preferred in the original helpers.py
|
||||
if HAS_OLD_GENAI:
|
||||
try:
|
||||
old_genai.configure(api_key=api_key)
|
||||
generation_config = {
|
||||
"temperature": temperature,
|
||||
"top_p": 0.95,
|
||||
"top_k": 40,
|
||||
"max_output_tokens": 8192,
|
||||
}
|
||||
if json_mode:
|
||||
generation_config["response_mime_type"] = "application/json"
|
||||
|
||||
model = old_genai.GenerativeModel(
|
||||
model_name="gemini-1.5-flash", # Using 1.5 as it's the modern standard
|
||||
generation_config=generation_config,
|
||||
system_instruction=system_instruction
|
||||
)
|
||||
response = model.generate_content([prompt])
|
||||
return response.text.strip()
|
||||
except Exception as e:
|
||||
logger.error(f"Error with legacy GenAI Lib: {e}")
|
||||
if not HAS_NEW_GENAI: raise e
|
||||
# Fallthrough to new lib if legacy fails
|
||||
|
||||
# Fallback to the new library
|
||||
if HAS_NEW_GENAI:
|
||||
try:
|
||||
# CORRECT: Use the Client-based API for the new library
|
||||
client = genai.Client(api_key=api_key)
|
||||
|
||||
config = {
|
||||
"temperature": temperature,
|
||||
"top_p": 0.95,
|
||||
"top_k": 40,
|
||||
"max_output_tokens": 8192,
|
||||
}
|
||||
if json_mode:
|
||||
config["response_mime_type"] = "application/json"
|
||||
|
||||
# Construct the contents list, including the system instruction if provided
|
||||
contents = []
|
||||
if system_instruction:
|
||||
# Note: The new API doesn't have a direct 'system_instruction' parameter
|
||||
# in generate_content. It's typically passed as the first message.
|
||||
# This is an adaptation. For a more robust solution, one would
|
||||
# structure prompts with roles.
|
||||
contents.append({'role': 'system', 'parts': [{'text': system_instruction}]})
|
||||
contents.append({'role': 'user', 'parts': [{'text': prompt}]})
|
||||
|
||||
# Use the client to generate content
|
||||
response = client.models.generate_content(
|
||||
model="models/gemini-2.0-flash-001", # CORRECTED: Using the project's standard model
|
||||
contents=contents,
|
||||
config=config
|
||||
)
|
||||
return response.text.strip()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error with new GenAI Lib: {e}")
|
||||
raise e
|
||||
|
||||
raise RuntimeError("Both Gemini libraries failed or are unavailable.")
|
||||
Reference in New Issue
Block a user