Spaces:
Runtime error
Runtime error
File size: 9,828 Bytes
92eb899 742b2a5 92eb899 73f9fb2 742b2a5 3f5b0f9 92eb899 4a45067 742b2a5 73f9fb2 4a45067 73f9fb2 4a45067 f1fb766 4a45067 92eb899 3f5b0f9 4a45067 3f5b0f9 73f9fb2 3f5b0f9 4a45067 f1fb766 4a45067 f1fb766 4a45067 92eb899 f1fb766 4a45067 f1fb766 4a45067 92eb899 f1fb766 92eb899 03df531 742b2a5 03df531 742b2a5 f1fb766 742b2a5 f1fb766 742b2a5 f1fb766 742b2a5 f1fb766 742b2a5 f1fb766 742b2a5 92eb899 f1fb766 92eb899 f1fb766 92eb899 f1fb766 742b2a5 f1fb766 742b2a5 92eb899 f1fb766 92eb899 3f5b0f9 f1fb766 3f5b0f9 92eb899 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# modules/analyzer.py
from openai import OpenAI
import requests
import time
import logging
from modules.server_cache import RedisServerStatusCache
from modules.status_logger import log_server_status
class Analyzer:
def __init__(self, base_url, api_key):
self.client = OpenAI(
base_url=base_url,
api_key=api_key
)
self.base_url = base_url.rstrip('/')
self.health_check_url = self.base_url + "/health"
self.models_url = self.base_url + "/models"
self.headers = {"Authorization": f"Bearer {api_key}"}
self.cache_key = f"server_status_{base_url}"
# Connect to Redis cache
self.cache = RedisServerStatusCache()
def is_server_ready(self):
# Check cache first
cached_status = self.cache.get(self.cache_key)
if cached_status is not None:
logging.info(f"Using cached server status: {cached_status}")
return cached_status
# Try multiple approaches to check if server is ready
is_ready = False
# Approach 1: Try /models endpoint (commonly available)
try:
logging.info(f"Checking server models at: {self.models_url}")
response = requests.get(self.models_url, headers=self.headers, timeout=10)
if response.status_code in [200, 401, 403]: # 401/403 means auth required but endpoint exists
is_ready = True
logging.info(f"Server models check response: {response.status_code}")
else:
logging.info(f"Server models check response: {response.status_code}")
except requests.exceptions.RequestException as e:
logging.info(f"Models endpoint check failed: {str(e)}")
# Approach 2: Try a lightweight API call if models endpoint failed
if not is_ready:
try:
logging.info("Trying lightweight API call to test server availability")
# Make a request to list models (doesn't consume tokens)
response = requests.get(f"{self.base_url}/models", headers=self.headers, timeout=10)
if response.status_code in [200, 401, 403]:
is_ready = True
logging.info(f"Lightweight API call response: {response.status_code}")
else:
logging.info(f"Lightweight API call response: {response.status_code}")
except requests.exceptions.RequestException as e:
logging.info(f"Lightweight API call failed: {str(e)}")
# Cache the result for a shorter time since we're not using a proper health endpoint
self.cache.set(self.cache_key, is_ready, ttl=60) # Cache for 1 minute
log_server_status(self.cache_key, is_ready)
return is_ready
def wait_for_server(self, timeout=180, interval=15):
if self.is_server_ready():
logging.info("✅ Server is already ready (from cache or direct check).")
return True
logging.info("⏳ Server not ready. Starting polling...")
start_time = time.time()
while time.time() - start_time < timeout:
logging.info(f"Polling server... ({int(time.time() - start_time)}s elapsed)")
if self.is_server_ready():
logging.info("✅ Server is now ready!")
return True
time.sleep(interval)
logging.warning("⏰ Server initialization timeout reached")
return False
def analyze_stream(self, query, search_results):
"""
Analyze search results using the custom LLM with streaming output
Yields chunks of the response as they arrive
"""
# Prepare context from search results
context = "\n\n".join([
f"Source: {result.get('url', 'N/A')}\nTitle: {result.get('title', 'N/A')}\nContent: {result.get('content', 'N/A')}"
for result in search_results[:5] # Limit to top 5 for context
])
prompt = f"""
You are an expert research analyst. Analyze the following query and information to provide a comprehensive summary.
Query: {query}
Information:
{context}
Please provide:
1. A brief overview of the topic
2. Key findings or developments
3. Different perspectives or approaches
4. Potential implications or future directions
5. Any controversies or conflicting viewpoints
Structure your response clearly with these sections. If there is insufficient information, state that clearly.
"""
try:
# First check if server is ready
logging.info("Checking if server is ready for analysis...")
if not self.wait_for_server(timeout=180): # 3 minutes timeout
error_msg = "⚠️ The AI model server is still initializing. Please try again in a few minutes."
logging.warning(error_msg)
yield error_msg
return
logging.info("Server is ready. Sending streaming request to AI model...")
# Send streaming request
response = self.client.chat.completions.create(
model="DavidAU/OpenAi-GPT-oss-20b-abliterated-uncensored-NEO-Imatrix-gguf",
messages=[
{"role": "system", "content": "You are a helpful research assistant that provides structured, analytical responses."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=1500,
stream=True # Enable streaming
)
# Yield chunks as they arrive
for chunk in response:
if chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
logging.info("Analysis streaming completed successfully")
except Exception as e:
error_msg = str(e)
logging.error(f"Analysis streaming failed: {error_msg}")
if "503" in error_msg or "Service Unavailable" in error_msg:
yield "⚠️ The AI model server is currently unavailable. It may be initializing. Please try again in a few minutes."
elif "timeout" in error_msg.lower() or "read timeout" in error_msg.lower():
yield "⚠️ The AI model request timed out. The server may be overloaded or initializing. Please try again in a few minutes."
elif "404" in error_msg:
yield "⚠️ The AI model endpoint was not found. Please check the configuration."
else:
yield f"Analysis failed: {str(e)}"
def analyze(self, query, search_results):
"""
Non-streaming version for compatibility
"""
# Prepare context from search results
context = "\n\n".join([
f"Source: {result.get('url', 'N/A')}\nTitle: {result.get('title', 'N/A')}\nContent: {result.get('content', 'N/A')}"
for result in search_results[:5] # Limit to top 5 for context
])
prompt = f"""
You are an expert research analyst. Analyze the following query and information to provide a comprehensive summary.
Query: {query}
Information:
{context}
Please provide:
1. A brief overview of the topic
2. Key findings or developments
3. Different perspectives or approaches
4. Potential implications or future directions
5. Any controversies or conflicting viewpoints
Structure your response clearly with these sections. If there is insufficient information, state that clearly.
"""
try:
# First check if server is ready
logging.info("Checking if server is ready for analysis...")
if not self.wait_for_server(timeout=180): # 3 minutes timeout
error_msg = "⚠️ The AI model server is still initializing. Please try again in a few minutes."
logging.warning(error_msg)
return error_msg
logging.info("Server is ready. Sending request to AI model...")
response = self.client.chat.completions.create(
model="DavidAU/OpenAi-GPT-oss-20b-abliterated-uncensored-NEO-Imatrix-gguf",
messages=[
{"role": "system", "content": "You are a helpful research assistant that provides structured, analytical responses."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=1500,
stream=False
)
result_content = response.choices[0].message.content
logging.info("Analysis completed successfully")
return result_content
except Exception as e:
error_msg = str(e)
logging.error(f"Analysis failed: {error_msg}")
if "503" in error_msg or "Service Unavailable" in error_msg:
return "⚠️ The AI model server is currently unavailable. It may be initializing. Please try again in a few minutes."
elif "timeout" in error_msg.lower() or "read timeout" in error_msg.lower():
return "⚠️ The AI model request timed out. The server may be overloaded or initializing. Please try again in a few minutes."
elif "404" in error_msg:
return "⚠️ The AI model endpoint was not found. Please check the configuration."
return f"Analysis failed: {str(e)}" |