mgbam commited on
Commit
b22fc56
·
verified ·
1 Parent(s): 671f49e

Rename core/llm_clients.py to core/llm_services.py

Browse files
Files changed (2) hide show
  1. core/llm_clients.py +0 -126
  2. core/llm_services.py +161 -0
core/llm_clients.py DELETED
@@ -1,126 +0,0 @@
1
- # algoforge_prime/core/llm_clients.py
2
- import os
3
- import google.generativeai as genai
4
- from huggingface_hub import InferenceClient
5
- import time
6
-
7
- # --- Configuration ---
8
- GOOGLE_API_KEY = None
9
- HF_TOKEN = None
10
- GEMINI_API_CONFIGURED = False
11
- HF_API_CONFIGURED = False
12
- hf_inference_client = None
13
-
14
- def initialize_all_clients():
15
- global GOOGLE_API_KEY, HF_TOKEN, GEMINI_API_CONFIGURED, HF_API_CONFIGURED, hf_inference_client
16
- print("INFO: llm_clients.py - Attempting to initialize all API clients...")
17
- GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
18
- if GOOGLE_API_KEY and GOOGLE_API_KEY.strip():
19
- print("INFO: llm_clients.py - GOOGLE_API_KEY found.")
20
- try:
21
- genai.configure(api_key=GOOGLE_API_KEY)
22
- GEMINI_API_CONFIGURED = True
23
- print("SUCCESS: llm_clients.py - Google Gemini API configured.")
24
- except Exception as e:
25
- GEMINI_API_CONFIGURED = False
26
- print(f"ERROR: llm_clients.py - Failed to configure Google Gemini API: {type(e).__name__}: {e}")
27
- else:
28
- GEMINI_API_CONFIGURED = False
29
- print("WARNING: llm_clients.py - GOOGLE_API_KEY not found or empty.")
30
-
31
- HF_TOKEN = os.getenv("HF_TOKEN")
32
- if HF_TOKEN and HF_TOKEN.strip():
33
- print("INFO: llm_clients.py - HF_TOKEN found.")
34
- try:
35
- hf_inference_client = InferenceClient(token=HF_TOKEN)
36
- HF_API_CONFIGURED = True
37
- print("SUCCESS: llm_clients.py - Hugging Face InferenceClient initialized.")
38
- except Exception as e:
39
- HF_API_CONFIGURED = False
40
- print(f"ERROR: llm_clients.py - Failed to initialize HF InferenceClient: {type(e).__name__}: {e}")
41
- hf_inference_client = None
42
- else:
43
- HF_API_CONFIGURED = False
44
- print("WARNING: llm_clients.py - HF_TOKEN not found or empty.")
45
- print(f"INFO: llm_clients.py - Init complete. Gemini Configured: {GEMINI_API_CONFIGURED}, HF Configured: {HF_API_CONFIGURED}")
46
-
47
- # --- Status Getter Functions ---
48
- def is_gemini_api_configured():
49
- global GEMINI_API_CONFIGURED
50
- return GEMINI_API_CONFIGURED
51
-
52
- def is_hf_api_configured():
53
- global HF_API_CONFIGURED
54
- return HF_API_CONFIGURED
55
-
56
- # ... (LLMResponse class and call_huggingface_api function remain the same as the last full version) ...
57
- class LLMResponse: # Make sure this is defined
58
- def __init__(self, text=None, error=None, success=True, raw_response=None, model_id_used="unknown"):
59
- self.text, self.error, self.success, self.raw_response, self.model_id_used = text, error, success, raw_response, model_id_used
60
- def __str__(self): return str(self.text) if self.success and self.text is not None else f"ERROR (Model: {self.model_id_used}): {self.error}"
61
-
62
- def call_huggingface_api(prompt_text, model_id, temperature=0.7, max_new_tokens=512, system_prompt_text=None):
63
- print(f"DEBUG: llm_clients.py - call_huggingface_api for model: {model_id}")
64
- if not is_hf_api_configured() or not hf_inference_client: # Use getter
65
- error_msg = "HF API not configured."
66
- print(f"ERROR: llm_clients.py - {error_msg}")
67
- return LLMResponse(error=error_msg, success=False, model_id_used=model_id)
68
- full_prompt = f"<s>[INST] <<SYS>>\n{system_prompt_text}\n<</SYS>>\n\n{prompt_text} [/INST]" if system_prompt_text else prompt_text
69
- try:
70
- print(f" HF API Call - Prompt (first 100): {full_prompt[:100]}...")
71
- use_sample = temperature > 0.001
72
- raw_response = hf_inference_client.text_generation(full_prompt, model=model_id, max_new_tokens=max_new_tokens, temperature=temperature if use_sample else None, do_sample=use_sample, stream=False)
73
- print(f" HF API Call - Success for {model_id}. Response (first 100): {str(raw_response)[:100]}...")
74
- return LLMResponse(text=raw_response, raw_response=raw_response, model_id_used=model_id)
75
- except Exception as e:
76
- error_msg = f"HF API Error ({model_id}): {type(e).__name__} - {str(e)}"
77
- print(f"ERROR: llm_clients.py - {error_msg}")
78
- return LLMResponse(error=error_msg, success=False, raw_response=e, model_id_used=model_id)
79
-
80
-
81
- def call_gemini_api(prompt_text, model_id, temperature=0.7, max_new_tokens=1024, system_prompt_text=None): # Increased default max_tokens
82
- print(f"DEBUG: llm_clients.py - call_gemini_api for model: {model_id}")
83
- if not is_gemini_api_configured(): # Use getter
84
- error_msg = "Google Gemini API not configured."
85
- print(f"ERROR: llm_clients.py - {error_msg}")
86
- return LLMResponse(error=error_msg, success=False, model_id_used=model_id)
87
- try:
88
- print(f" Gemini API Call - Getting instance for: {model_id}")
89
- model_instance = genai.GenerativeModel(model_name=model_id, system_instruction=system_prompt_text)
90
- generation_config = genai.types.GenerationConfig(temperature=temperature, max_output_tokens=max_new_tokens)
91
- print(f" Gemini API Call - User Prompt (first 100): {prompt_text[:100]}...")
92
- if system_prompt_text: print(f" Gemini API Call - System Prompt (first 100): {system_prompt_text[:100]}...")
93
- raw_response = model_instance.generate_content(prompt_text, generation_config=generation_config, stream=False)
94
- print(f" Gemini API Call - Raw response for {model_id}. Feedback: {raw_response.prompt_feedback}, Candidates: {'Yes' if raw_response.candidates else 'No'}")
95
-
96
- if raw_response.prompt_feedback and raw_response.prompt_feedback.block_reason:
97
- reason = raw_response.prompt_feedback.block_reason_message or raw_response.prompt_feedback.block_reason
98
- error_msg = f"Gemini API: Prompt blocked. Reason: {reason}."
99
- print(f"WARNING: llm_clients.py - {error_msg}")
100
- return LLMResponse(error=error_msg, success=False, raw_response=raw_response, model_id_used=model_id)
101
- if not raw_response.candidates:
102
- error_msg = "Gemini API: No candidates in response (often due to blocking)."
103
- if raw_response.prompt_feedback: error_msg += f" Feedback: {raw_response.prompt_feedback}"
104
- print(f"WARNING: llm_clients.py - {error_msg}")
105
- return LLMResponse(error=error_msg, success=False, raw_response=raw_response, model_id_used=model_id)
106
-
107
- candidate = raw_response.candidates[0]
108
- if not candidate.content or not candidate.content.parts:
109
- finish_reason = str(candidate.finish_reason if candidate.finish_reason else "UNKNOWN").upper()
110
- error_msg = f"Gemini API: No content parts. Finish Reason: {finish_reason}."
111
- if finish_reason == "SAFETY": error_msg += " Likely safety filters."
112
- print(f"WARNING: llm_clients.py - {error_msg}")
113
- partial_text = candidate.content.parts[0].text if candidate.content and candidate.content.parts and hasattr(candidate.content.parts[0], 'text') else ""
114
- return LLMResponse(text=partial_text + f"\n[Note: Generation ended: {finish_reason}]" if partial_text else None, error=error_msg if not partial_text else None, success=bool(partial_text), raw_response=raw_response, model_id_used=model_id)
115
-
116
- response_text = candidate.content.parts[0].text
117
- print(f" Gemini API Call - Success for {model_id}. Response (first 100): {response_text[:100]}...")
118
- return LLMResponse(text=response_text, raw_response=raw_response, model_id_used=model_id)
119
- except Exception as e:
120
- error_msg = f"Gemini API Exception ({model_id}): {type(e).__name__} - {str(e)}"
121
- # ... (specific error parsing as before) ...
122
- if "API key not valid" in str(e) or "PERMISSION_DENIED" in str(e): error_msg = f"Gemini API Error ({model_id}): API key invalid/permission denied. Check GOOGLE_API_KEY & Google Cloud. Original: {str(e)}"
123
- elif "Could not find model" in str(e) : error_msg = f"Gemini API Error ({model_id}): Model ID '{model_id}' not found/inaccessible. Original: {str(e)}"
124
- elif "Quota exceeded" in str(e): error_msg = f"Gemini API Error ({model_id}): API quota exceeded. Original: {str(e)}"
125
- print(f"ERROR: llm_clients.py - {error_msg}")
126
- return LLMResponse(error=error_msg, success=False, raw_response=e, model_id_used=model_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/llm_services.py ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # storyverse_weaver/core/llm_services.py
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.")