""" Test Research Agent Functionality This test demonstrates the Research Agent's ability to: 1. Detect knowledge gaps by searching the feature registry 2. Learn patterns from example files (XML, Python, etc.) 3. Synthesize knowledge from multiple sources 4. Document research sessions Example workflow: - User requests: "Create NX material XML for titanium" - Agent detects: No 'material_generator' feature exists - Agent plans: Ask user for example → Learn schema → Generate feature - Agent learns: From user-provided steel_material.xml - Agent generates: New material XML following learned schema Author: Atomizer Development Team Version: 0.1.0 (Phase 2) Last Updated: 2025-01-16 """ import sys import os from pathlib import Path # Set UTF-8 encoding for Windows console if sys.platform == 'win32': import codecs sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, errors='replace') sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, errors='replace') # Add project root to path project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from optimization_engine.future.research_agent import ( ResearchAgent, ResearchFindings, CONFIDENCE_LEVELS ) def test_knowledge_gap_detection(): """Test that the agent can detect when it lacks knowledge.""" print("\n" + "="*60) print("TEST 1: Knowledge Gap Detection") print("="*60) agent = ResearchAgent() # Test 1: Known feature (minimize stress) print("\n[Test 1a] Request: 'Minimize stress in my bracket'") gap = agent.identify_knowledge_gap("Minimize stress in my bracket") print(f" Missing features: {gap.missing_features}") print(f" Missing knowledge: {gap.missing_knowledge}") print(f" Confidence: {gap.confidence:.2f}") print(f" Research needed: {gap.research_needed}") assert gap.confidence > 0.5, "Should have high confidence for known features" print(" [PASS] Correctly identified existing feature") # Test 2: Unknown feature (material XML) print("\n[Test 1b] Request: 'Create NX material XML for titanium'") gap = agent.identify_knowledge_gap("Create NX material XML for titanium") print(f" Missing features: {gap.missing_features}") print(f" Missing knowledge: {gap.missing_knowledge}") print(f" Confidence: {gap.confidence:.2f}") print(f" Research needed: {gap.research_needed}") assert gap.research_needed, "Should need research for unknown domain" assert 'material' in gap.missing_knowledge, "Should identify material domain gap" print(" [PASS] Correctly detected knowledge gap") def test_xml_schema_learning(): """Test that the agent can learn XML schemas from examples.""" print("\n" + "="*60) print("TEST 2: XML Schema Learning") print("="*60) agent = ResearchAgent() # Create example NX material XML example_xml = """ 7850 200 0.29 1.17e-05 295 420 """ print("\n[Test 2a] Learning from steel material XML...") print(" Example XML:") print(" " + "\n ".join(example_xml.split('\n')[:3])) print(" ...") # Create research findings with XML data findings = ResearchFindings( sources={'user_example': 'steel_material.xml'}, raw_data={'user_example': example_xml}, confidence_scores={'user_example': CONFIDENCE_LEVELS['user_validated']} ) # Synthesize knowledge from findings knowledge = agent.synthesize_knowledge(findings) print(f"\n Synthesis notes:") for line in knowledge.synthesis_notes.split('\n'): print(f" {line}") # Verify schema was extracted assert knowledge.schema is not None, "Should extract schema from XML" assert 'xml_structure' in knowledge.schema, "Should have XML structure" assert knowledge.schema['xml_structure']['root_element'] == 'PhysicalMaterial', "Should identify root element" print(f"\n Root element: {knowledge.schema['xml_structure']['root_element']}") print(f" Required fields: {knowledge.schema['xml_structure']['required_fields']}") print(f" Confidence: {knowledge.confidence:.2f}") assert knowledge.confidence > 0.8, "User-validated example should have high confidence" print("\n ✓ PASSED: Successfully learned XML schema") def test_python_code_pattern_extraction(): """Test that the agent can extract reusable patterns from Python code.""" print("\n" + "="*60) print("TEST 3: Python Code Pattern Extraction") print("="*60) agent = ResearchAgent() # Example Python code example_code = """ import numpy as np from pathlib import Path class MaterialGenerator: def __init__(self, template_path): self.template_path = template_path def generate_material_xml(self, name, density, youngs_modulus): # Generate XML from template xml_content = f''' {density} {youngs_modulus} ''' return xml_content """ print("\n[Test 3a] Extracting patterns from Python code...") print(" Code sample:") print(" " + "\n ".join(example_code.split('\n')[:5])) print(" ...") findings = ResearchFindings( sources={'code_example': 'material_generator.py'}, raw_data={'code_example': example_code}, confidence_scores={'code_example': 0.8} ) knowledge = agent.synthesize_knowledge(findings) print(f"\n Patterns extracted: {len(knowledge.patterns)}") for pattern in knowledge.patterns: if pattern['type'] == 'class': print(f" - Class: {pattern['name']}") elif pattern['type'] == 'function': print(f" - Function: {pattern['name']}({pattern['parameters']})") elif pattern['type'] == 'import': module = pattern['module'] or '' print(f" - Import: {module} {pattern['items']}") # Verify patterns were extracted class_patterns = [p for p in knowledge.patterns if p['type'] == 'class'] func_patterns = [p for p in knowledge.patterns if p['type'] == 'function'] import_patterns = [p for p in knowledge.patterns if p['type'] == 'import'] assert len(class_patterns) > 0, "Should extract class definitions" assert len(func_patterns) > 0, "Should extract function definitions" assert len(import_patterns) > 0, "Should extract import statements" print("\n ✓ PASSED: Successfully extracted code patterns") def test_research_session_documentation(): """Test that research sessions are properly documented.""" print("\n" + "="*60) print("TEST 4: Research Session Documentation") print("="*60) agent = ResearchAgent() # Simulate a complete research session from optimization_engine.future.research_agent import KnowledgeGap, SynthesizedKnowledge gap = KnowledgeGap( missing_features=['material_xml_generator'], missing_knowledge=['NX material XML format'], user_request="Create NX material XML for titanium Ti-6Al-4V", confidence=0.2 ) findings = ResearchFindings( sources={'user_example': 'steel_material.xml'}, raw_data={'user_example': ''}, confidence_scores={'user_example': 0.95} ) knowledge = agent.synthesize_knowledge(findings) generated_files = [ 'optimization_engine/custom_functions/nx_material_generator.py', 'knowledge_base/templates/xml_generation_template.py' ] print("\n[Test 4a] Documenting research session...") session_path = agent.document_session( topic='nx_materials', knowledge_gap=gap, findings=findings, knowledge=knowledge, generated_files=generated_files ) print(f"\n Session path: {session_path}") print(f" Session exists: {session_path.exists()}") # Verify session files were created assert session_path.exists(), "Session folder should be created" assert (session_path / 'user_question.txt').exists(), "Should save user question" assert (session_path / 'sources_consulted.txt').exists(), "Should save sources" assert (session_path / 'findings.md').exists(), "Should save findings" assert (session_path / 'decision_rationale.md').exists(), "Should save rationale" # Read and display user question user_question = (session_path / 'user_question.txt').read_text() print(f"\n User question saved: {user_question}") # Read and display findings findings_content = (session_path / 'findings.md').read_text() print(f"\n Findings preview:") for line in findings_content.split('\n')[:10]: print(f" {line}") print("\n ✓ PASSED: Successfully documented research session") def test_multi_source_synthesis(): """Test combining knowledge from multiple sources.""" print("\n" + "="*60) print("TEST 5: Multi-Source Knowledge Synthesis") print("="*60) agent = ResearchAgent() # Simulate findings from multiple sources xml_example = """ 8000 110 """ code_example = """ def create_material(density, modulus): return {'density': density, 'modulus': modulus} """ findings = ResearchFindings( sources={ 'user_example': 'material.xml', 'web_docs': 'documentation.html', 'code_sample': 'generator.py' }, raw_data={ 'user_example': xml_example, 'web_docs': {'schema': 'Material schema from official docs'}, 'code_sample': code_example }, confidence_scores={ 'user_example': CONFIDENCE_LEVELS['user_validated'], # 0.95 'web_docs': CONFIDENCE_LEVELS['web_generic'], # 0.50 'code_sample': CONFIDENCE_LEVELS['nxopen_tse'] # 0.70 } ) print("\n[Test 5a] Synthesizing from 3 sources...") print(f" Sources: {list(findings.sources.keys())}") print(f" Confidence scores:") for source, score in findings.confidence_scores.items(): print(f" - {source}: {score:.2f}") knowledge = agent.synthesize_knowledge(findings) print(f"\n Overall confidence: {knowledge.confidence:.2f}") print(f" Total patterns: {len(knowledge.patterns)}") print(f" Schema elements: {len(knowledge.schema) if knowledge.schema else 0}") # Weighted confidence should be dominated by high-confidence user example assert knowledge.confidence > 0.7, "Should have high confidence with user-validated source" assert knowledge.schema is not None, "Should extract schema from XML" assert len(knowledge.patterns) > 0, "Should extract patterns from code" print("\n ✓ PASSED: Successfully synthesized multi-source knowledge") def run_all_tests(): """Run all Research Agent tests.""" print("\n" + "="*60) print("=" + " "*58 + "=") print("=" + " RESEARCH AGENT TEST SUITE - Phase 2".center(58) + "=") print("=" + " "*58 + "=") print("="*60) try: test_knowledge_gap_detection() test_xml_schema_learning() test_python_code_pattern_extraction() test_research_session_documentation() test_multi_source_synthesis() print("\n" + "="*60) print("ALL TESTS PASSED! ✓") print("="*60) print("\nResearch Agent is functional and ready for use.") print("\nNext steps:") print(" 1. Integrate with LLM interface for interactive research") print(" 2. Add web search capability (Phase 2 Week 2)") print(" 3. Implement feature generation from learned templates") print(" 4. Build knowledge retrieval system") print() return True except AssertionError as e: print(f"\n✗ TEST FAILED: {e}") import traceback traceback.print_exc() return False except Exception as e: print(f"\n✗ UNEXPECTED ERROR: {e}") import traceback traceback.print_exc() return False if __name__ == '__main__': success = run_all_tests() sys.exit(0 if success else 1)