search_index.json•96.3 kB
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde0 Adaptive Graph of Thoughts","text":"<p>Transforming Scientific Discovery with Intelligent Graph-Based Reasoning</p> <p>Get Started Explore Features View on GitHub</p> Intelligent Scientific Reasoning through Graph-of-Thoughts <p> </p> <p>\ud83d\ude80 Next-Generation AI Reasoning Framework for Scientific Research</p> <p>Leveraging graph structures to transform how AI systems approach scientific reasoning</p>"},{"location":"#overview","title":"\ud83d\udd0d Overview","text":"<p>Adaptive Graph of Thoughts leverages a Neo4j graph database to perform sophisticated scientific reasoning, with graph operations managed within its pipeline stages. It implements the Model Context Protocol (MCP) to integrate with AI applications like Claude Desktop, providing an Advanced Scientific Reasoning Graph-of-Thoughts (ASR-GoT) framework designed for complex research tasks.</p> <p>Key highlights: - Process complex scientific queries using graph-based reasoning - Dynamic confidence scoring with multi-dimensional evaluations - Built with modern Python and FastAPI for high performance - Dockerized for easy deployment - Modular design for extensibility and customization - Integration with Claude Desktop via MCP protocol</p>"},{"location":"#key-features","title":"\ud83c\udf1f Key Features","text":""},{"location":"#8-stage-reasoning-pipeline","title":"8-Stage Reasoning Pipeline","text":"<pre><code>graph TD\n A[\ud83c\udf31 Stage 1: Initialization] --> B[\ud83e\udde9 Stage 2: Decomposition]\n B --> C[\ud83d\udd2c Stage 3: Hypothesis/Planning]\n C --> D[\ud83d\udcca Stage 4: Evidence Integration]\n D --> E[\u2702\ufe0f Stage 5: Pruning/Merging]\n E --> F[\ud83d\udd0d Stage 6: Subgraph Extraction]\n F --> G[\ud83d\udcdd Stage 7: Composition]\n G --> H[\ud83e\udd14 Stage 8: Reflection]\n\n A1[Create root node<br/>Set initial confidence<br/>Define graph structure] --> A\n B1[Break into dimensions<br/>Identify components<br/>Create dimensional nodes] --> B\n C1[Generate hypotheses<br/>Create reasoning strategy<br/>Set falsification criteria] --> C\n D1[Gather evidence<br/>Link to hypotheses<br/>Update confidence scores] --> D\n E1[Remove low-value elements<br/>Consolidate similar nodes<br/>Optimize structure] --> E\n F1[Identify relevant portions<br/>Focus on high-value paths<br/>Create targeted subgraphs] --> F\n G1[Synthesize findings<br/>Create coherent insights<br/>Generate comprehensive answer] --> G\n H1[Evaluate reasoning quality<br/>Identify improvements<br/>Final confidence assessment] --> H\n\n style A fill:#e1f5fe\n style B fill:#f3e5f5\n style C fill:#e8f5e8\n style D fill:#fff3e0\n style E fill:#ffebee\n style F fill:#f1f8e9\n style G fill:#e3f2fd\n style H fill:#fce4ec</code></pre> <p>The core reasoning process follows a sophisticated 8-stage pipeline:</p> <ol> <li>\ud83c\udf31 Initialization</li> <li>Creates root node from query with multi-dimensional confidence vector</li> <li>Establishes initial graph structure with proper metadata</li> <li> <p>Sets baseline confidence across empirical, theoretical, methodological, and consensus dimensions</p> </li> <li> <p>\ud83e\udde9 Decomposition</p> </li> <li>Breaks query into key dimensions: Scope, Objectives, Constraints, Data Needs, Use Cases</li> <li>Identifies potential biases and knowledge gaps from the outset</li> <li> <p>Creates dimensional nodes with initial confidence assessments</p> </li> <li> <p>\ud83d\udd2c Hypothesis/Planning</p> </li> <li>Generates 3-5 hypotheses per dimension with explicit falsification criteria</li> <li>Creates detailed execution plans for each hypothesis</li> <li> <p>Tags with disciplinary provenance and impact estimates</p> </li> <li> <p>\ud83d\udcca Evidence Integration</p> </li> <li>Iteratively selects hypotheses based on confidence-to-cost ratio and impact</li> <li>Gathers and links evidence using typed edges (causal, temporal, correlative)</li> <li> <p>Updates confidence vectors using Bayesian methods with statistical power assessment</p> </li> <li> <p>\u2702\ufe0f Pruning/Merging</p> </li> <li>Removes nodes with low confidence and impact scores</li> <li>Consolidates semantically similar nodes</li> <li> <p>Optimizes graph structure while preserving critical relationships</p> </li> <li> <p>\ud83d\udd0d Subgraph Extraction</p> </li> <li>Identifies high-value subgraphs based on multiple criteria</li> <li>Focuses on nodes with high confidence and impact scores</li> <li> <p>Extracts patterns relevant to the original query</p> </li> <li> <p>\ud83d\udcdd Composition</p> </li> <li>Synthesizes findings into coherent narrative</li> <li>Annotates claims with node IDs and edge types</li> <li> <p>Provides comprehensive answers with proper citations</p> </li> <li> <p>\ud83e\udd14 Reflection</p> </li> <li>Performs comprehensive quality audit</li> <li>Evaluates coverage, bias detection, and methodological rigor</li> <li>Provides final confidence assessment and improvement recommendations</li> </ol>"},{"location":"#advanced-technical-capabilities","title":"Advanced Technical Capabilities","text":"\ud83d\udd04 Multi-DimensionalConfidence \ud83e\udde0 Graph-BasedKnowledge \ud83d\udd0c MCPIntegration \u26a1 FastAPIBackend \ud83d\udc33 DockerDeployment \ud83e\udde9 ModularDesign \u2699\ufe0f ConfigurationManagement \ud83d\udd12 TypeSafety \ud83c\udf10 InterdisciplinaryBridge Nodes \ud83d\udd17 HyperedgeSupport \ud83d\udcca StatisticalPower Analysis \ud83c\udfaf ImpactEstimation"},{"location":"#architectural-highlights","title":"Architectural Highlights","text":"<p>Adaptive Graph of Thoughts is built around a flexible 8-stage pipeline architecture, where each stage encapsulates specific reasoning logic. This design promotes modularity and clarity.</p> <ul> <li>8-Stage Pipeline Design: The core reasoning process is broken down into eight distinct stages, from initialization to reflection. Each stage has a well-defined responsibility.</li> <li>Stage-Specific Logic and Neo4j Interaction: Graph operations and interactions with the Neo4j database are primarily handled within individual stages. Each stage formulates and executes Cypher queries relevant to its task, utilizing <code>neo4j_utils</code> for database communication. This means the graph representation is persisted and manipulated directly within Neo4j.</li> <li>Orchestration by <code>GoTProcessor</code>: The <code>GoTProcessor</code> acts as the central orchestrator. It manages the flow through the 8-stage pipeline, invoking each stage in sequence. It does not manage a central graph object in memory; rather, it facilitates the overall process.</li> <li>Data Flow Between Stages: Data is passed between stages using <code>GoTProcessorSessionData</code> and <code>accumulated_context</code>. Each stage receives context from previous stages and can contribute its findings to the <code>accumulated_context</code>, which is then available to subsequent stages. This allows for a progressive build-up of insights as the pipeline executes.</li> </ul> <p>Core Features: - \ud83e\udde0 Graph Knowledge Representation: Utilizes a Neo4j graph database to model complex relationships. Graph interactions and manipulations are performed by individual pipeline stages using Cypher queries via <code>neo4j_utils</code>. - \ud83d\udd04 Dynamic Confidence Vectors: Four-dimensional confidence assessment (empirical support, theoretical basis, methodological rigor, consensus alignment) - \ud83c\udf10 Interdisciplinary Bridge Nodes: Automatically connects insights across different research domains - \ud83d\udd17 Advanced Edge Types: Supports causal, temporal, correlative, and custom relationship types - \ud83d\udcca Statistical Rigor: Integrated power analysis and effect size estimation - \ud83c\udfaf Impact-Driven Prioritization: Focuses on high-impact research directions - \ud83d\udd0c MCP Server: Seamless Claude Desktop integration with Model Context Protocol - \u26a1 High-Performance API: Modern FastAPI implementation with async support</p>"},{"location":"#technology-stack","title":"\ud83d\udee0\ufe0f Technology Stack","text":"Python 3.11+ FastAPI NetworkX Docker Pytest Pydantic Poetry Uvicorn <p>For detailed setup, usage, and contribution guidelines, please refer to the respective sections in this documentation.</p>"},{"location":"CONTRIBUTING/","title":"Contributing to Adaptive Graph of Thoughts","text":"<p>We welcome contributions to Adaptive Graph of Thoughts! Please follow these general guidelines when contributing:</p>"},{"location":"CONTRIBUTING/#getting-started","title":"Getting Started","text":"<ul> <li>Fork the Repository: Start by forking the main Adaptive Graph of Thoughts repository to your own GitHub account.</li> <li>Clone your fork: <pre><code>git clone https://github.com/YOUR_USERNAME/Adaptive Graph of Thoughts.git\ncd Adaptive Graph of Thoughts\n</code></pre></li> <li>Install Dependencies: Ensure you have Poetry (version 1.2+) installed and run: <pre><code>poetry install --with dev\n</code></pre> This will create a virtual environment and install all necessary dependencies.</li> </ul>"},{"location":"CONTRIBUTING/#branching-strategy","title":"Branching Strategy","text":"<ol> <li>Branch from <code>main</code>: Always create your new feature or bugfix branches from the latest <code>main</code> branch of the upstream (original) Adaptive Graph of Thoughts repository. <pre><code># Ensure your main branch is up-to-date with upstream\ngit checkout main\ngit pull upstream main # Assuming 'upstream' remote is configured to git@github.com:CognitiveAreNa/Adaptive Graph of Thoughts.git\n\n# Create your new branch\ngit checkout -b feature/your-descriptive-feature-name\n</code></pre> Or for bug fixes: <pre><code>git checkout -b fix/issue-123-brief-description\n</code></pre></li> <li>Naming Conventions:<ul> <li>Feature branches: <code>feature/some-feature-description</code></li> <li>Bugfix branches: <code>fix/issue-number-short-description</code> (e.g., <code>fix/123-mcp-auth-error</code>)</li> <li>Documentation branches: <code>docs/update-readme-styles</code></li> <li>Refactor branches: <code>refactor/improve-stage-loading</code></li> </ul> </li> </ol>"},{"location":"CONTRIBUTING/#development-process","title":"Development Process","text":"<ol> <li>Make Changes: Implement your feature or bug fix in your created branch.</li> <li>Write Tests: <ul> <li>Add appropriate tests for your changes. </li> <li>Ensure all existing and new tests pass by running: <pre><code>poetry run pytest\n</code></pre></li> <li>Test Coverage: We aim for a high test coverage of over 95%. Please ensure your contributions include relevant tests to maintain or increase this coverage.</li> </ul> </li> <li>Check Code Quality: Run linters and type checkers: <pre><code>poetry run ruff check .\npoetry run ruff format . # Or use an IDE plugin for on-the-fly formatting\npoetry run mypy src/\n</code></pre></li> <li>Commit Your Changes: <ul> <li>Follow Conventional Commit guidelines if possible (e.g., <code>feat: add user authentication</code>, <code>fix: resolve issue with API response</code>). This is not strictly enforced but highly encouraged.</li> <li>Write clear and concise commit messages.</li> </ul> </li> <li>Push to Your Fork: <pre><code>git push origin feature/your-descriptive-feature-name\n</code></pre></li> <li>Submit a Pull Request: <ul> <li>Open a pull request from your feature branch in your fork to the <code>main</code> branch of the <code>CognitiveAreNa/Adaptive Graph of Thoughts</code> repository.</li> <li>Provide a clear title and a detailed description of your changes in the pull request. Link any relevant issues.</li> <li>Ensure all automated checks (CI/CD pipeline) pass.</li> </ul> </li> </ol>"},{"location":"CONTRIBUTING/#code-style","title":"Code Style","text":"<ul> <li>PEP 8: Follow PEP 8 style guidelines. <code>ruff</code> helps enforce this.</li> <li>Type Hints: Use type hints for all function and method signatures, and for complex variable types. <code>mypy</code> is used for static type checking.</li> <li>Docstrings: Write comprehensive docstrings for all modules, classes, functions, and methods using a standard format (e.g., Google style, reStructuredText). Explain what the code does, its arguments, and what it returns.</li> <li>Imports: Organize imports according to PEP 8 (standard library, then third-party, then local application/library specific imports, each group separated by a blank line). <code>ruff</code> can help sort these.</li> </ul>"},{"location":"CONTRIBUTING/#release-strategy","title":"Release Strategy","text":"<p>The project aims to follow Semantic Versioning (SemVer - <code>MAJOR.MINOR.PATCH</code>). Releases are managed by the core maintainers. Branch protection rules are in place for the <code>main</code> branch to ensure stability.</p>"},{"location":"CONTRIBUTING/#reporting-issues","title":"Reporting Issues","text":"<p>If you find a bug or have a feature request, please open an issue on the GitHub repository.</p> <p>Thank you for contributing!</p>"},{"location":"ROADMAP/","title":"Adaptive Graph of Thoughts Roadmap","text":"<p>This document outlines potential future development directions for Adaptive Graph of Thoughts. These are ideas for community contribution and project evolution. Priorities and timelines are subject to change.</p>"},{"location":"ROADMAP/#near-term-goals","title":"Near-Term Goals","text":"<ul> <li>Enhanced Documentation: Continuously improving user and developer documentation, including more examples and tutorials.</li> <li>Refinement of Core Stages: Optimizing existing ASR-GoT stages for performance and accuracy.</li> <li>Expanded Test Coverage: Striving for comprehensive test coverage across all modules.</li> </ul>"},{"location":"ROADMAP/#medium-term-goals","title":"Medium-Term Goals","text":"<ul> <li>UI for Graph Visualization: Develop a user interface for interactive exploration of knowledge graphs (suggested feature, see <code>docs/suggested_issues/ui_for_graph_visualization.md</code> for details).</li> <li>Integration with Arxiv API: Enhance evidence gathering by integrating with the Arxiv API (suggested feature, see <code>docs/suggested_issues/integration_with_arxiv_api.md</code> for details).</li> <li>Advanced Configuration Options: Exploring more granular configuration for stages and parameters.</li> </ul>"},{"location":"ROADMAP/#long-term-vision","title":"Long-Term / Vision","text":"<ul> <li>Wider Range of Data Source Integrations: Connectors for more academic databases, enterprise knowledge bases, etc.</li> <li>User-Defined Custom Stages via UI: Allowing users to define or combine stages through a graphical interface.</li> <li>Collaborative Reasoning: Features enabling multiple users or agents to contribute to a single reasoning process.</li> </ul>"},{"location":"ROADMAP/#contributing","title":"Contributing","text":"<p>We welcome contributions! If you're interested in tackling any of these areas, please check our Contributing Guidelines and consider opening an issue to discuss your ideas.</p>"},{"location":"claude_action/","title":"Claude Desktop Custom Action","text":"<p>A lightweight custom action lets Claude Desktop query the Adaptive Graph of Thoughts server without any code.</p> <p>Place the <code>manifest.json</code> and <code>index.js</code> files from <code>integrations/claude-action</code> into Claude's custom actions directory. When text is selected, choose Ask Adaptive Graph from the action menu and the selection will be sent to the <code>/nlq</code> endpoint. The returned summary is displayed inside Claude.</p>"},{"location":"configuration/","title":"Configuration Reference","text":"<ul> <li>app/</li> <li><code>app.name</code>: <code>Adaptive Graph of Thoughts</code></li> <li><code>app.version</code>: <code>0.1.0</code></li> <li><code>app.host</code>: <code>0.0.0.0</code></li> <li><code>app.port</code>: <code>8000</code></li> <li><code>app.mcp_transport_type</code>: <code>http</code></li> <li><code>app.mcp_stdio_enabled</code>: <code>True</code></li> <li><code>app.mcp_http_enabled</code>: <code>True</code></li> <li><code>app.log_level</code>: <code>INFO</code></li> <li>asr_got/</li> <li>asr_got.default_parameters/</li> <li><code>asr_got.default_parameters.initial_confidence</code>: <code>[0.9, 0.9, 0.9, 0.9]</code></li> <li><code>asr_got.default_parameters.initial_layer</code>: <code>root_layer</code></li> <li><code>asr_got.default_parameters.default_decomposition_dimensions</code>: <code>[{'label': 'Scope and Delimitations', 'description': 'Clearly define the boundaries and specific focus of the research question.'}, {'label': 'Core Objectives', 'description': 'Identify the primary goals and desired outcomes of the analysis.'}, {'label': 'Methodological Approach', 'description': 'Outline the research methods and analytical techniques to be employed.'}, {'label': 'Data Requirements and Availability', 'description': 'Specify the types of data needed and assess their accessibility and quality.'}, {'label': 'Key Assumptions', 'description': 'List any underlying assumptions made at the outset of the investigation.'}, {'label': 'Potential Challenges and Limitations', 'description': 'Anticipate obstacles, constraints, or limitations that might affect the research.'}, {'label': 'Expected Impact and Applications', 'description': 'Consider the potential significance of the findings and their practical use cases.'}, {'label': 'Ethical Considerations', 'description': 'Address any ethical implications related to the research topic or methodology.'}, {'label': 'Identification of Knowledge Gaps', 'description': 'Pinpoint areas of uncertainty or missing information relevant to the query.'}, {'label': 'Assessment of Potential Biases', 'description': 'Identify possible cognitive, methodological, or data-related biases.'}]</code></li> <li><code>asr_got.default_parameters.dimension_confidence</code>: <code>[0.8, 0.8, 0.8, 0.8]</code></li> <li>asr_got.default_parameters.hypotheses_per_dimension/</li> <li><code>asr_got.default_parameters.hypotheses_per_dimension.min</code>: <code>2</code></li> <li><code>asr_got.default_parameters.hypotheses_per_dimension.max</code>: <code>4</code></li> <li><code>asr_got.default_parameters.hypothesis_confidence</code>: <code>[0.5, 0.5, 0.5, 0.5]</code></li> <li><code>asr_got.default_parameters.default_disciplinary_tags</code>: <code>['general_science', 'interdisciplinary_studies']</code></li> <li><code>asr_got.default_parameters.default_plan_types</code>: <code>['literature_review', 'data_analysis', 'simulation', 'expert_consultation']</code></li> <li><code>asr_got.default_parameters.evidence_max_iterations</code>: <code>5</code></li> <li><code>asr_got.default_parameters.pruning_confidence_threshold</code>: <code>0.2</code></li> <li><code>asr_got.default_parameters.pruning_impact_threshold</code>: <code>0.3</code></li> <li><code>asr_got.default_parameters.merging_semantic_overlap_threshold</code>: <code>0.8</code></li> <li><code>asr_got.default_parameters.subgraph_min_confidence_threshold</code>: <code>0.6</code></li> <li><code>asr_got.default_parameters.subgraph_min_impact_threshold</code>: <code>0.5</code></li> <li><code>asr_got.pipeline_stages</code>: <code>[{'name': 'Initialization', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_1_initialization.InitializationStage', 'enabled': True}, {'name': 'Decomposition', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_2_decomposition.DecompositionStage', 'enabled': True}, {'name': 'Hypothesis Generation', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_3_hypothesis.HypothesisStage', 'enabled': True}, {'name': 'Evidence Integration', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_4_evidence.EvidenceStage', 'enabled': True}, {'name': 'Pruning and Merging', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_5_pruning_merging.PruningMergingStage', 'enabled': True}, {'name': 'Subgraph Extraction', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_6_subgraph_extraction.SubgraphExtractionStage', 'enabled': True}, {'name': 'Composition', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_7_composition.CompositionStage', 'enabled': True}, {'name': 'Reflection', 'module_path': 'adaptive_graph_of_thoughts.domain.stages.stage_8_reflection.ReflectionStage', 'enabled': True}]</code></li> <li>asr_got.layers/</li> <li>asr_got.layers.root_layer/</li> <li><code>asr_got.layers.root_layer.description</code>: <code>Core foundational layer for initial task understanding and decomposition.</code></li> <li>asr_got.layers.evidence_layer/</li> <li><code>asr_got.layers.evidence_layer.description</code>: <code>Layer primarily containing evidence nodes and their direct connections.</code></li> <li>asr_got.layers.hypothesis_analysis_layer/</li> <li><code>asr_got.layers.hypothesis_analysis_layer.description</code>: <code>Layer focused on hypothesis development, competition, and refinement.</code></li> <li>asr_got.layers.integration_synthesis_layer/</li> <li><code>asr_got.layers.integration_synthesis_layer.description</code>: <code>Layer for integrating diverse findings and synthesizing overall conclusions.</code></li> <li>mcp_settings/</li> <li><code>mcp_settings.protocol_version</code>: <code>2024-11-05</code></li> <li><code>mcp_settings.server_version</code>: <code>0.1.0</code></li> <li><code>mcp_settings.vendor_name</code>: <code>Adaptive Graph of Thoughts Development Team</code></li> <li>google_scholar/</li> <li><code>google_scholar.api_key</code>: <code>YOUR_GOOGLE_SCHOLAR_API_KEY_HERE</code></li> <li><code>google_scholar.base_url</code>: <code>https://serpapi.com/search</code></li> <li>pubmed/</li> <li><code>pubmed.api_key</code>: <code>YOUR_PUBMED_API_KEY_HERE_IF_NEEDED</code></li> <li><code>pubmed.base_url</code>: <code>https://eutils.ncbi.nlm.nih.gov/entrez/eutils/</code></li> <li><code>pubmed.email</code>: <code>your_email@example.com</code></li> <li>exa_search/</li> <li><code>exa_search.api_key</code>: <code>YOUR_EXA_SEARCH_API_KEY_HERE</code></li> <li><code>exa_search.base_url</code>: <code>https://api.exa.ai</code></li> <li><code>knowledge_domains</code>: <code>[{'name': 'Skin Immunology', 'keywords': ['skin', 'immune', 'immunology', 'dermatitis', 'psoriasis'], 'description': 'Focuses on the immune responses and mechanisms within the skin.'}, {'name': 'Dermatology', 'keywords': ['dermatology', 'skin diseases', 'cutaneous'], 'description': 'Branch of medicine dealing with the skin, hair, nails, and their diseases.'}, {'name': 'Cutaneous Malignancies', 'keywords': ['skin cancer', 'melanoma', 'lymphoma', 'carcinoma'], 'description': 'Cancers arising from the skin.'}, {'name': 'CTCL (Cutaneous T-Cell Lymphoma)', 'keywords': ['ctcl', 'mycosis fungoides', 'sezary syndrome'], 'description': 'A rare type of non-Hodgkin lymphoma that affects the skin.'}, {'name': 'Genomics', 'keywords': ['genomics', 'gene expression', 'dna', 'rna', 'sequencing'], 'description': 'Study of genomes, their structure, function, evolution, and mapping.'}, {'name': 'Microbiome', 'keywords': ['microbiome', 'microbiota', 'bacteria', 'fungi', 'virome'], 'description': 'The community of microorganisms living together in a particular habitat, including the human body.'}, {'name': 'Molecular Biology', 'keywords': ['molecular biology', 'proteins', 'enzymes', 'pathways'], 'description': 'Branch of biology that seeks to understand the molecular basis of biological activity.'}, {'name': 'Machine Learning', 'keywords': ['machine learning', 'ai', 'neural networks', 'deep learning', 'prediction'], 'description': \"Field of artificial intelligence that uses statistical techniques to give computer systems the ability to 'learn'.\"}, {'name': 'Biomedical LLMs', 'keywords': ['biomedical llm', 'medical ai', 'nlp in medicine'], 'description': 'Large language models specialized for biomedical applications.'}]</code></li> </ul>"},{"location":"extending_with_claude/","title":"Extending Adaptive Graph of Thoughts with Direct Claude API Calls","text":""},{"location":"extending_with_claude/#introduction","title":"Introduction","text":"<p>Adaptive Graph of Thoughts's ASR-GoT (Automated Scientific Reasoning - Graph of Thoughts) pipeline is designed to be modular. While many reasoning tasks can be handled by its core stages, there might be scenarios where directly leveraging a powerful Large Language Model (LLM) like Anthropic's Claude can be beneficial for specific, complex sub-tasks or to use Claude as a specialized tool within the pipeline.</p> <p>This guide outlines how to configure Adaptive Graph of Thoughts for direct Claude API calls and provides conceptual examples for integrating these calls within custom service functions or ASR-GoT stages.</p>"},{"location":"extending_with_claude/#configuration","title":"Configuration","text":"<p>To enable direct Claude API calls, you need to configure the <code>claude_api</code> section in your <code>config/settings.yaml</code> file.</p> <pre><code># config/settings.yaml (snippet)\n\n# ... other settings ...\n\n# Optional: Direct Claude API integration settings (if the app needs to call Claude API itself)\nclaude_api:\n api_key: \"env_var:CLAUDE_API_KEY\" # Recommended: Load from environment variable CLAUDE_API_KEY\n # api_key: \"your_actual_claude_api_key_here\" # Alternatively, direct input (less secure)\n default_model: \"claude-3-opus-20240229\" # Or any other Claude model you intend to use\n timeout_seconds: 120 # Timeout for API requests in seconds\n max_retries: 2 # Maximum number of retries for API requests\n</code></pre> <p>Key Configuration Fields:</p> <ul> <li><code>api_key</code> (Optional[str]):<ul> <li>Your API key for accessing the Claude API.</li> <li>Security Best Practice: It is strongly recommended to provide the API key via an environment variable named <code>CLAUDE_API_KEY</code>. The application is configured to recognize the <code>\"env_var:CLAUDE_API_KEY\"</code> string and substitute it with the actual value from the environment variable at runtime.</li> <li>Alternatively, for development or testing, you can directly paste your API key, but avoid this for production deployments.</li> <li>If not provided, any direct Claude API calls will fail.</li> </ul> </li> <li><code>default_model</code> (str):<ul> <li>The default Claude model to use for API calls (e.g., <code>\"claude-3-opus-20240229\"</code>, <code>\"claude-3-sonnet-20240229\"</code>).</li> <li>Default: <code>\"claude-3-opus-20240229\"</code></li> </ul> </li> <li><code>timeout_seconds</code> (int):<ul> <li>The timeout duration in seconds for waiting for a response from the Claude API.</li> <li>Default: <code>120</code></li> </ul> </li> <li><code>max_retries</code> (int):<ul> <li>The maximum number of times the application will attempt to retry a failed API request.</li> <li>Default: <code>2</code></li> </ul> </li> </ul> <p>If the <code>claude_api</code> section is omitted or commented out, Adaptive Graph of Thoughts will not be able to make direct calls to the Claude API. The settings loader will treat <code>settings.claude_api</code> as <code>None</code>.</p>"},{"location":"extending_with_claude/#service-function-implementation-conceptual","title":"Service Function Implementation (Conceptual)","text":"<p>You can create service functions or utility methods that encapsulate the logic for calling the Claude API. These functions can then be used by various parts of the application, such as custom ASR-GoT stages.</p> <p>Here's a conceptual example using <code>httpx</code> for asynchronous requests:</p> <pre><code># Hypothetical service function (e.g., in src/adaptive_graph_of_thoughts/services/claude_service.py)\nimport httpx\nfrom typing import Optional, Dict, Any\nfrom loguru import logger\n\n# Assuming 'settings' is the global AppSettings instance from src.adaptive_graph_of_thoughts.config\nfrom src.adaptive_graph_of_thoughts.config import settings\n\nCLAUDE_API_BASE_URL = \"https://api.anthropic.com/v1\" # Example base URL\n\nasync def call_claude_api(\n prompt: str,\n system_prompt: Optional[str] = None,\n model_override: Optional[str] = None,\n max_tokens: int = 1024,\n) -> Optional[Dict[str, Any]]:\n \"\"\"\n Makes a conceptual call to the Claude API (e.g., messages endpoint).\n \"\"\"\n if not settings.claude_api or not settings.claude_api.api_key:\n logger.error(\"Claude API settings or API key is not configured.\")\n return None\n\n api_key = settings.claude_api.api_key\n # Resolve environment variable if specified (Pydantic settings usually handle this,\n # but direct usage might need explicit resolution if not using Pydantic model directly for key)\n if api_key.startswith(\"env_var:\"):\n env_var_name = api_key.split(\":\", 1)[1]\n import os\n api_key = os.getenv(env_var_name)\n if not api_key:\n logger.error(f\"Environment variable {env_var_name} for Claude API key not set.\")\n return None\n\n model_to_use = model_override or settings.claude_api.default_model\n timeout = settings.claude_api.timeout_seconds\n # Max retries would typically be handled by the HTTP client's retry mechanism or a wrapper.\n\n headers = {\n \"x-api-key\": api_key,\n \"anthropic-version\": \"2023-06-01\", # Required header\n \"content-type\": \"application/json\"\n }\n\n messages = [{\"role\": \"user\", \"content\": prompt}]\n\n payload = {\n \"model\": model_to_use,\n \"messages\": messages,\n \"max_tokens\": max_tokens,\n }\n if system_prompt:\n payload[\"system\"] = system_prompt\n\n\n try:\n async with httpx.AsyncClient(timeout=timeout) as client:\n # Note: For production, consider more robust retry logic (e.g., with tenacity)\n # For simplicity, only one attempt is shown here. Max_retries from config is not used directly.\n response = await client.post(f\"{CLAUDE_API_BASE_URL}/messages\", headers=headers, json=payload)\n response.raise_for_status() # Raises HTTPStatusError for 4xx/5xx responses\n\n response_data = response.json()\n logger.debug(f\"Claude API response: {response_data}\")\n return response_data\n\n except httpx.HTTPStatusError as e:\n logger.error(f\"Claude API request failed with status {e.response.status_code}: {e.response.text}\")\n except httpx.RequestError as e:\n logger.error(f\"Claude API request failed: {e}\")\n except Exception as e:\n logger.error(f\"An unexpected error occurred while calling Claude API: {e}\")\n\n return None\n\n# Example Usage (conceptual):\n# async def main():\n# response = await call_claude_api(\"Explain quantum entanglement in simple terms.\")\n# if response and response.get(\"content\"):\n# print(response.get(\"content\")[0].get(\"text\"))\n# main()\n</code></pre> <p>Key points for the service function: * Reads configuration from <code>settings.claude_api</code>. * Handles API key resolution (especially if using the <code>env_var:</code> prefix manually, though Pydantic settings often handle this transparently when the <code>ClaudeAPIConfig</code> model is instantiated). * Uses an HTTP client (<code>httpx</code> in this example) to make the API call. * Sets necessary headers, including <code>x-api-key</code> and <code>anthropic-version</code>. * Sends a JSON payload appropriate for the target Claude API endpoint (e.g., <code>/v1/messages</code>). * Includes basic error handling for network issues or API errors.</p>"},{"location":"extending_with_claude/#custom-stage-example-conceptual","title":"Custom Stage Example (Conceptual)","text":"<p>A custom ASR-GoT stage can leverage the service function described above to incorporate Claude's capabilities into the reasoning pipeline.</p> <pre><code># Hypothetical custom stage (e.g., in src/adaptive_graph_of_thoughts/domain/stages/custom_claude_stage.py)\nfrom src.adaptive_graph_of_thoughts.domain.stages.base_stage import BaseStage, StageOutput\nfrom src.adaptive_graph_of_thoughts.domain.models.common_types import GoTProcessorSessionData\nfrom loguru import logger\n\n# Assuming the service function is available, e.g.:\n# from src.adaptive_graph_of_thoughts.services.claude_service import call_claude_api\n\nclass ClaudeQueryStage(BaseStage):\n stage_name = \"ClaudeQueryStage\" # Unique name for this stage type\n\n async def execute(\n self,\n current_session_data: GoTProcessorSessionData,\n ) -> StageOutput:\n \"\"\"\n Example stage that uses Claude to answer a query from the session data.\n \"\"\"\n output = StageOutput(stage_name=self.stage_name)\n\n # Get some input from the accumulated context\n # For example, a specific query or data piece generated by a previous stage\n query_for_claude = current_session_data.accumulated_context.get(\"query_for_claude\", current_session_data.query)\n\n if not query_for_claude:\n output.error_message = \"No query found for Claude in session data.\"\n logger.warning(output.error_message)\n return output\n\n logger.info(f\"[{self.stage_name}] Calling Claude API for: {query_for_claude[:100]}...\")\n\n # Conceptual: In a real implementation, call_claude_api would be imported\n # from its actual location (e.g., a services module).\n # For this example, we'll mock its existence.\n # claude_response_data = await call_claude_api(prompt=query_for_claude)\n\n # Mocked response for illustration:\n claude_response_data = { \"content\": [{\"type\": \"text\", \"text\": f\"Mocked Claude response to: {query_for_claude}\"}] }\n\n if claude_response_data and claude_response_data.get(\"content\"):\n claude_text_response = claude_response_data.get(\"content\")[0].get(\"text\")\n logger.info(f\"[{self.stage_name}] Received response from Claude.\")\n\n # Add Claude's response to the accumulated context for subsequent stages\n output.next_stage_context_update = {\n self.stage_name: { # Key results under this stage's name\n \"claude_response_text\": claude_text_response,\n \"status\": \"success\"\n }\n }\n output.summary = f\"Successfully queried Claude. Response: {claude_text_response[:100]}...\"\n else:\n output.error_message = \"Failed to get a valid response from Claude API.\"\n logger.error(f\"[{self.stage_name}] {output.error_message}\")\n output.next_stage_context_update = {\n self.stage_name: {\n \"status\": \"failure\",\n \"error_message\": output.error_message\n }\n }\n\n return output\n</code></pre> <p>Key points for the custom stage: * It inherits from <code>BaseStage</code>. * It uses the <code>current_session_data</code> to get inputs. * It calls the <code>call_claude_api</code> service function. * It processes the response and updates <code>current_session_data.accumulated_context</code> via <code>StageOutput.next_stage_context_update</code> for subsequent stages. * It provides a summary of its operation.</p> <p>To use this custom stage, you would add its configuration to the <code>pipeline_stages</code> list in <code>config/settings.yaml</code>: <pre><code># config/settings.yaml (snippet)\nasr_got:\n # ... other asr_got settings ...\n pipeline_stages:\n # ... other stages ...\n - name: \"Custom Claude Query\"\n module_path: \"src.adaptive_graph_of_thoughts.domain.stages.custom_claude_stage.ClaudeQueryStage\"\n enabled: true\n # ... other stages ...\n</code></pre></p>"},{"location":"extending_with_claude/#disclaimer","title":"Disclaimer","text":"<p>Integrating direct LLM calls like those to the Claude API is an advanced extension point. Developers should carefully consider:</p> <ul> <li>API Costs: Frequent or large-scale calls to Claude can incur significant costs. Monitor usage and optimize prompts/requests.</li> <li>Rate Limits: Be aware of Claude API rate limits and implement appropriate backoff and retry strategies (potentially more robust than the basic example).</li> <li>Latency: Direct API calls, especially synchronous ones, can add latency to the ASR-GoT pipeline. Consider asynchronous patterns or background tasks for non-critical API calls if they might block pipeline progression.</li> <li>Error Handling: Implement comprehensive error handling for API unavailability, timeouts, invalid responses, etc.</li> <li>Data Privacy and Security: Ensure that data sent to external APIs complies with privacy policies and security requirements.</li> </ul> <p>By understanding these considerations, developers can effectively extend Adaptive Graph of Thoughts's capabilities using the Claude API. ```</p>"},{"location":"getting_started/","title":"Getting Started with Adaptive Graph of Thoughts","text":"<p>This guide will help you get Adaptive Graph of Thoughts up and running, whether for local development or Docker-based deployment.</p> <p>Deployment Prerequisites</p> <p>Before running Adaptive Graph of Thoughts (either locally or via Docker if not using the provided <code>docker-compose.prod.yml</code> which includes Neo4j), ensure you have:</p> <ul> <li> <p>A running Neo4j Instance: Adaptive Graph of Thoughts requires a connection to a Neo4j graph database.</p> <ul> <li>APOC Library: The Neo4j instance must have the APOC (Awesome Procedures On Cypher) library installed. Many Cypher queries rely on APOC procedures. See the official APOC website for installation.</li> <li>Indexing: For optimal performance, ensure appropriate Neo4j indexes are created. See Neo4j Indexing Strategy for details. </li> </ul> <p>Note: The provided <code>docker-compose.yml</code> (for development) and <code>docker-compose.prod.yml</code> (for production) already include a Neo4j service with the APOC library pre-configured, satisfying this requirement when using Docker Compose.</p> </li> </ul>"},{"location":"getting_started/#core-prerequisites","title":"Core Prerequisites","text":"<ul> <li>Python 3.11+ (as specified in <code>pyproject.toml</code>)</li> <li>Poetry: For dependency management.</li> <li>Docker and Docker Compose: For containerized deployment.</li> </ul>"},{"location":"getting_started/#installation-and-setup-local-development","title":"Installation and Setup (Local Development)","text":"<ol> <li> <p>Clone the repository: <pre><code>git clone https://github.com/SaptaDey/Adaptive-Graph-of-Thoughts-MCP.git # Adjust if your fork/repo is different\ncd Adaptive-Graph-of-Thoughts-MCP\n</code></pre></p> </li> <li> <p>Install dependencies using Poetry: <pre><code>poetry install --with dev # Installs main and development dependencies\n</code></pre> This creates a virtual environment (if one isn't already activated) and installs all necessary packages.</p> </li> <li> <p>Activate the virtual environment: <pre><code>poetry shell\n</code></pre></p> </li> </ol> <p>Configure Neo4j Connection (Critical)</p> <p>Adaptive Graph of Thoughts connects to Neo4j using environment variables. See the Configuration Guide for detailed instructions on setting <code>NEO4J_URI</code>, <code>NEO4J_USER</code>, <code>NEO4J_PASSWORD</code>, and <code>NEO4J_DATABASE</code>. For local development, using a <code>.env</code> file is recommended.</p> <ol> <li> <p>Application Configuration: Other application settings are in <code>config/settings.yaml</code>. You can review and customize this file if needed. See the Configuration Guide for more details.</p> </li> <li> <p>Run the development server: Ensure your Neo4j instance is running and accessible with the configured credentials.</p> <p>If you haven't set <code>NEO4J_PASSWORD</code> in a <code>.env</code> file, you might need to provide it directly (though <code>.env</code> is preferred): <pre><code>NEO4J_PASSWORD=\"your_neo4j_password\" poetry run uvicorn src.adaptive_graph_of_thoughts.main:app --reload --host 0.0.0.0 --port 8000\n</code></pre> If using a <code>.env</code> file (recommended for all Neo4j credentials): <pre><code>poetry run uvicorn src.adaptive_graph_of_thoughts.main:app --reload --host 0.0.0.0 --port 8000\n</code></pre> The API will be available at <code>http://localhost:8000</code> (or the port you configured, e.g., via <code>APP_PORT</code> in your <code>.env</code> file).</p> </li> </ol>"},{"location":"getting_started/#docker-deployment","title":"Docker Deployment","text":"<p>Adaptive Graph of Thoughts is designed to be easily deployed using Docker.</p> <p>B[\ud83d\udc33 Docker Compose] end</p> <pre><code>subgraph \"Container Orchestration\"\n B --> C[\ud83d\udce6 Adaptive Graph of Thoughts Container]\n B --> D[\ud83d\udcca Monitoring Container] # Placeholder if you add monitoring\n B --> E[\ud83d\uddc4\ufe0f Database Container]\nend\n\nsubgraph \"Adaptive Graph of Thoughts Application\"\n C --> F[\u26a1 FastAPI Server]\n F --> G[\ud83e\udde0 ASR-GoT Engine]\n F --> H[\ud83d\udd0c MCP Protocol]\nend\n\nsubgraph \"External Integrations\"\n H --> I[\ud83e\udd16 Claude Desktop]\n H --> J[\ud83d\udd17 Other AI Clients]\nend\n</code></pre> <p>``` --></p>"},{"location":"getting_started/#1-quick-start-with-docker-compose-recommended-for-development","title":"1. Quick Start with Docker Compose (Recommended for Development)","text":"<p>The <code>docker-compose.yml</code> file is pre-configured for local development and includes the Adaptive Graph of Thoughts API service and a Neo4j service with APOC.</p> <p><pre><code># Build and run all services\ndocker-compose up --build\n\n# For detached mode (background)\ndocker-compose up --build -d\n\n# View logs for the API service\ndocker-compose logs -f adaptive-graph-of-thoughts-api\n</code></pre> Ensure you have a <code>.env</code> file with your <code>NEO4J_PASSWORD</code> (and other Neo4j settings if not using defaults) as <code>docker-compose.yml</code> is set up to use it.</p>"},{"location":"getting_started/#2-individual-docker-container-manual-run","title":"2. Individual Docker Container (Manual Run)","text":"<p><pre><code># Build the image\ndocker build -t adaptive-graph-of-thoughts:latest .\n\n# Run the container (ensure NEO4J_* env vars are set, e.g., via --env-file)\ndocker run -d \\\n -p 8000:8000 \\\n --env-file .env \\\n -v /path/to/your/local/config:/app/config \\\n adaptive-graph-of-thoughts:latest\n</code></pre> Replace <code>/path/to/your/local/config</code> with the actual path to your custom configuration directory if you need to override the defaults baked into the image. See the Configuration Guide for more details.</p>"},{"location":"getting_started/#3-production-deployment","title":"3. Production Deployment","text":"<p>For production, use the <code>docker-compose.prod.yml</code> file: <pre><code># Ensure all required environment variables (especially NEO4J_PASSWORD) are set\n# in your production environment or a secure .env file used by the compose file.\ndocker-compose -f docker-compose.prod.yml up --build -d\n</code></pre> Refer to the Production Configuration section in the Configuration Guide for details on required environment variables.</p>"},{"location":"getting_started/#notes-on-specific-deployment-platforms","title":"Notes on Specific Deployment Platforms","text":"<ul> <li>Smithery.ai: Deploy using the provided <code>smithery.yaml</code>.<ul> <li>Connect your repository on Smithery and click Deploy.</li> <li>The container listens on the <code>PORT</code> environment variable (default <code>8000</code>).</li> <li>Health Checks use the <code>/health</code> endpoint.</li> <li>Configure required environment variables (e.g. <code>NEO4J_PASSWORD</code>) through the Smithery dashboard.</li> </ul> </li> </ul>"},{"location":"getting_started/#accessing-the-services-after-deployment","title":"Accessing the Services (after deployment)","text":"<ul> <li>API Documentation (Swagger UI): <code>http://localhost:8000/docs</code></li> <li>Health Check: <code>http://localhost:8000/health</code></li> <li>MCP Endpoint: <code>http://localhost:8000/mcp</code> (or the relevant service address if deployed)</li> </ul> <p>Navigate to these URLs in your browser or API client after starting the application.</p>"},{"location":"neo4j_indexing/","title":"Neo4j Indexing and Constraints Strategy for Adaptive Graph of Thoughts","text":"<p>This document outlines the recommended Neo4j indexing and constraint strategy to ensure optimal performance for the Adaptive Graph of Thoughts application. These commands are typically run manually by a database administrator or as part of an initial database setup script.</p>"},{"location":"neo4j_indexing/#rationale","title":"Rationale","text":"<p>Indexes are crucial for speeding up query performance, especially for <code>MATCH</code> operations with <code>WHERE</code> clauses on specific properties. Constraints (like uniqueness) also implicitly create indexes and ensure data integrity.</p> <p>The following recommendations are based on common query patterns observed in the Adaptive Graph of Thoughts stages.</p>"},{"location":"neo4j_indexing/#uniqueness-constraints","title":"Uniqueness Constraints","text":"<p>It's vital that node IDs are unique. The <code>id</code> property is used universally for node lookups.</p> <pre><code>// Ensures every node with the :Node label has a unique 'id' property.\n// This also creates an index on :Node(id).\nCREATE CONSTRAINT IF NOT EXISTS FOR (n:Node) REQUIRE n.id IS UNIQUE;\n</code></pre> <p>Note: All nodes created by the application currently receive the <code>:Node</code> label in addition to a more specific type label (e.g., <code>:HYPOTHESIS</code>, <code>:EVIDENCE</code>). This constraint effectively covers all application-managed nodes.</p>"},{"location":"neo4j_indexing/#node-property-indexes","title":"Node Property Indexes","text":"<p>These indexes will speed up filtering and lookups based on common properties.</p> <pre><code>// Index on the 'type' property for nodes.\n// Useful for queries that filter by n.type (e.g., pruning, some audit checks).\nCREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.type);\n\n// Index on 'metadata_impact_score' for nodes.\n// Used in pruning and potentially subgraph extraction.\nCREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.metadata_impact_score);\n\n// Index for overall confidence. Choose one of the following based on availability/usage:\n// If 'confidence_overall_avg' is reliably populated:\n// CREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.confidence_overall_avg);\n// As a common proxy if the above is not set:\nCREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.confidence_empirical_support);\n\n// Index on 'metadata_layer_id' for nodes.\n// Can be used in subgraph extraction or other layer-specific queries.\nCREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.metadata_layer_id);\n\n// Index on 'metadata_is_knowledge_gap' for nodes.\n// Used in subgraph extraction and reflection audits.\nCREATE INDEX IF NOT EXISTS FOR (n:Node) ON (n.metadata_is_knowledge_gap);\n</code></pre>"},{"location":"neo4j_indexing/#label-specific-property-indexes","title":"Label-Specific Property Indexes","text":"<p>While the <code>:Node</code> indexes cover many cases, indexes on properties within specific types can be beneficial if those types are frequently queried with those property filters.</p> <pre><code>// Index on 'metadata_query_context' for :ROOT nodes.\n// Speeds up the initial root node lookup in Stage 1.\nCREATE INDEX IF NOT EXISTS FOR (r:ROOT) ON (r.metadata_query_context);\n</code></pre>"},{"location":"neo4j_indexing/#relationship-property-indexes-optional","title":"Relationship Property Indexes (Optional)","text":"<p>Indexing relationship properties is less common than node properties but can be beneficial for queries that scan many relationships based on a property.</p> <pre><code>// Optional: Index on the 'confidence' property of relationships.\n// May improve performance of edge pruning in Stage 5 if the graph has a vast number of relationships.\n// CREATE INDEX IF NOT EXISTS FOR ()-[r]-() ON (r.confidence);\n</code></pre>"},{"location":"neo4j_indexing/#applying-indexes","title":"Applying Indexes","text":"<p>These Cypher commands can be executed directly in the Neo4j Browser or via a Cypher shell. It's generally safe to run <code>CREATE INDEX IF NOT EXISTS</code> or <code>CREATE CONSTRAINT IF NOT EXISTS</code> multiple times; they will only create the index/constraint if it doesn't already exist.</p> <p>Building indexes can take time on large databases. It's recommended to apply them during a maintenance window if the database is already heavily populated. For new databases, apply them after the initial schema setup.</p>"},{"location":"status_info/","title":"Status Page Information","text":"<p>The <code>status.html</code> page, located in the root of the repository, provides a simple, standalone HTML interface for interacting with a running Adaptive Graph of Thoughts server.</p>"},{"location":"status_info/#features","title":"Features","text":"<ul> <li>Server Status Check: Quickly verify if the Adaptive Graph of Thoughts MCP server is running and accessible.</li> <li>Basic Query Interface: Allows sending a query string and parameters (as JSON) to the <code>asr_got.query</code> MCP method.</li> <li>View Responses: Displays the JSON response received from the server.</li> </ul>"},{"location":"status_info/#usage","title":"Usage","text":"<ol> <li>Ensure your Adaptive Graph of Thoughts server is running locally (e.g., via <code>poetry run uvicorn src.adaptive_graph_of_thoughts.main:app --reload</code>).</li> <li>Open the <code>status.html</code> file directly in your web browser (e.g., <code>file:///path/to/your/Adaptive Graph of Thoughts-2.0/status.html</code>).</li> <li>The page will typically attempt to connect to the server at <code>http://localhost:8000/mcp</code>.</li> <li>Use the form to send test queries.</li> </ol> <p>Note: This page makes direct HTTP requests from your browser to the local server. It's intended for development and testing purposes. It does not require MkDocs to run and is not part of the generated documentation site in the same way as these Markdown files.</p>"},{"location":"usage/","title":"Using Adaptive Graph of Thoughts","text":"<p>This section describes how to interact with the Adaptive Graph of Thoughts application, primarily through its API, and details on session handling and testing.</p>"},{"location":"usage/#api-endpoints","title":"API Endpoints","text":"<p>Adaptive Graph of Thoughts exposes its functionalities via a FastAPI backend. The primary interaction points are:</p>"},{"location":"usage/#mcp-protocol-endpoint","title":"MCP Protocol Endpoint","text":"<ul> <li>Endpoint: <code>/mcp</code> (supports <code>GET</code>, <code>POST</code>, and <code>DELETE</code>)</li> <li>Description: This is the main endpoint for communication with Model Context Protocol (MCP) clients like Claude Desktop. It handles JSON-RPC requests for various methods defined by the ASR-GoT framework.</li> <li>Example Request (<code>asr_got.query</code> method): <pre><code>{\n \"jsonrpc\": \"2.0\",\n \"method\": \"asr_got.query\",\n \"params\": {\n \"query\": \"Analyze the relationship between microbiome diversity and cancer progression.\",\n \"parameters\": {\n \"include_reasoning_trace\": true,\n \"include_graph_state\": false\n }\n },\n \"id\": \"123\"\n}\n</code></pre></li> <li>Supported MCP Methods:<ul> <li><code>initialize</code>: To initialize the connection with the MCP server.</li> <li><code>asr_got.query</code>: To submit a query for processing through the ASR-GoT pipeline.</li> <li><code>shutdown</code>: To signal the server to prepare for shutdown.</li> </ul> </li> </ul>"},{"location":"usage/#health-check-endpoint","title":"Health Check Endpoint","text":"<ul> <li>Endpoint: <code>GET /health</code></li> <li>Description: Provides a simple health status of the application, indicating if it's running and accessible.</li> <li>Example Response: <pre><code>{\n \"status\": \"healthy\",\n \"version\": \"0.1.0\" \n}\n</code></pre></li> </ul>"},{"location":"usage/#api-documentation-swagger-ui","title":"API Documentation (Swagger UI)","text":"<ul> <li>Endpoint: <code>GET /docs</code></li> <li>Description: Access the interactive Swagger UI documentation for a detailed view of all available API endpoints, request/response schemas, and to try out the API directly from your browser.</li> </ul>"},{"location":"usage/#session-handling-session_id","title":"Session Handling (<code>session_id</code>)","text":"<p>The <code>session_id</code> parameter is available in API requests (e.g., for <code>asr_got.query</code>) and is included in responses. Its primary functions are:</p> <ul> <li>Tracking: To identify and track a single, complete query-response cycle.</li> <li>Correlation: Used for correlating progress notifications (e.g., <code>got/queryProgress</code> if implemented via Server-Sent Events or WebSockets) with the originating query.</li> </ul> <p>Current Limitations: Adaptive Graph of Thoughts does not currently support true multi-turn conversational continuity where the detailed graph state or reasoning context from a previous query is automatically loaded and reused for a follow-up query using the same <code>session_id</code>. Each query is processed independently at this time.</p>"},{"location":"usage/#future-enhancement-persistent-sessions","title":"Future Enhancement: Persistent Sessions","text":"<p>A potential future enhancement for Adaptive Graph of Thoughts is the implementation of persistent sessions. This would enable more interactive and evolving reasoning processes by allowing users to:</p> <ol> <li>Persist State: Store the generated graph state and relevant reasoning context from a query, associated with its <code>session_id</code>, likely within the Neo4j database.</li> <li>Reload State: When a new query is submitted with an existing <code>session_id</code>, the system could reload this saved state as the starting point for further processing.</li> <li>Refine and Extend: Allow the new query to interact with the loaded graph\u2014for example, by refining previous hypotheses, adding new evidence to existing structures, or exploring alternative reasoning paths based on the established context.</li> </ol> <p>This is a significant feature that could greatly enhance the interactive capabilities of Adaptive Graph of Thoughts.</p>"},{"location":"usage/#future-enhancement-asynchronous-and-parallel-stage-execution","title":"Future Enhancement: Asynchronous and Parallel Stage Execution","text":"<p>Currently, the 8 stages of the Adaptive Graph of Thoughts reasoning pipeline are executed sequentially. For complex queries or to further optimize performance, exploring asynchronous or parallel execution for certain parts of the pipeline is a potential future enhancement.</p> <p>Potential Areas for Parallelism:</p> <ul> <li>Hypothesis Generation: Hypothesis generation for different, independent dimensions could potentially be parallelized.</li> <li>Evidence Integration (Partial): The \"plan execution\" phase for different hypotheses might be performed concurrently.</li> </ul> <p>Challenges and Considerations: Implementing parallelism requires careful management of data consistency, transaction management, dependency sequencing, resource utilization, and overall complexity.</p>"},{"location":"usage/#testing-quality-assurance","title":"Testing & Quality Assurance","text":"<p>Adaptive Graph of Thoughts uses Pytest for testing, Ruff for linting and formatting, and MyPy/Pyright for type checking.</p> \ud83e\uddeaTesting \ud83d\udd0dType Checking \u2728Linting \ud83d\udccaCoverage <pre>poetry run pytest</pre> <pre>make test</pre> <pre>poetry run mypy src/</pre> <pre>poetry run pyright src/</pre> <pre>poetry run ruff check .</pre> <pre>poetry run ruff format .</pre> <pre>poetry run pytest --cov=src</pre> <pre>coverage html</pre>"},{"location":"usage/#development-commands","title":"Development Commands","text":"<pre><code># Run full test suite with coverage using Poetry\npoetry run pytest --cov=src --cov-report=html --cov-report=term\n\n# Or using Makefile for the default test run\nmake test\n\n# Run specific test categories (using poetry)\npoetry run pytest tests/unit/stages/ # Stage-specific tests\npoetry run pytest tests/integration/ # Integration tests\npoetry run pytest -k \"test_confidence\" # Tests matching pattern\n\n# Type checking and linting (can also be run via Makefile targets: make lint, make check-types)\npoetry run mypy src/ --strict # Strict type checking\npoetry run ruff check . --fix # Auto-fix linting issues\npoetry run ruff format . # Format code\n\n# Pre-commit hooks (recommended for contributors)\npoetry run pre-commit install # Install hooks\npoetry run pre-commit run --all-files # Run all hooks\n\n# See Makefile for other useful targets like 'make all-checks'.\n</code></pre>"},{"location":"usage/#quality-metrics","title":"Quality Metrics","text":"<ul> <li>Type Safety: </li> <li>Fully typed codebase with strict mypy configuration.</li> <li>Configured with <code>mypy.ini</code> and <code>pyrightconfig.json</code>.</li> <li>Code Quality:</li> <li>Aim for 95%+ test coverage.</li> <li>Automated formatting with Ruff.</li> <li>Pre-commit hooks for consistent code quality.</li> <li>Comprehensive integration tests for the 8-stage pipeline. ```</li> </ul>"},{"location":"vscode_extension/","title":"VS Code Extension","text":"<p>The <code>integrations/vscode-agot</code> folder contains a simple VS Code extension.</p> <p>Run <code>npm install</code> and press <code>F5</code> to launch an Extension Development Host. Use the Command Palette and select AGoT: Ask Graph\u2026 to send a question to the running server's <code>/nlq</code> endpoint. Results appear in a webview.</p>"},{"location":"api/mcp_api/","title":"MCP API Reference","text":"<p>This section provides details about the Model Context Protocol (MCP) API endpoints implemented by Adaptive Graph of Thoughts.</p>"},{"location":"api/mcp_api/#overview","title":"Overview","text":"<p>Adaptive Graph of Thoughts implements an MCP server to allow integration with MCP clients such as Claude Desktop. The primary endpoint for MCP communication is <code>/mcp</code>.</p> <p>This endpoint accepts <code>GET</code>, <code>POST</code>, and <code>DELETE</code> requests. Configuration values passed by Smithery are supplied as query parameters using dot notation, for example <code>GET /mcp?server.host=localhost&server.port=8080</code>.</p>"},{"location":"api/mcp_api/#methods","title":"Methods","text":"<p>The following JSON-RPC methods are supported via the <code>/mcp</code> endpoint:</p>"},{"location":"api/mcp_api/#initialize","title":"<code>initialize</code>","text":"<ul> <li>Description: Initializes the session between the MCP client and the Adaptive Graph of Thoughts server. Provides server information to the client.</li> <li>Parameters: See <code>MCPInitializeParams</code> in <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>.</li> <li>Returns: <code>MCPInitializeResult</code> (see <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>).</li> </ul>"},{"location":"api/mcp_api/#asr_gotquery","title":"<code>asr_got.query</code>","text":"<ul> <li>Description: Submits a natural language query to the Adaptive Graph of Thoughts ASR-GoT engine for processing through its 8-stage pipeline.</li> <li>Parameters: See <code>MCPASRGoTQueryParams</code> in <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>. This includes:<ul> <li><code>query</code> (str): The main query string.</li> <li><code>session_id</code> (Optional[str]): An optional session identifier.</li> <li><code>parameters</code> (Optional[<code>ASRGoTQueryExecutionParams</code>]): Parameters to control query execution, such as:<ul> <li><code>include_reasoning_trace</code> (bool): Whether to include a summary of stage outputs.</li> <li><code>include_graph_state</code> (bool): Whether to include the full graph state in the response.</li> <li>Other operational parameters specific to ASR-GoT stages.</li> </ul> </li> <li><code>context</code> (Optional[<code>ASRGoTQueryContext</code>]): Optional initial context for the query.</li> </ul> </li> <li>Returns: <code>MCPASRGoTQueryResult</code> (see <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>). This includes:<ul> <li><code>answer</code> (str): The final answer generated by the pipeline.</li> <li><code>reasoning_trace_summary</code> (Optional[str]): A summary of the reasoning steps if requested.</li> <li><code>graph_state_full</code> (Optional[<code>GraphStateSchema</code>]): The full graph state if requested.</li> <li><code>confidence_vector</code> (Optional[list[float]]): The final confidence assessment.</li> <li><code>session_id</code> (str): The session ID for this query-response cycle.</li> <li><code>execution_time_ms</code> (int): The total processing time for the query.</li> </ul> </li> </ul>"},{"location":"api/mcp_api/#shutdown","title":"<code>shutdown</code>","text":"<ul> <li>Description: Signals the server that the client session is ending and the server can prepare for shutdown or resource cleanup if necessary.</li> <li>Parameters: See <code>ShutdownParams</code> in <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>.</li> <li>Returns: <code>None</code>.</li> </ul> <p>Further details on request/response schemas can be found by examining the Pydantic models in <code>src/adaptive_graph_of_thoughts/api/schemas.py</code>.</p>"},{"location":"extending/custom_stages/","title":"Developing Custom ASR-GoT Stages","text":""},{"location":"extending/custom_stages/#introduction","title":"Introduction","text":"<p>Adaptive Graph of Thoughts's ASR-GoT (Automated Scientific Reasoning - Graph of Thoughts) pipeline is designed for modularity, allowing developers to extend its capabilities by creating custom processing stages. Each stage in the pipeline performs a specific task, transforming or analyzing the data within the <code>GoTProcessorSessionData</code> and contributing to the overall reasoning process.</p> <p>This guide provides a basic outline for developing your own custom stages.</p>"},{"location":"extending/custom_stages/#stage-structure","title":"Stage Structure","text":"<p>A custom stage should inherit from the <code>BaseStage</code> class found in <code>src.adaptive_graph_of_thoughts.domain.stages.base_stage</code>.</p> <p>Key components of a stage:</p> <ol> <li> <p><code>stage_name</code> (Static Class Attribute):</p> <ul> <li>A unique string identifier for the stage. This name is used as a key in the <code>accumulated_context</code> within <code>GoTProcessorSessionData</code> to store and retrieve results specific to this stage.</li> <li>Example: <code>stage_name = \"MyCustomAnalysisStage\"</code></li> </ul> </li> <li> <p><code>__init__(self, settings)</code>:</p> <ul> <li>The constructor can be used to accept the global application <code>settings</code> (an instance of <code>AppSettings</code> from <code>src.adaptive_graph_of_thoughts.config</code>) if your stage needs access to configuration parameters.</li> </ul> </li> <li> <p><code>async def execute(self, current_session_data: GoTProcessorSessionData) -> StageOutput:</code>:</p> <ul> <li>This is the main method where your stage's logic resides.</li> <li>It takes <code>current_session_data</code> as input, allowing access to the query, existing graph state (if applicable, though direct graph manipulation is now stage-local within Neo4j), and outputs from previous stages stored in <code>current_session_data.accumulated_context</code>.</li> <li>It must return an instance of <code>StageOutput</code> (from <code>src.adaptive_graph_of_thoughts.domain.stages.base_stage</code>).</li> </ul> </li> </ol>"},{"location":"extending/custom_stages/#stageoutput-class","title":"<code>StageOutput</code> Class","text":"<p>The <code>StageOutput</code> class is used to return results from your stage:</p> <ul> <li><code>stage_name</code> (str): The name of the stage producing this output (should match your stage's <code>stage_name</code>).</li> <li><code>status</code> (str, Optional): A simple status string (e.g., \"success\", \"failure\", \"partial_success\").</li> <li><code>summary</code> (str, Optional): A brief human-readable summary of what the stage accomplished.</li> <li><code>error_message</code> (str, Optional): If an error occurred, a message describing the error.</li> <li><code>next_stage_context_update</code> (Dict[str, Any], Optional): A dictionary containing data that should be added to or updated in the <code>GoTProcessorSessionData.accumulated_context</code>.<ul> <li>Best Practice: Store your stage's primary results under a key that matches your stage's <code>stage_name</code> to avoid conflicts with other stages. Example: <code>{\"MyCustomAnalysisStage\": {\"analysis_result\": \"...\", \"score\": 0.8}}</code></li> </ul> </li> <li><code>metrics</code> (Dict[str, Any], Optional): Any metrics collected during the stage's execution (e.g., processing time for sub-tasks, number of items processed).</li> </ul>"},{"location":"extending/custom_stages/#example-custom-stage-conceptual","title":"Example Custom Stage (Conceptual)","text":"<pre><code># src/adaptive_graph_of_thoughts/domain/stages/my_custom_stage.py (Example Path)\n\nfrom adaptive_graph_of_thoughts.domain.stages.base_stage import BaseStage, StageOutput\nfrom adaptive_graph_of_thoughts.domain.models.common_types import GoTProcessorSessionData\nfrom src.adaptive_graph_of_thoughts.config import Settings # Assuming settings are passed\nfrom loguru import logger\nclass MyCustomAnalysisStage(BaseStage):\n stage_name = \"MyCustomAnalysisStage\"\n\n def __init__(self, settings: Settings): # Pass global settings if needed\n super().__init__(settings)\n # You can access self.settings here if needed for configuration\n # e.g., self.my_custom_param = settings.asr_got.default_parameters.some_param\n\n async def execute(\n self,\n current_session_data: GoTProcessorSessionData,\n ) -> StageOutput:\n logger.info(f\"[{self.stage_name}] Starting execution for session: {current_session_data.session_id}\")\n output = StageOutput(stage_name=self.stage_name)\n\n try:\n # 1. Get necessary input from current_session_data.accumulated_context\n # For example, data from a previous stage:\n # prev_stage_output = current_session_data.accumulated_context.get(\"PreviousStageName\", {})\n # input_data = prev_stage_output.get(\"some_key\")\n\n # 2. Perform your custom logic\n # (e.g., interact with Neo4j via neo4j_utils, call external APIs, perform complex calculations)\n analysis_result = f\"Analysis of '{current_session_data.query[:20]}...' completed.\"\n custom_score = 0.75\n\n # 3. Prepare results for the next stage or final output\n output.next_stage_context_update = {\n self.stage_name: {\n \"processed_data\": analysis_result,\n \"custom_score\": custom_score,\n \"status\": \"success\"\n }\n }\n output.summary = f\"Successfully analyzed data. Score: {custom_score}\"\n output.status = \"success\"\n logger.info(f\"[{self.stage_name}] Execution successful.\")\n\n except Exception as e:\n error_msg = f\"Error during {self.stage_name}: {str(e)}\"\n logger.error(error_msg)\n output.error_message = error_msg\n output.status = \"failure\"\n output.next_stage_context_update = {\n self.stage_name: {\n \"status\": \"failure\",\n \"error_details\": error_msg\n }\n }\n\n return output\n</code></pre>"},{"location":"extending/custom_stages/#integrating-your-custom-stage","title":"Integrating Your Custom Stage","text":"<ol> <li>Place your stage file in a suitable location (e.g., within <code>src/adaptive_graph_of_thoughts/domain/stages/</code> or a new subdirectory for custom/plugin stages).</li> <li>Configure the pipeline in <code>config/settings.yaml</code> to include your stage: <pre><code># config/settings.yaml (snippet)\nasr_got:\n # ...\n pipeline_stages:\n # ... other stages ...\n - name: \"My Custom Analysis\" # Friendly name for your stage\n module_path: \"src.adaptive_graph_of_thoughts.domain.stages.my_custom_stage.MyCustomAnalysisStage\" # Adjust path as needed\n enabled: true\n # ... other stages ...\n</code></pre></li> <li>Ensure your stage's <code>module_path</code> is correct and the class name matches.</li> </ol>"},{"location":"extending/custom_stages/#best-practices","title":"Best Practices","text":"<ul> <li>Idempotency: If possible, design stages to be idempotent, meaning running them multiple times with the same input produces the same result.</li> <li>Error Handling: Implement robust error handling within your stage and populate <code>StageOutput.error_message</code> appropriately.</li> <li>Configuration: If your stage requires specific parameters, consider adding them to the <code>ASRGoTDefaultParams</code> model (in <code>config.py</code>) or a dedicated configuration model, and access them via <code>self.settings</code>.</li> <li>Logging: Use <code>loguru</code> for detailed logging within your stage to aid in debugging and monitoring.</li> <li>Testing: Write unit tests for your custom stage to ensure its logic is correct and it handles various inputs and edge cases properly.</li> </ul> <p>This placeholder guide should help you get started. Refer to the existing stages in <code>src/adaptive_graph_of_thoughts/domain/stages/</code> for more detailed examples.</p>"},{"location":"setup/neo4j_windows_wsl2_docs/","title":"Neo4j windows wsl2 docs","text":""},{"location":"setup/neo4j_windows_wsl2_docs/#accessing-neo4j-in-development-windows-with-wsl2","title":"Accessing Neo4j in Development (Windows with WSL2)","text":"<p>When running the application stack using Docker Desktop on Windows with the WSL2 backend, the Neo4j database service should be directly accessible from your Windows host environment. Modern versions of Docker Desktop handle the necessary port forwarding from <code>localhost</code> on Windows to the services running within the WSL2 containers.</p> <p>Neo4j Service Access:</p> <ul> <li> <p>Neo4j Browser: You can access the Neo4j web browser interface by navigating to: <code>http://localhost:7474</code> This interface allows you to execute Cypher queries, explore the graph visually, and manage the database.</p> </li> <li> <p>Bolt Protocol URI: For connecting to Neo4j from client applications (e.g., Python scripts using the <code>neo4j</code> driver, or other database tools), use the following Bolt URI: <code>neo4j://localhost:7687</code></p> </li> </ul> <p>Default Credentials:</p> <p>The Neo4j service is configured with default credentials in the <code>docker-compose.yml</code> file. Unless you have modified these, they are: * Username: <code>neo4j</code> * Password: <code>password</code></p> <p>You will be prompted for these when connecting via the Neo4j Browser or a Bolt client.</p> <p>Troubleshooting Connectivity:</p> <p>In most cases, accessing Neo4j via <code>localhost</code> should work seamlessly. However, if you encounter issues connecting to Neo4j on <code>localhost:7474</code> or <code>localhost:7687</code>:</p> <ol> <li>Docker Desktop Version & Settings: Ensure you are running a recent version of Docker Desktop. Older versions might have limitations with WSL2 networking. Check your Docker Desktop settings, particularly those related to WSL2 integration and networking, to ensure they are configured correctly.</li> <li>Firewall Configuration: Your Windows firewall or any third-party firewall software could potentially block the connection. Temporarily disabling the firewall (for testing purposes only) or adding explicit rules to allow traffic on ports <code>7474</code> and <code>7687</code> might help identify if this is the issue.</li> <li>Other Network Configurations: Complex network setups, VPNs, or proxy servers could interfere with localhost forwarding.</li> <li>WSL2 Port Forwarding (Fallback): In rare cases, especially with older Docker Desktop versions or specific WSL2 network configurations, <code>localhost</code> forwarding might not work as expected. If you've ruled out other causes, you might need to manually set up port forwarding from your Windows host to the WSL2 IP address for the container. This can be done using the <code>netsh interface portproxy</code> command in Windows. For detailed instructions on this, you can search online for \"WSL2 port forwarding netsh\" or similar terms. This is generally considered a last resort.</li> </ol> <p>If you continue to experience issues, consult the Docker Desktop documentation for WSL2 networking troubleshooting.</p>"},{"location":"testing/testing_strategy_and_example/","title":"Testing strategy and example","text":""},{"location":"testing/testing_strategy_and_example/#testing-strategy-outline","title":"Testing Strategy Outline","text":"<p>A comprehensive testing strategy for the refactored Neo4j-native application should cover different levels of granularity to ensure correctness and robustness.</p>"},{"location":"testing/testing_strategy_and_example/#1-unit-tests","title":"1. Unit Tests","text":"<ul> <li>Focus:<ul> <li>Test individual helper functions within each stage that do not involve direct database calls. This includes:<ul> <li>Property preparation logic (e.g., <code>_prepare_node_properties_for_neo4j</code>, <code>_prepare_edge_properties_for_neo4j</code> if they exist in stages or are moved to a utility).</li> <li>Data transformation and parsing logic (e.g., parsing JSON strings from Neo4j properties into Pydantic models if done within a stage).</li> <li>Complex business logic that determines what data to write (e.g., <code>_generate_hypothesis_content</code> in <code>HypothesisStage</code>, <code>_get_conceptual_dimensions</code> in <code>DecompositionStage</code>).</li> <li>Conditional logic within stages that determines flow based on input data (not DB state).</li> </ul> </li> </ul> </li> <li>Mocking:<ul> <li>External dependencies like LLM calls (if any) should be mocked.</li> <li>Direct Neo4j <code>execute_query</code> calls should not be part of unit tests; these are covered by integration tests. If a helper function unavoidably prepares data and then calls <code>execute_query</code>, the <code>execute_query</code> part should be mocked to assert it's called with correct parameters.</li> </ul> </li> <li>Tools:<ul> <li><code>pytest</code> (for test structure, fixtures, assertions).</li> <li><code>unittest.mock.patch</code> or <code>pytest-mock</code> (for mocking).</li> </ul> </li> </ul>"},{"location":"testing/testing_strategy_and_example/#2-integration-tests-per-stage","title":"2. Integration Tests (Per Stage)","text":"<ul> <li>Focus: Verify the direct Neo4j interaction of each refactored stage. Ensure that each stage correctly reads from and/or writes to Neo4j as per its responsibilities.</li> <li>Setup:<ul> <li>Testcontainers: Use <code>testcontainers-python</code> with the official Neo4j container (e.g., <code>Neo4jContainer</code>). This allows spinning up a clean, ephemeral Neo4j instance for each test module/suite or even per test if necessary (though per-module is often a good balance).</li> <li>Neo4j Configuration: The <code>neo4j_utils</code> module (or wherever the Neo4j driver connection is managed) must be configured to connect to the dynamically created test Neo4j instance. This typically involves:<ul> <li>Modifying the URI, user, and password used by <code>neo4j_utils</code> at runtime within the test setup (e.g., via environment variables that <code>Neo4jSettings</code> in <code>neo4j_utils</code> can pick up, or by directly patching the settings object within <code>neo4j_utils</code> for the duration of the test).</li> <li>Ensuring the Neo4j driver instance is re-initialized with the test container's details.</li> </ul> </li> </ul> </li> <li>Test Flow (Arrange, Act, Assert):<ol> <li>Arrange:<ul> <li>Before running the stage, use the Neo4j driver (connected to the test container) to populate the database with any prerequisite data specific to the test case. For example:<ul> <li>For <code>DecompositionStage</code>, ensure a root node with a specific ID and properties exists.</li> <li>For <code>HypothesisStage</code>, ensure dimension nodes (created by <code>DecompositionStage</code>) exist.</li> <li>For <code>EvidenceStage</code>, ensure hypothesis nodes exist.</li> </ul> </li> <li>Prepare <code>GoTProcessorSessionData</code> with the necessary input context for the stage being tested (e.g., <code>root_node_id</code> for <code>DecompositionStage</code>).</li> </ul> </li> <li>Act:<ul> <li>Instantiate the stage with appropriate settings.</li> <li>Execute the stage's <code>execute(current_session_data=...)</code> method.</li> </ul> </li> <li>Assert:<ul> <li>Database State: Use the Neo4j driver to query the test database.<ul> <li>Verify that the expected nodes were created/updated/deleted.</li> <li>Verify that the expected relationships were created/updated/deleted.</li> <li>Check the properties, labels of these nodes and relationships.</li> </ul> </li> <li>Stage Output:<ul> <li>Validate the <code>StageOutput</code> object returned by the <code>execute</code> method.</li> <li>Check <code>next_stage_context_update</code> for correct data being passed on (e.g., new node IDs).</li> <li>Check <code>metrics</code> for accuracy (e.g., <code>nodes_created_in_neo4j</code>).</li> </ul> </li> </ul> </li> </ol> </li> <li>Teardown:<ul> <li>Testcontainers will automatically stop and remove the Neo4j container after tests.</li> <li>Ensure any modifications to global state (like <code>neo4j_utils</code> settings) are reverted if necessary (fixtures with <code>yield</code> can handle this).</li> </ul> </li> <li>Tools:<ul> <li><code>pytest</code> (especially for fixtures and async tests if stages are async).</li> <li><code>testcontainers-python</code>.</li> <li><code>neo4j</code> Python driver (for setting up DB state and making assertions against DB).</li> </ul> </li> </ul>"},{"location":"testing/testing_strategy_and_example/#3-end-to-end-tests-gotprocessor","title":"3. End-to-End Tests (<code>GoTProcessor</code>)","text":"<ul> <li>Focus: Test the entire <code>GoTProcessor.process_query</code> flow, ensuring all Neo4j-native stages integrate correctly and produce the expected final output and database state.</li> <li>Setup:<ul> <li>Use Testcontainers for a clean Neo4j instance.</li> <li>Configure <code>neo4j_utils</code> to point to this test instance.</li> </ul> </li> <li>Test Flow:<ol> <li>Arrange:<ul> <li>Optionally, pre-populate Neo4j with any baseline data relevant for a complex scenario.</li> <li>Prepare the input query string and any <code>operational_params</code> or <code>initial_context</code>.</li> </ul> </li> <li>Act:<ul> <li>Instantiate <code>GoTProcessor</code>.</li> <li>Call <code>GoTProcessor.process_query(...)</code>.</li> </ul> </li> <li>Assert:<ul> <li>Final Database State: Query Neo4j to verify the overall graph structure created by the full pipeline (e.g., presence of root, dimensions, hypotheses, evidence, IBNs, hyperedges as expected for the input query). Check key properties.</li> <li><code>GoTProcessorSessionData</code>: Inspect the session data object returned by <code>process_query</code>.<ul> <li>Verify <code>final_answer</code> and <code>final_confidence_vector</code>.</li> <li>Check the <code>stage_outputs_trace</code> for completeness and correctness of summaries/errors per stage.</li> <li>Verify the <code>accumulated_context</code> contains expected final outputs from key stages (like <code>CompositionStage</code>'s output).</li> </ul> </li> </ul> </li> </ol> </li> <li>Tools:<ul> <li><code>pytest</code>.</li> <li><code>testcontainers-python</code>.</li> <li><code>neo4j</code> Python driver.</li> </ul> </li> </ul>"},{"location":"testing/testing_strategy_and_example/#4-dependency-management-for-tests","title":"4. Dependency Management for Tests","text":"<ul> <li>Ensure test-specific dependencies like <code>testcontainers-python</code>, <code>pytest-asyncio</code> (if using async stages), and any other relevant testing utilities are added to the project's development dependencies (e.g., in <code>pyproject.toml</code> under <code>[tool.poetry.group.test.dependencies]</code> or equivalent for other package managers).</li> </ul>"},{"location":"testing/testing_strategy_and_example/#acknowledgment-on-neo4j_utils-configuration-for-testing","title":"Acknowledgment on <code>neo4j_utils</code> Configuration for Testing:","text":"<p>The <code>neo4j_utils</code> module, due to its singleton-like nature for managing Neo4j settings and the driver, requires careful handling in a testing environment. The example integration test demonstrates a method of patching its internal settings (<code>_neo4j_settings</code>) and driver instance (<code>_driver</code>) within a pytest fixture. This allows tests to redirect Neo4j operations to a test-specific container. Alternatives include designing <code>neo4j_utils</code> to prioritize environment variables for connection details (which Testcontainers can provide) or adding an explicit re-initialization function to <code>neo4j_utils</code>. The patching approach in the example is a pragmatic way to test the current structure.</p>"},{"location":"testing/testing_strategy_and_example/#example-integration-test-for-initializationstage","title":"Example Integration Test (for <code>InitializationStage</code>)","text":"<p>{% raw %} <pre><code>import pytest\nfrom neo4j import Driver # type: ignore\nfrom testcontainers.neo4j import Neo4jContainer # type: ignore\nimport os # For potentially setting environment variables\n\nfrom src.adaptive_graph_of_thoughts.config import Settings\nfrom src.adaptive_graph_of_thoughts.domain.models.common_types import GoTProcessorSessionData\nfrom src.adaptive_graph_of_thoughts.domain.stages.stage_1_initialization import InitializationStage\n# Import the neo4j_utils module itself to allow patching/re-evaluating its globals\nfrom src.adaptive_graph_of_thoughts.domain.services import neo4j_utils\nfrom src.adaptive_graph_of_thoughts.domain.models.graph_elements import NodeType\n\n\n@pytest.fixture(scope=\"module\")\ndef settings_instance():\n \"\"\"Provides a Settings instance for tests.\"\"\"\n return Settings() # Assumes Settings() can load from a test .env or has defaults\n\n@pytest.fixture(scope=\"module\")\ndef neo4j_test_container_manager():\n \"\"\"\n Manages a Neo4j test container for the test module.\n This fixture demonstrates patching neo4j_utils internals.\n \"\"\"\n original_settings = None\n original_driver = None\n\n # Attempt to capture original state if neo4j_utils was already initialized\n if hasattr(neo4j_utils, '_neo4j_settings') and neo4j_utils._neo4j_settings is not None:\n original_settings = neo4j_utils.Neo4jSettings(\n uri=neo4j_utils._neo4j_settings.uri,\n user=neo4j_utils._neo4j_settings.user,\n password=neo4j_utils._neo4j_settings.password,\n database=neo4j_utils._neo4j_settings.database\n )\n if hasattr(neo4j_utils, '_driver') and neo4j_utils._driver is not None:\n original_driver = neo4j_utils._driver\n\n with Neo4jContainer(\"neo4j:5.18.0\") as neo4j_cont:\n # Override settings in neo4j_utils\n # Ensure _neo4j_settings exists; get_neo4j_settings() will create it if None\n current_settings_obj = neo4j_utils.get_neo4j_settings() \n\n current_settings_obj.uri = neo4j_cont.get_connection_url()\n current_settings_obj.user = \"neo4j\" # Default for container\n current_settings_obj.password = neo4j_cont.NEO4J_ADMIN_PASSWORD\n current_settings_obj.database = \"neo4j\" # Default DB in container\n\n # Force re-initialization of the driver in neo4j_utils if it was already set\n if neo4j_utils._driver is not None:\n neo4j_utils.close_neo4j_driver() # Closes and sets _driver to None\n\n # The next call to get_neo4j_driver() within tests will use these patched settings\n yield neo4j_cont\n\n # Teardown: Restore original settings and driver IF they existed\n if original_settings:\n neo4j_utils._neo4j_settings.uri = original_settings.uri\n neo4j_utils._neo4j_settings.user = original_settings.user\n neo4j_utils._neo4j_settings.password = original_settings.password\n neo4j_utils._neo4j_settings.database = original_settings.database\n else: # If it was None before, reset to None so it can be lazy-loaded again\n neo4j_utils._neo4j_settings = None\n\n if neo4j_utils._driver is not None: # If a test driver was created\n neo4j_utils.close_neo4j_driver() # Ensure it's closed\n\n # If original_driver was something, restore it (though typically it'd be None after close)\n # Forcing a clean state for subsequent modules is often best:\n neo4j_utils._driver = None\n\n\n@pytest.fixture(autouse=True)\ndef auto_use_neo4j_container_manager(neo4j_test_container_manager):\n \"\"\"Fixture to automatically apply the container manager for all tests in the module.\"\"\"\n pass\n\n\n@pytest.mark.asyncio\nasync def test_initialization_stage_creates_new_root_node(settings_instance):\n stage = InitializationStage(settings=settings_instance)\n session_data = GoTProcessorSessionData(query=\"Test query for new root\")\n\n # Driver will be configured by neo4j_test_container_manager fixture\n driver: Driver = neo4j_utils.get_neo4j_driver()\n db_name = neo4j_utils.get_neo4j_settings().database\n\n with driver.session(database=db_name) as s:\n s.run(\"MATCH (n) DETACH DELETE n\") # Clean database for this test\n\n output = await stage.execute(current_session_data=session_data)\n\n assert output.metrics[\"nodes_created_in_neo4j\"] == 1\n assert output.metrics[\"used_existing_neo4j_node\"] is False\n root_node_id = output.next_stage_context_update[InitializationStage.stage_name][\"root_node_id\"]\n assert root_node_id == \"n0\" # Default ID for new root\n\n # Verify node in Neo4j\n with driver.session(database=db_name) as s:\n result = s.run(\"MATCH (n:Node:ROOT {id: $id}) RETURN properties(n) as props, labels(n) as labels\", id=root_node_id)\n record = result.single()\n assert record is not None\n assert record[\"props\"][\"label\"] == stage.root_node_label\n assert record[\"props\"][\"metadata_query_context\"] == \"Test query for new root\"\n assert NodeType.ROOT.value in record[\"labels\"] \n assert \"Node\" in record[\"labels\"]\n\n@pytest.mark.asyncio\nasync def test_initialization_stage_uses_existing_root_node(settings_instance):\n stage = InitializationStage(settings=settings_instance)\n initial_query = \"Test query for existing root\"\n op_params = {\"initial_disciplinary_tags\": [\"physics\", \"new_tag\"]}\n session_data = GoTProcessorSessionData(query=initial_query, accumulated_context={\"operational_params\": op_params})\n\n driver: Driver = neo4j_utils.get_neo4j_driver()\n db_name = neo4j_utils.get_neo4j_settings().database\n\n existing_node_id = \"n0_existing\" # Using a different ID for existing node\n with driver.session(database=db_name) as s:\n s.run(\"MATCH (n) DETACH DELETE n\") # Clean first\n # Create the node with the ROOT label and also the specific type label via property\n s.run(f\"\"\"\n CREATE (r:Node:ROOT {{\n id: $id,\n label: \"Existing Task Understanding\",\n type: \"{NodeType.ROOT.value}\", \n metadata_query_context: $query,\n metadata_disciplinary_tags: [\"general\", \"physics\"] \n }})\n \"\"\", id=existing_node_id, query=initial_query)\n\n output = await stage.execute(current_session_data=session_data)\n\n assert output.metrics[\"nodes_created_in_neo4j\"] == 0\n assert output.metrics[\"used_existing_neo4j_node\"] is True\n assert output.metrics.get(\"updated_existing_node_tags\", False) is True \n\n root_node_id_from_output = output.next_stage_context_update[InitializationStage.stage_name][\"root_node_id\"]\n assert root_node_id_from_output == existing_node_id\n\n updated_tags_from_output = output.next_stage_context_update[InitializationStage.stage_name][\"initial_disciplinary_tags\"]\n assert \"general\" in updated_tags_from_output\n assert \"physics\" in updated_tags_from_output\n assert \"new_tag\" in updated_tags_from_output\n\n # Verify tags in Neo4j\n with driver.session(database=db_name) as s:\n result = s.run(\"MATCH (n:Node:ROOT {id: $id}) RETURN n.metadata_disciplinary_tags AS tags\", id=existing_node_id)\n record = result.single()\n assert record is not None\n assert \"general\" in record[\"tags\"]\n assert \"physics\" in record[\"tags\"]\n assert \"new_tag\" in record[\"tags\"]\n\n # Ensure no \"n0\" node was created if the existing one was used\n result_n0 = s.run(\"MATCH (n:Node:ROOT {id: 'n0'}) RETURN n\")\n assert result_n0.single() is None\n</code></pre> {% endraw %} This file (<code>testing_strategy_and_example.md</code>) contains the testing strategy and the example integration test. The example test has been updated to: 1. Use a module-scoped fixture <code>neo4j_test_container_manager</code> that attempts to save and restore the state of <code>neo4j_utils._neo4j_settings</code> and <code>neo4j_utils._driver</code>. This makes it more robust if <code>neo4j_utils</code> was initialized before tests or by other test modules. 2. Ensure the test Neo4j database is cleaned (<code>MATCH (n) DETACH DELETE n</code>) before each relevant test execution to ensure test isolation. 3. Explicitly use the database name from <code>neo4j_utils.get_neo4j_settings().database</code> when opening sessions, which defaults to \"neo4j\" for the container. 4. The existing node in the second test uses <code>id: \"n0_existing\"</code> to avoid collision if the stage accidentally creates \"n0\". 5. Assert that the default \"n0\" node is not created when an existing node is used. 6. The <code>auto_use_neo4j_container_manager</code> fixture ensures that the container setup and teardown logic is applied for all tests within the module where this fixture is defined or imported.</p> <p>The test file would typically reside in a path like <code>tests/integration/stages/test_integration_initialization_stage.py</code>. The <code>neo4j_utils</code> module's singleton pattern for driver and settings management makes testing a bit more involved regarding setup/teardown of this global state. The fixture tries to handle this gracefully. The use of <code>pytest-asyncio</code> would be necessary to run these <code>async def</code> tests (e.g., by installing it and <code>pytest</code> running normally). The <code>Neo4jContainer</code> version is specified as \"neo4j:5.18.0\" as an example; it should match a version compatible with the application's Cypher queries and features (like APOC if used by other stages). The <code>type: ignore</code> comments are for <code>testcontainers</code> as it might not have perfect type hints recognized by all static analyzers immediately. The <code>neo4j_utils._NEO4J_SETTINGS.uri = original_uri</code> line in the previous version of the test was incorrect as <code>_NEO4J_SETTINGS</code> is the Pydantic model instance itself, so its attributes should be set directly. This has been corrected in this version. Also corrected setting <code>neo4j_utils._neo4j_settings</code> to <code>None</code> if it was <code>None</code> originally, to ensure proper lazy loading behavior is restored. Final check of <code>test_initialization_stage_uses_existing_root_node</code>: the node creation query was updated to ensure the <code>ROOT</code> label is applied, and <code>type</code> property is set for consistency with how <code>InitializationStage</code> creates new nodes. The <code>neo4j_test_container_manager</code> fixture now correctly captures the original settings by instantiating a <code>Neo4jSettings</code> object if <code>_neo4j_settings</code> was initially <code>None</code>, ensuring that defaults are captured before patching.The file <code>testing_strategy_and_example.md</code> has been created with the testing strategy outline and the example integration test for <code>InitializationStage</code>.</p> <p>The testing strategy covers: 1. Unit Tests: Focusing on helper functions within stages, mocking external dependencies and Neo4j calls. 2. Integration Tests (Per Stage): Verifying direct Neo4j interactions using Testcontainers for ephemeral Neo4j instances. This involves an Arrange-Act-Assert pattern where the database state and stage output are checked. 3. End-to-End Tests (<code>GoTProcessor</code>): Testing the full processing pipeline with Neo4j-native stages, verifying the final database state and the overall output from <code>GoTProcessor</code>. 4. Dependency Management: Noting the need for test-specific dependencies. 5. Acknowledgment on <code>neo4j_utils</code> Configuration: Highlighting the need to manage the singleton-like nature of <code>neo4j_utils</code> for test isolation, with the example fixture demonstrating a patching approach.</p> <p>The example integration test for <code>InitializationStage</code> (<code>tests/integration/stages/test_integration_initialization_stage.py</code>) includes: * A module-scoped <code>pytest</code> fixture (<code>neo4j_test_container_manager</code>) using <code>testcontainers.neo4j.Neo4jContainer</code> to manage an ephemeral Neo4j database. * This fixture patches the <code>neo4j_utils._neo4j_settings</code> object and manages the <code>neo4j_utils._driver</code> instance to ensure that during the tests, the application connects to the test container. It also includes teardown logic to restore the original settings. * An <code>autouse</code> fixture to apply this container management to all tests in the module. * Two test cases for <code>InitializationStage</code>: * <code>test_initialization_stage_creates_new_root_node</code>: Verifies that a new root node (\"n0\") is created in Neo4j with correct properties and labels when no existing matching node is found. * <code>test_initialization_stage_uses_existing_root_node</code>: Pre-populates Neo4j with a root node matching the query, then verifies that the stage uses this existing node and correctly updates its disciplinary tags based on operational parameters. It also checks that a new \"n0\" node is not created in this scenario. * Database cleaning (<code>MATCH (n) DETACH DELETE n</code>) is performed before tests that require a specific initial state. * Assertions are made against both the <code>StageOutput</code> metrics/context and the actual data in the test Neo4j database.</p> <p>This fulfills the requirements of the subtask.</p>"}]}