"""AI research setup component for the API key manager.""" import streamlit as st from loguru import logger from typing import Dict, Any from ..manager import APIKeyManager import os from dotenv import load_dotenv # Keep if api_key_manager uses it import sys # Configure logger (assuming configured elsewhere or keep minimal here) logger.add(sys.stderr, level="INFO") # Keep simple example if needed # Helper function to validate a specific research provider's key def _validate_research_key(provider_name: str, key_value: str) -> bool: """Validate the API key for a given research provider.""" if not key_value: logger.debug(f"Validation: Key for {provider_name} is empty.") return False try: logger.debug(f"Validating key for {provider_name}...") # Ensure the function exists in validation.py before calling if provider_name == "serpapi": if callable(getattr(sys.modules[__name__], 'test_serpapi_key', None)): is_valid = test_serpapi_key(key_value) else: logger.error("test_serpapi_key not found in validation module") is_valid = False elif provider_name == "tavily": if callable(getattr(sys.modules[__name__], 'test_tavily_key', None)): is_valid = test_tavily_key(key_value) else: logger.error("test_tavily_key not found in validation module") is_valid = False elif provider_name == "metaphor": if callable(getattr(sys.modules[__name__], 'test_metaphor_key', None)): is_valid = test_metaphor_key(key_value) else: logger.error("test_metaphor_key not found in validation module") is_valid = False elif provider_name == "firecrawl": if callable(getattr(sys.modules[__name__], 'test_firecrawl_key', None)): is_valid = test_firecrawl_key(key_value) else: logger.error("test_firecrawl_key not found in validation module") is_valid = False else: logger.warning(f"Validation not implemented for research provider: {provider_name}") return False # Default to False for unknown providers logger.info(f"Validation result for {provider_name}: {'Valid' if is_valid else 'Invalid'}") return is_valid except Exception as e: logger.error(f"Error validating key for {provider_name}: {e}", exc_info=True) return False # Callback function for handling API key input changes def _handle_research_key_change(provider_name: str, api_key_manager): """Save and validate research API key when input changes.""" key_input_widget_key = f"{provider_name}_key_input" status_widget_key = f"{provider_name}_status" if key_input_widget_key not in st.session_state: logger.warning(f"Input widget key '{key_input_widget_key}' not found in session state.") return key_value = st.session_state[key_input_widget_key] current_status = st.session_state.get(status_widget_key) logger.debug(f"Handling research key change for {provider_name}. Key: {'***' if key_value else 'Empty'}. Current status: {current_status}") if not key_value: api_key_manager.save_api_key(provider_name, "") st.session_state[status_widget_key] = "unsaved" logger.info(f"Cleared API key for {provider_name}.") return st.session_state[status_widget_key] = "saving" st.rerun() try: logger.debug(f"Saving key for {provider_name}...") api_key_manager.save_api_key(provider_name, key_value) logger.info(f"Saved API key for {provider_name}.") is_valid = _validate_research_key(provider_name, key_value) if is_valid: st.session_state[status_widget_key] = "valid" else: st.session_state[status_widget_key] = "invalid" except Exception as e: logger.error(f"Error during saving/validation for {provider_name}: {e}", exc_info=True) st.session_state[status_widget_key] = "error" def render_ai_research_setup(api_key_manager: APIKeyManager) -> Dict[str, Any]: """Render the AI research setup step with immediate feedback.""" logger.info("[render_ai_research_setup] Rendering AI research setup component") research_providers = ["serpapi", "tavily", "metaphor", "firecrawl"] # Initialize statuses for provider in research_providers: status_key = f"{provider}_status" if status_key not in st.session_state: existing_key = api_key_manager.get_api_key(provider) if existing_key: if _validate_research_key(provider, existing_key): st.session_state[status_key] = "valid" else: st.session_state[status_key] = "invalid" else: st.session_state[status_key] = "unsaved" st.markdown("""
Set up API keys for enhanced web research, crawling, and analysis. These are optional but recommended.