summaryrefslogtreecommitdiff
path: root/backend/app/services/llm.py
diff options
context:
space:
mode:
Diffstat (limited to 'backend/app/services/llm.py')
-rw-r--r--backend/app/services/llm.py22
1 files changed, 11 insertions, 11 deletions
diff --git a/backend/app/services/llm.py b/backend/app/services/llm.py
index 96b0514..87b9155 100644
--- a/backend/app/services/llm.py
+++ b/backend/app/services/llm.py
@@ -4,18 +4,18 @@ import openai
import google.generativeai as genai
from app.schemas import LLMConfig, Message, Role, Context
-# Simple in-memory cache for clients to avoid re-initializing constantly
+# Cache OpenAI clients by API key to avoid re-initializing constantly
# In a real app, use dependency injection or singletons
-_openai_client = None
+_openai_clients: dict[str, openai.AsyncOpenAI] = {}
def get_openai_client(api_key: str = None):
- global _openai_client
+ global _openai_clients
key = api_key or os.getenv("OPENAI_API_KEY")
if not key:
raise ValueError("OpenAI API Key not found")
- if not _openai_client:
- _openai_client = openai.AsyncOpenAI(api_key=key)
- return _openai_client
+ if key not in _openai_clients:
+ _openai_clients[key] = openai.AsyncOpenAI(api_key=key)
+ return _openai_clients[key]
def configure_google(api_key: str = None):
key = api_key or os.getenv("GOOGLE_API_KEY")
@@ -345,12 +345,12 @@ async def llm_streamer(
yield f"Error calling LLM: {str(e)}"
-async def generate_title(user_prompt: str, response: str) -> str:
+async def generate_title(user_prompt: str, response: str, api_key: str = None) -> str:
"""
Generate a short title (3-4 words) for a Q-A pair using gpt-5-nano.
Uses Responses API (required for gpt-5 series), synchronous mode (no background).
"""
- client = get_openai_client()
+ client = get_openai_client(api_key)
instructions = """TASK: Extract a short topic title from the given Q&A. Do NOT answer the question - only extract the topic.
@@ -413,7 +413,7 @@ Q: "What's the weather in NYC?" -> "NYC Weather\""""
return "New Question"
-async def summarize_content(content: str, model: str) -> str:
+async def summarize_content(content: str, model: str, openai_api_key: str = None, gemini_api_key: str = None) -> str:
"""
Summarize the given content using the specified model.
Supports both OpenAI and Gemini models.
@@ -434,7 +434,7 @@ Output only the summary, no preamble."""
from google.genai import types
import os
- key = os.getenv("GOOGLE_API_KEY")
+ key = gemini_api_key or os.getenv("GOOGLE_API_KEY")
if not key:
return "Error: Google API Key not found"
@@ -456,7 +456,7 @@ Output only the summary, no preamble."""
else:
# Use OpenAI
- client = get_openai_client()
+ client = get_openai_client(openai_api_key)
# Check if model needs Responses API
responses_api_models = [