@@ -100,15 +100,70 @@ def is_ollama_available() -> bool:
100100 return False
101101
102102
103+ def _check_api_key_validity (provider : str ) -> bool :
104+ """
105+ Check if API key for a provider is valid and configured using actual connection tests.
106+
107+ Args:
108+ provider: The provider name (openai, google, ollama)
109+
110+ Returns:
111+ True if API key is valid, False otherwise
112+ """
113+ logger .debug ("Checking API key validity for provider: %s" , provider )
114+
115+ try :
116+ from src .ui .settings_page import (
117+ _test_google_connection ,
118+ _test_ollama_connection ,
119+ _test_openai_connection ,
120+ )
121+
122+ if provider == "openai" :
123+ api_key = os .getenv ("OPENAI_API_KEY" , "" ).strip ()
124+ if not api_key :
125+ logger .debug ("OpenAI API key not configured" )
126+ return False
127+ # Test the connection
128+ model = os .getenv ("OPENAI_MODEL" , "gpt-4o-mini" )
129+ success , _ = _test_openai_connection (api_key , model )
130+ logger .debug ("OpenAI API key validity: %s" , success )
131+ return success
132+
133+ elif provider == "google" :
134+ api_key = os .getenv ("GOOGLE_API_KEY" , "" ).strip ()
135+ if not api_key :
136+ logger .debug ("Google API key not configured" )
137+ return False
138+ # Test the connection
139+ model = os .getenv ("GOOGLE_MODEL" , "gemini-2.0-flash-exp" )
140+ success , _ = _test_google_connection (api_key , model )
141+ logger .debug ("Google API key validity: %s" , success )
142+ return success
143+
144+ elif provider == "ollama" :
145+ # Ollama doesn't need API key, just needs to be running
146+ logger .debug ("Ollama provider doesn't require API key validation" )
147+ return is_ollama_available ()
148+
149+ else :
150+ logger .warning ("Unknown provider: %s" , provider )
151+ return False
152+
153+ except Exception as e :
154+ logger .error ("Error checking API key validity for %s: %s" , provider , str (e ))
155+ return False
156+
157+
103158def get_available_providers () -> list :
104159 """
105- Get list of available providers.
106- Ollama is only available if it's running .
160+ Get list of available providers with valid API keys .
161+ Only returns providers that have valid credentials configured .
107162
108163 Returns:
109164 List of available provider names
110165 """
111- logger .debug ("Getting available providers" )
166+ logger .debug ("Getting available providers with valid API keys " )
112167
113168 all_providers = list_providers ()
114169 logger .debug ("All registered providers: %s" , all_providers )
@@ -123,9 +178,14 @@ def get_available_providers() -> list:
123178 else :
124179 logger .debug ("Ollama is not available" )
125180 else :
126- # Google and OpenAI are always available (if API keys are set, they'll work)
127- available .append (provider )
128- logger .debug ("Provider %s is available" , provider )
181+ # Check if API key is valid for Google and OpenAI
182+ if _check_api_key_validity (provider ):
183+ available .append (provider )
184+ logger .debug ("Provider %s is available with valid API key" , provider )
185+ else :
186+ logger .debug (
187+ "Provider %s is not available (no valid API key)" , provider
188+ )
129189
130190 logger .info ("Available providers: %s" , available )
131191 return available
@@ -483,6 +543,10 @@ def _initialize_session_state():
483543 False ,
484544 "Initialized show_settings session state to False" ,
485545 ),
546+ "skip_initial_settings" : (
547+ False ,
548+ "Initialized skip_initial_settings session state to False" ,
549+ ),
486550 }
487551
488552 for key , (default_value , debug_message ) in session_state_defaults .items ():
@@ -552,6 +616,11 @@ def _show_provider_selection():
552616 use_container_width = True ,
553617 )
554618
619+ if st .button ("🔑 Configure API Keys" , use_container_width = True ):
620+ logger .info ("Opening API configuration from provider selection" )
621+ st .session_state .show_settings = True
622+ st .rerun ()
623+
555624 st .divider ()
556625 st .info (
557626 "💡 **Tip:** Ollama is free and runs locally. "
@@ -699,7 +768,7 @@ def _setup_sidebar(chatbot_agent, financial_advisor_agent):
699768 st .session_state .agent_is_healthy = False
700769 st .session_state .profile_loaded_from_json = False
701770 st .success ("Conversation cleared!" )
702-
771+
703772 # API Configuration button
704773 if st .button ("🔑 API Configuration" , use_container_width = True ):
705774 logger .info ("Opening API configuration settings" )
@@ -1585,8 +1654,36 @@ def main():
15851654
15861655 # Initialize session state
15871656 _initialize_session_state ()
1588-
1589- # Show settings page if requested
1657+
1658+ # Check if any providers are available
1659+ available_providers = get_available_providers ()
1660+ logger .debug ("Available providers on startup: %s" , available_providers )
1661+
1662+ # Show API key configuration on first load only if NO providers are available
1663+ if not st .session_state .skip_initial_settings and not available_providers :
1664+ logger .debug (
1665+ "First load with no available providers - showing API key configuration page"
1666+ )
1667+ _show_header ()
1668+ st .subheader ("🔑 Configure Your API Keys" )
1669+ st .markdown (
1670+ "Welcome! No LLM providers are currently configured. Let's set up your API keys and LLM provider settings before we get started."
1671+ )
1672+ show_settings_page ()
1673+
1674+ # Add button to proceed to provider selection
1675+ if st .button ("✅ Continue to Provider Selection" , use_container_width = True ):
1676+ logger .info ("User proceeding to provider selection after configuration" )
1677+ st .session_state .skip_initial_settings = True
1678+ st .rerun ()
1679+ return
1680+
1681+ # Mark initial settings as skipped if we reach here (at least one provider is available)
1682+ if not st .session_state .skip_initial_settings and available_providers :
1683+ logger .debug ("Skipping initial settings - at least one provider is available" )
1684+ st .session_state .skip_initial_settings = True
1685+
1686+ # Show settings page if requested from sidebar
15901687 if st .session_state .get ("show_settings" , False ):
15911688 show_settings_page ()
15921689 return
0 commit comments