#!/usr/bin/env python3 """ Test programmatic access to Local Deep Research without database dependencies. """ from unittest.mock import Mock from langchain_core.retrievers import Document def test_import_without_database(): """Test that we can import AdvancedSearchSystem without database initialization.""" # This should not fail with database errors from local_deep_research.search_system import AdvancedSearchSystem # Should be able to create an instance with mock components llm = Mock() search = Mock() # Create settings snapshot without programmatic_mode settings_snapshot = { "search.iterations": {"value": 1, "type": "int"}, "search.questions_per_iteration": {"value": 2, "type": "int"}, "search.strategy": {"value": "direct", "type": "str"}, "search.max_results_per_query": {"value": 10, "type": "int"}, "search.source_strategy.diversity_threshold": { "value": 0.8, "type": "float", }, "search.source_strategy.min_relevance_score": { "value": 0.5, "type": "float", }, "search.source_strategy.max_sources_per_topic": { "value": 5, "type": "int", }, "search.source_strategy.enable_clustering": { "value": False, "type": "bool", }, "search.cross_engine_max_results": {"value": 100, "type": "int"}, } # Pass programmatic_mode as explicit parameter system = AdvancedSearchSystem( llm=llm, search=search, settings_snapshot=settings_snapshot, programmatic_mode=True, ) assert system is not None assert system.model == llm assert system.search == search assert system.programmatic_mode is True def test_analyze_topic_without_database(): """Test analyze_topic function without database.""" from local_deep_research.search_system import AdvancedSearchSystem # Create mock LLM llm = Mock() llm.invoke.return_value = Mock( content="This is a summary about AI research." ) # Create mock search engine search = Mock() search.run.return_value = [ { "title": "AI Research Paper", "link": "http://example.com/ai", "snippet": "Recent advances in AI...", "full_content": "Full content about AI research...", "rank": 1, } ] # Create settings snapshot without programmatic_mode settings_snapshot = { "search.iterations": {"value": 1, "type": "int"}, "search.questions_per_iteration": {"value": 2, "type": "int"}, "search.strategy": {"value": "direct", "type": "str"}, "search.max_results_per_query": {"value": 10, "type": "int"}, "search.source_strategy.diversity_threshold": { "value": 0.8, "type": "float", }, "search.source_strategy.min_relevance_score": { "value": 0.5, "type": "float", }, "search.source_strategy.max_sources_per_topic": { "value": 5, "type": "int", }, "search.source_strategy.enable_clustering": { "value": False, "type": "bool", }, "search.cross_engine_max_results": {"value": 100, "type": "int"}, } # Create system with programmatic_mode as parameter system = AdvancedSearchSystem( llm=llm, search=search, settings_snapshot=settings_snapshot, programmatic_mode=True, ) # Should be able to call analyze_topic result = system.analyze_topic("What is AI?") print(f"Result: {result}") print(f"Search called: {search.run.called}") print(f"Search call count: {search.run.call_count}") assert result is not None assert "findings" in result def test_search_with_retriever(): """Test using a retriever as search engine.""" from local_deep_research.search_system import AdvancedSearchSystem from langchain_community.vectorstores import FAISS from langchain_community.embeddings import FakeEmbeddings # Create a simple retriever documents = [ Document( page_content="Machine learning is a subset of artificial intelligence.", metadata={"source": "ml_intro.txt"}, ), Document( page_content="Deep learning uses neural networks with multiple layers.", metadata={"source": "dl_intro.txt"}, ), ] embeddings = FakeEmbeddings(size=10) vectorstore = FAISS.from_documents(documents, embeddings) retriever = vectorstore.as_retriever() # Create retriever wrapper class SimpleRetrieverWrapper: def __init__(self, retriever, settings_snapshot=None): self.retriever = retriever self.include_full_content = True self.settings_snapshot = settings_snapshot or {} def run(self, query, research_context=None): docs = self.retriever.get_relevant_documents(query) results = [] for i, doc in enumerate(docs): results.append( { "title": f"Result {i + 1}", "link": doc.metadata.get("source", "unknown"), "snippet": doc.page_content[:200], "full_content": doc.page_content if self.include_full_content else None, "rank": i + 1, } ) return results # Create mock LLM llm = Mock() llm.invoke.return_value = Mock(content="Summary about machine learning.") # Create settings without programmatic_mode settings_snapshot = { "search.iterations": {"value": 1, "type": "int"}, "search.questions_per_iteration": {"value": 2, "type": "int"}, "search.strategy": {"value": "direct", "type": "str"}, "search.max_results_per_query": {"value": 10, "type": "int"}, "search.source_strategy.diversity_threshold": { "value": 0.8, "type": "float", }, "search.source_strategy.min_relevance_score": { "value": 0.5, "type": "float", }, "search.source_strategy.max_sources_per_topic": { "value": 5, "type": "int", }, "search.source_strategy.enable_clustering": { "value": False, "type": "bool", }, "search.cross_engine_max_results": {"value": 100, "type": "int"}, } # Create search wrapper with settings search = SimpleRetrieverWrapper(retriever, settings_snapshot) # Create system with programmatic_mode as parameter system = AdvancedSearchSystem( llm=llm, search=search, settings_snapshot=settings_snapshot, programmatic_mode=True, ) # Run a search result = system.analyze_topic("What is machine learning?") assert result is not None assert "findings" in result assert len(result["findings"]) > 0 def test_thread_context_without_database(): """Test that thread context utilities work without database.""" from local_deep_research.utilities.thread_context import ( preserve_research_context, ) # This should not fail even without database @preserve_research_context def sample_function(): return "success" result = sample_function() assert result == "success" if __name__ == "__main__": # Run tests test_import_without_database() print("✓ Import test passed") test_analyze_topic_without_database() print("✓ Analyze topic test passed") test_search_with_retriever() print("✓ Retriever search test passed") test_thread_context_without_database() print("✓ Thread context test passed") print("\nAll tests passed! Programmatic access works without database.")