mgbam commited on
Commit
95e771a
·
verified ·
1 Parent(s): 64a134a

Update core/llm_services.py

Browse files
Files changed (1) hide show
  1. core/llm_services.py +46 -108
core/llm_services.py CHANGED
@@ -2,160 +2,98 @@
2
  import os
3
  import google.generativeai as genai
4
  from huggingface_hub import InferenceClient
5
- # from dotenv import load_dotenv # Optional: for local .env file
6
- # load_dotenv() # Load environment variables from .env file if present
7
 
8
- GOOGLE_API_KEY = os.getenv("STORYVERSE_GOOGLE_API_KEY") # Use specific env var names
9
- HF_TOKEN = os.getenv("STORYVERSE_HF_TOKEN")
10
 
11
  GEMINI_TEXT_CONFIGURED = False
12
- HF_TEXT_CONFIGURED = False
13
  hf_inference_text_client = None
14
 
15
  class LLMTextResponse:
16
  def __init__(self, text=None, error=None, success=True, model_id_used="unknown_text_llm"):
17
  self.text, self.error, self.success, self.model_id_used = text, error, success, model_id_used
 
18
 
19
- def initialize_text_llms():
20
- global GOOGLE_API_KEY, HF_TOKEN, GEMINI_TEXT_CONFIGURED, HF_TEXT_CONFIGURED, hf_inference_text_client
21
- print("INFO: llm_services.py - Initializing Text LLM clients...")
22
- if GOOGLE_API_KEY and GOOGLE_API_KEY.strip():
23
- try:
24
- genai.configure(api_key=GOOGLE_API_KEY)
25
- GEMINI_TEXT_CONFIGURED = True
26
- print("SUCCESS: llm_services.py - Google Gemini API (for text) configured.")
27
- except Exception as e:
28
- print(f"ERROR: llm_services.py - Failed to configure Google Gemini API: {e}")
29
- GEMINI_TEXT_CONFIGURED = False
30
- else:
31
- print("WARNING: llm_services.py - STORYVERSE_GOOGLE_API_KEY not found or empty.")
32
- GEMINI_TEXT_CONFIGURED = False
33
-
34
- if HF_TOKEN and HF_TOKEN.strip():
35
- try:
36
- hf_inference_text_client = InferenceClient(token=HF_TOKEN)
37
- HF_TEXT_CONFIGURED = True
38
- print("SUCCESS: llm_services.py - Hugging Face InferenceClient (for text) initialized.")
39
- except Exception as e:
40
- print(f"ERROR: llm_services.py - Failed to initialize HF InferenceClient: {e}")
41
- HF_TEXT_CONFIGURED = False
42
- else:
43
- print("WARNING: llm_services.py - STORYVERSE_HF_TOKEN not found or empty.")
44
- HF_TEXT_CONFIGURED = False
45
- print(f"INFO: llm_services.py - Text LLM Init complete. Gemini Text: {GEMINI_TEXT_CONFIGURED}, HF Text: {HF_TEXT_CONFIGURED}")
46
-
47
- def is_gemini_text_ready(): return GEMINI_TEXT_CONFIGURED
48
- def is_hf_text_ready(): return HF_TEXT_CONFIGURED
49
-
50
- def generate_text_gemini(prompt: str, model_id: str = "gemini-1.5-flash-latest", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
51
- if not is_gemini_text_ready():
52
- return LLMTextResponse(error="Gemini text API not configured.", success=False, model_id_used=model_id)
53
- try:
54
- model = genai.GenerativeModel(model_name=model_id, system_instruction=system_prompt)
55
- config = genai.types.GenerationConfig(temperature=temperature, max_output_tokens=max_tokens)
56
- response = model.generate_content(prompt, generation_config=config)
57
- # Add robust response checking as in AlgoForge's llm_clients.py
58
- if response.prompt_feedback and response.prompt_feedback.block_reason:
59
- return LLMTextResponse(error=f"Gemini: Prompt blocked ({response.prompt_feedback.block_reason})", success=False, model_id_used=model_id)
60
- if not response.candidates or not response.candidates[0].content.parts:
61
- return LLMTextResponse(error=f"Gemini: No content generated (Finish reason: {response.candidates[0].finish_reason if response.candidates else 'Unknown'})", success=False, model_id_used=model_id)
62
- return LLMTextResponse(text=response.text, model_id_used=model_id)
63
- except Exception as e:
64
- return LLMTextResponse(error=f"Gemini API Error ({model_id}): {type(e).__name__} - {str(e)}", success=False, model_id_used=model_id)
65
-
66
- def generate_text_hf(prompt: str, model_id: str = "mistralai/Mistral-7B-Instruct-v0.2", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
67
- if not is_hf_text_ready() or not hf_inference_text_client:
68
- return LLMTextResponse(error="HF text API not configured.", success=False, model_id_used=model_id)
69
-
70
- full_prompt = f"<s>[INST] <<SYS>>\n{system_prompt}\n<</SYS>>\n\n{prompt} [/INST]" if system_prompt else prompt
71
- try:
72
- use_sample = temperature > 0.001
73
- response_text = hf_inference_text_client.text_generation(
74
- full_prompt, model=model_id, max_new_tokens=max_tokens,
75
- temperature=temperature if use_sample else None, do_sample=use_sample
76
- )
77
- return LLMTextResponse(text=response_text, model_id_used=model_id)
78
- except Exception as e:
79
- return LLMTextResponse(error=f"HF API Error ({model_id}): {type(e).__name__} - {str(e)}", success=False, model_id_used=model_id)
80
-
81
- print("DEBUG: core.llm_services (for StoryVerseWeaver) - Module defined.")# storyverse_weaver/core/llm_services.py
82
- import os
83
- import google.generativeai as genai
84
- from huggingface_hub import InferenceClient
85
- # from dotenv import load_dotenv # Optional: for local .env file
86
- # load_dotenv() # Load environment variables from .env file if present
87
-
88
- GOOGLE_API_KEY = os.getenv("STORYVERSE_GOOGLE_API_KEY") # Use specific env var names
89
- HF_TOKEN = os.getenv("STORYVERSE_HF_TOKEN")
90
-
91
- GEMINI_TEXT_CONFIGURED = False
92
- HF_TEXT_CONFIGURED = False
93
- hf_inference_text_client = None
94
-
95
- class LLMTextResponse:
96
- def __init__(self, text=None, error=None, success=True, model_id_used="unknown_text_llm"):
97
- self.text, self.error, self.success, self.model_id_used = text, error, success, model_id_used
98
 
99
  def initialize_text_llms():
100
  global GOOGLE_API_KEY, HF_TOKEN, GEMINI_TEXT_CONFIGURED, HF_TEXT_CONFIGURED, hf_inference_text_client
101
- print("INFO: llm_services.py - Initializing Text LLM clients...")
 
 
102
  if GOOGLE_API_KEY and GOOGLE_API_KEY.strip():
 
103
  try:
104
  genai.configure(api_key=GOOGLE_API_KEY)
 
 
 
 
105
  GEMINI_TEXT_CONFIGURED = True
106
- print("SUCCESS: llm_services.py - Google Gemini API (for text) configured.")
107
  except Exception as e:
108
- print(f"ERROR: llm_services.py - Failed to configure Google Gemini API: {e}")
109
  GEMINI_TEXT_CONFIGURED = False
 
 
110
  else:
111
- print("WARNING: llm_services.py - STORYVERSE_GOOGLE_API_KEY not found or empty.")
112
  GEMINI_TEXT_CONFIGURED = False
 
113
 
 
114
  if HF_TOKEN and HF_TOKEN.strip():
 
115
  try:
116
  hf_inference_text_client = InferenceClient(token=HF_TOKEN)
117
  HF_TEXT_CONFIGURED = True
118
- print("SUCCESS: llm_services.py - Hugging Face InferenceClient (for text) initialized.")
119
  except Exception as e:
120
- print(f"ERROR: llm_services.py - Failed to initialize HF InferenceClient: {e}")
121
  HF_TEXT_CONFIGURED = False
 
 
122
  else:
123
- print("WARNING: llm_services.py - STORYVERSE_HF_TOKEN not found or empty.")
124
  HF_TEXT_CONFIGURED = False
125
- print(f"INFO: llm_services.py - Text LLM Init complete. Gemini Text: {GEMINI_TEXT_CONFIGURED}, HF Text: {HF_TEXT_CONFIGURED}")
 
 
126
 
127
  def is_gemini_text_ready(): return GEMINI_TEXT_CONFIGURED
128
- def is_hf_text_ready(): return HF_TEXT_CONFIGURED
129
 
130
  def generate_text_gemini(prompt: str, model_id: str = "gemini-1.5-flash-latest", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
131
  if not is_gemini_text_ready():
132
  return LLMTextResponse(error="Gemini text API not configured.", success=False, model_id_used=model_id)
 
133
  try:
134
  model = genai.GenerativeModel(model_name=model_id, system_instruction=system_prompt)
135
  config = genai.types.GenerationConfig(temperature=temperature, max_output_tokens=max_tokens)
136
- response = model.generate_content(prompt, generation_config=config)
137
- # Add robust response checking as in AlgoForge's llm_clients.py
138
  if response.prompt_feedback and response.prompt_feedback.block_reason:
139
- return LLMTextResponse(error=f"Gemini: Prompt blocked ({response.prompt_feedback.block_reason})", success=False, model_id_used=model_id)
140
  if not response.candidates or not response.candidates[0].content.parts:
141
  return LLMTextResponse(error=f"Gemini: No content generated (Finish reason: {response.candidates[0].finish_reason if response.candidates else 'Unknown'})", success=False, model_id_used=model_id)
142
- return LLMTextResponse(text=response.text, model_id_used=model_id)
 
 
 
143
  except Exception as e:
144
- return LLMTextResponse(error=f"Gemini API Error ({model_id}): {type(e).__name__} - {str(e)}", success=False, model_id_used=model_id)
 
 
 
 
 
145
 
146
  def generate_text_hf(prompt: str, model_id: str = "mistralai/Mistral-7B-Instruct-v0.2", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
147
- if not is_hf_text_ready() or not hf_inference_text_client:
148
- return LLMTextResponse(error="HF text API not configured.", success=False, model_id_used=model_id)
149
-
150
  full_prompt = f"<s>[INST] <<SYS>>\n{system_prompt}\n<</SYS>>\n\n{prompt} [/INST]" if system_prompt else prompt
151
  try:
152
  use_sample = temperature > 0.001
153
- response_text = hf_inference_text_client.text_generation(
154
- full_prompt, model=model_id, max_new_tokens=max_tokens,
155
- temperature=temperature if use_sample else None, do_sample=use_sample
156
- )
157
  return LLMTextResponse(text=response_text, model_id_used=model_id)
158
- except Exception as e:
159
- return LLMTextResponse(error=f"HF API Error ({model_id}): {type(e).__name__} - {str(e)}", success=False, model_id_used=model_id)
160
 
161
- print("DEBUG: core.llm_services (for StoryVerseWeaver) - Module defined.")
 
2
  import os
3
  import google.generativeai as genai
4
  from huggingface_hub import InferenceClient
5
+ # from dotenv import load_dotenv
6
+ # load_dotenv()
7
 
8
+ GOOGLE_API_KEY = os.getenv("STORYVERSE_GOOGLE_API_KEY")
9
+ HF_TOKEN = os.getenv("STORYVERSE_HF_TOKEN") # For fallback
10
 
11
  GEMINI_TEXT_CONFIGURED = False
12
+ HF_TEXT_CONFIGURED = False # For fallback text model
13
  hf_inference_text_client = None
14
 
15
  class LLMTextResponse:
16
  def __init__(self, text=None, error=None, success=True, model_id_used="unknown_text_llm"):
17
  self.text, self.error, self.success, self.model_id_used = text, error, success, model_id_used
18
+ def __str__(self): return str(self.text) if self.success and self.text is not None else f"ERROR (Text Model: {self.model_id_used}): {self.error}"
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  def initialize_text_llms():
22
  global GOOGLE_API_KEY, HF_TOKEN, GEMINI_TEXT_CONFIGURED, HF_TEXT_CONFIGURED, hf_inference_text_client
23
+ print("INFO: llm_services.py - Initializing Text LLM clients (Gemini primary)...")
24
+
25
+ # Google Gemini (Primary)
26
  if GOOGLE_API_KEY and GOOGLE_API_KEY.strip():
27
+ print("INFO: llm_services.py - STORYVERSE_GOOGLE_API_KEY found in environment.")
28
  try:
29
  genai.configure(api_key=GOOGLE_API_KEY)
30
+ # Simple test: list available models to confirm API key works and API is enabled
31
+ models = [m for m in genai.list_models() if 'generateContent' in m.supported_generation_methods and "gemini" in m.name]
32
+ if not models:
33
+ raise Exception("No usable Gemini models found with this API key, or Generative Language API not fully enabled/propagated.")
34
  GEMINI_TEXT_CONFIGURED = True
35
+ print(f"SUCCESS: llm_services.py - Google Gemini API (for text) configured. Found models like: {models[0].name}")
36
  except Exception as e:
 
37
  GEMINI_TEXT_CONFIGURED = False
38
+ print(f"ERROR: llm_services.py - Failed to configure/validate Google Gemini API.")
39
+ print(f" Gemini Init Error Details: {type(e).__name__}: {e}")
40
  else:
 
41
  GEMINI_TEXT_CONFIGURED = False
42
+ print("WARNING: llm_services.py - STORYVERSE_GOOGLE_API_KEY not found or empty.")
43
 
44
+ # Hugging Face (Fallback)
45
  if HF_TOKEN and HF_TOKEN.strip():
46
+ print("INFO: llm_services.py - STORYVERSE_HF_TOKEN found (for fallback text model).")
47
  try:
48
  hf_inference_text_client = InferenceClient(token=HF_TOKEN)
49
  HF_TEXT_CONFIGURED = True
50
+ print("SUCCESS: llm_services.py - Hugging Face InferenceClient (for fallback text) initialized.")
51
  except Exception as e:
 
52
  HF_TEXT_CONFIGURED = False
53
+ print(f"ERROR: llm_services.py - Failed to initialize HF InferenceClient for fallback text: {e}")
54
+ hf_inference_text_client = None # Ensure client is None on failure
55
  else:
 
56
  HF_TEXT_CONFIGURED = False
57
+ print("WARNING: llm_services.py - STORYVERSE_HF_TOKEN not found or empty (for fallback text model).")
58
+
59
+ print(f"INFO: llm_services.py - Text LLM Init complete. Gemini Text Ready: {GEMINI_TEXT_CONFIGURED}, HF Text (Fallback) Ready: {HF_TEXT_CONFIGURED}")
60
 
61
  def is_gemini_text_ready(): return GEMINI_TEXT_CONFIGURED
62
+ def is_hf_text_ready(): return HF_TEXT_CONFIGURED # Still useful to know if fallback is available
63
 
64
  def generate_text_gemini(prompt: str, model_id: str = "gemini-1.5-flash-latest", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
65
  if not is_gemini_text_ready():
66
  return LLMTextResponse(error="Gemini text API not configured.", success=False, model_id_used=model_id)
67
+ print(f"DEBUG: llm_services.py - Calling Gemini ({model_id}) for text. System prompt: {'Yes' if system_prompt else 'No'}")
68
  try:
69
  model = genai.GenerativeModel(model_name=model_id, system_instruction=system_prompt)
70
  config = genai.types.GenerationConfig(temperature=temperature, max_output_tokens=max_tokens)
71
+ response = model.generate_content(prompt, generation_config=config) # Pass prompt directly
72
+
73
  if response.prompt_feedback and response.prompt_feedback.block_reason:
74
+ return LLMTextResponse(error=f"Gemini: Prompt blocked ({response.prompt_feedback.block_reason_message or response.prompt_feedback.block_reason})", success=False, model_id_used=model_id)
75
  if not response.candidates or not response.candidates[0].content.parts:
76
  return LLMTextResponse(error=f"Gemini: No content generated (Finish reason: {response.candidates[0].finish_reason if response.candidates else 'Unknown'})", success=False, model_id_used=model_id)
77
+
78
+ generated_text = response.text # Simpler access for Gemini
79
+ print(f"DEBUG: llm_services.py - Gemini text generated successfully ({model_id}). Snippet: {generated_text[:50]}...")
80
+ return LLMTextResponse(text=generated_text, model_id_used=model_id)
81
  except Exception as e:
82
+ error_msg = f"Gemini API Error during text_generation ({model_id}): {type(e).__name__} - {str(e)}"
83
+ # Add specific checks for Google API errors
84
+ if "API key not valid" in str(e) or "PERMISSION_DENIED" in str(e):
85
+ error_msg += " Check your GOOGLE_API_KEY and ensure Generative Language API is enabled in Google Cloud."
86
+ print(f"ERROR: llm_services.py - {error_msg}")
87
+ return LLMTextResponse(error=error_msg, success=False, model_id_used=model_id)
88
 
89
  def generate_text_hf(prompt: str, model_id: str = "mistralai/Mistral-7B-Instruct-v0.2", system_prompt: str = None, temperature: float = 0.7, max_tokens: int = 512) -> LLMTextResponse:
90
+ # ... (This function remains the same as before, for fallback)
91
+ if not is_hf_text_ready() or not hf_inference_text_client: return LLMTextResponse(error="HF text API not configured.", success=False, model_id_used=model_id)
 
92
  full_prompt = f"<s>[INST] <<SYS>>\n{system_prompt}\n<</SYS>>\n\n{prompt} [/INST]" if system_prompt else prompt
93
  try:
94
  use_sample = temperature > 0.001
95
+ response_text = hf_inference_text_client.text_generation(full_prompt, model=model_id, max_new_tokens=max_tokens, temperature=temperature if use_sample else None, do_sample=use_sample)
 
 
 
96
  return LLMTextResponse(text=response_text, model_id_used=model_id)
97
+ except Exception as e: return LLMTextResponse(error=f"HF API Error ({model_id}): {type(e).__name__} - {str(e)}", success=False, model_id_used=model_id)
 
98
 
99
+ print("DEBUG: core.llm_services (Gemini Primary for StoryVerseWeaver) - Module defined.")