1818from app .models .user import User
1919from app .ai_providers .registry import provider_registry
2020from app .ai_providers .ollama import OllamaProvider
21+ from app .utils .json_parsing import safe_encrypted_json_parse , validate_ollama_settings_format , create_default_ollama_settings
2122from app .schemas .ai_providers import (
2223 TextGenerationRequest ,
2324 ChatCompletionRequest ,
@@ -41,6 +42,12 @@ async def get_provider_instance_from_request(request, db):
4142 user_id = user_id .replace ("-" , "" )
4243
4344 logger = logging .getLogger (__name__ )
45+ print (f"🚀 PROVIDER REQUEST RECEIVED" )
46+ print (f"📊 Provider: { request .provider } " )
47+ print (f"📊 Settings ID: { request .settings_id } " )
48+ print (f"📊 Server ID: { request .server_id } " )
49+ print (f"📊 Model: { getattr (request , 'model' , 'N/A' )} " )
50+ print (f"📊 User ID: { user_id } " )
4451 logger .info (f"Getting provider instance for: settings_id={ request .settings_id } , user_id={ user_id } " )
4552 logger .info (f"Original user_id from request: { request .user_id } " )
4653
@@ -94,43 +101,63 @@ async def get_provider_instance_from_request(request, db):
94101
95102 # Use the first setting found
96103 setting = settings [0 ]
97- logger .info (f"Using setting with ID: { setting ['id' ] if isinstance (setting , dict ) else setting .id } " )
104+ logger .debug (f"Using setting with ID: { setting ['id' ] if isinstance (setting , dict ) else setting .id } " )
98105
99- # Extract configuration from settings value
100- # Parse the JSON string if value is a string
106+ # Extract configuration from settings value using robust parsing
101107 setting_value = setting ['value' ] if isinstance (setting , dict ) else setting .value
108+ setting_id = setting ['id' ] if isinstance (setting , dict ) else setting .id
102109
103- if isinstance (setting_value , str ):
104- try :
105- # First parse
106- logger .info ("Parsing settings value as JSON string" )
107- value_dict = json .loads (setting_value )
108- logger .debug (f"Parsed JSON string into: { value_dict } " )
109-
110- # Check if the result is still a string (double-encoded JSON)
111- if isinstance (value_dict , str ):
112- logger .info ("Value is double-encoded JSON, parsing again" )
113- value_dict = json .loads (value_dict )
114- logger .debug (f"Parsed double-encoded JSON into: { value_dict } " )
115-
116- # Now value_dict should be a dictionary
117- if not isinstance (value_dict , dict ):
118- logger .error (f"Error: value_dict is not a dictionary: { type (value_dict )} " )
110+ # Use our robust JSON parsing utility that handles encryption issues
111+ try :
112+ value_dict = safe_encrypted_json_parse (
113+ setting_value ,
114+ context = f"settings_id={ request .settings_id } , user_id={ user_id } " ,
115+ setting_id = setting_id ,
116+ definition_id = request .settings_id
117+ )
118+
119+ # Ensure we have a dictionary
120+ if not isinstance (value_dict , dict ):
121+ logger .error (f"Parsed value is not a dictionary: { type (value_dict )} " )
122+ # For Ollama settings, provide a default structure
123+ if 'ollama' in request .settings_id .lower ():
124+ logger .warning ("Creating default Ollama settings structure" )
125+ value_dict = create_default_ollama_settings ()
126+ else :
119127 raise HTTPException (
120128 status_code = 500 ,
121- detail = f"Error parsing settings value: expected dict , got { type (value_dict )} . "
122- f"Please check the format of your settings. "
129+ detail = f"Settings value must be a dictionary , got { type (value_dict )} . "
130+ f"Setting ID: { setting_id } "
123131 )
124- except json .JSONDecodeError as e :
125- logger .error (f"Error parsing JSON string: { e } " )
132+
133+ logger .debug (f"Successfully parsed settings value for { request .settings_id } " )
134+
135+ except ValueError as e :
136+ logger .error (f"Failed to parse encrypted settings: { e } " )
137+ # For Ollama settings, provide helpful error message and fallback
138+ if 'ollama' in request .settings_id .lower ():
139+ logger .info ("Ollama settings parsing failed, using fallback configuration" )
140+ value_dict = create_default_ollama_settings ()
141+ else :
126142 raise HTTPException (
127143 status_code = 500 ,
128- detail = f"Error parsing settings value: { str (e )} . "
129- f"Please ensure the settings value is valid JSON."
144+ detail = str (e )
130145 )
131- else :
132- logger .info ("Settings value is already a dictionary" )
133- value_dict = setting_value
146+ except Exception as e :
147+ logger .error (f"Unexpected error parsing settings: { e } " )
148+ raise HTTPException (
149+ status_code = 500 ,
150+ detail = f"Unexpected error parsing settings: { str (e )} . Setting ID: { setting_id } "
151+ )
152+
153+ # Add specific validation for Ollama settings
154+ if 'ollama' in request .settings_id .lower ():
155+ logger .info ("Validating Ollama settings format" )
156+ if not validate_ollama_settings_format (value_dict ):
157+ logger .warning ("Ollama settings format validation failed, using default structure" )
158+ value_dict = create_default_ollama_settings ()
159+ else :
160+ logger .info ("Ollama settings format validation passed" )
134161
135162 # Handle different provider configurations
136163 if request .provider == "openai" :
@@ -207,32 +234,45 @@ async def get_provider_instance_from_request(request, db):
207234 logger .info (f"Created Groq config with API key" )
208235 else :
209236 # Other providers (like Ollama) use servers array
210- logger .info ("Processing server-based provider configuration" )
237+ logger .debug ("Processing server-based provider configuration" )
211238 servers = value_dict .get ("servers" , [])
212- logger .info (f"Found { len (servers )} servers in settings" )
239+ logger .debug (f"Found { len (servers )} servers in settings" )
240+
241+ logger .debug ("Processing server-based provider configuration" )
242+ servers = value_dict .get ("servers" , [])
243+ logger .debug (f"Found { len (servers )} servers in settings" )
213244
214245 # Find the specific server by ID
215- logger .info (f"Looking for server with ID: { request .server_id } " )
246+ logger .debug (f"Looking for server with ID: ' { request .server_id } ' " )
216247 server = next ((s for s in servers if s .get ("id" ) == request .server_id ), None )
217- if not server and servers :
218- # If the requested server ID is not found but there are servers available,
219- # use the first server as a fallback
220- logger .warning (f"Server with ID { request .server_id } not found, using first available server as fallback" )
221- server = servers [0 ]
222- logger .info (f"Using fallback server: { server .get ('serverName' )} ({ server .get ('id' )} )" )
223248
224249 if not server :
225- logger .error (f"No server found with ID: { request .server_id } and no fallback available" )
226- raise HTTPException (
227- status_code = 404 ,
228- detail = f"Server not found with ID: { request .server_id } . "
229- f"Please check your server configuration or use a different server ID."
230- )
250+ # Provide detailed error message about available servers
251+ if servers :
252+ available_servers = [f"{ s .get ('serverName' , 'Unknown' )} (ID: { s .get ('id' , 'Unknown' )} )" for s in servers ]
253+ available_list = ", " .join (available_servers )
254+ logger .error (f"❌ Server with ID '{ request .server_id } ' not found" )
255+ logger .error (f"📋 Available servers: { available_list } " )
256+ raise HTTPException (
257+ status_code = 404 ,
258+ detail = f"Ollama server '{ request .server_id } ' not found. "
259+ f"Available servers: { available_list } . "
260+ f"Please select a valid server from your Ollama settings."
261+ )
262+ else :
263+ logger .error (f"❌ No Ollama servers configured" )
264+ raise HTTPException (
265+ status_code = 404 ,
266+ detail = "No Ollama servers are configured. "
267+ "Please add at least one Ollama server in your settings before using this provider."
268+ )
231269
232- logger .info (f"Found server: { server .get ('serverName' )} " )
270+ logger .debug (f"Found server: { server .get ('serverName' )} (ID: { server . get ( 'id' ) } ) " )
233271
234272 # Create provider configuration from server details
235273 server_url = server .get ("serverAddress" )
274+ logger .debug (f"Server URL from settings: '{ server_url } '" )
275+
236276 if not server_url :
237277 logger .error (f"Server URL is missing for server: { server .get ('id' )} " )
238278 raise HTTPException (
@@ -246,11 +286,11 @@ async def get_provider_instance_from_request(request, db):
246286 "api_key" : server .get ("apiKey" , "" ),
247287 "server_name" : server .get ("serverName" , "Unknown Server" )
248288 }
249-
250- logger .info (f"Created config with server_url : { config .get ('server_url' , 'N/A ' )} " )
289+
290+ logger .debug (f"Created server config : { config .get ('server_name' ) } -> { config . get ( 'server_url ' )} " )
251291
252292 # Get provider instance
253- logger .info (f"Getting provider instance for: { request .provider } , { request .server_id } " )
293+ logger .debug (f"Getting provider instance for: { request .provider } , { request .server_id } " )
254294 provider_instance = await provider_registry .get_provider (
255295 request .provider ,
256296 request .server_id ,
@@ -716,6 +756,13 @@ async def chat_completion(request: ChatCompletionRequest, db: AsyncSession = Dep
716756 """
717757 logger = logging .getLogger (__name__ )
718758 try :
759+ print (f"🎯 CHAT COMPLETION ENDPOINT CALLED" )
760+ print (f"📊 Provider: { request .provider } " )
761+ print (f"📊 Settings ID: { request .settings_id } " )
762+ print (f"📊 Server ID: { request .server_id } " )
763+ print (f"📊 Model: { request .model } " )
764+ print (f"📊 User ID: { request .user_id } " )
765+ print (f"📊 Stream: { request .stream } " )
719766 logger .info (f"Production chat endpoint called with: provider={ request .provider } , settings_id={ request .settings_id } , server_id={ request .server_id } , model={ request .model } " )
720767 logger .debug (f"Messages: { request .messages } " )
721768 logger .debug (f"Params: { request .params } " )
0 commit comments