diff --git a/.github/scripts/deploy_to_hf_space.py b/.github/scripts/deploy_to_hf_space.py new file mode 100644 index 00000000..825dc580 --- /dev/null +++ b/.github/scripts/deploy_to_hf_space.py @@ -0,0 +1,235 @@ +"""Deploy repository to Hugging Face Space, excluding unnecessary files.""" + +import os +import shutil +from pathlib import Path +from typing import Set + +from huggingface_hub import HfApi, Repository + + +def get_excluded_dirs() -> Set[str]: + """Get set of directory names to exclude from deployment.""" + return { + "docs", + "dev", + "folder", + "site", + "tests", # Optional - can be included if desired + "examples", # Optional - can be included if desired + ".git", + ".github", + "__pycache__", + ".pytest_cache", + ".mypy_cache", + ".ruff_cache", + ".venv", + "venv", + "env", + "ENV", + "node_modules", + ".cursor", + "reference_repos", + "burner_docs", + "chroma_db", + "logs", + "build", + "dist", + ".eggs", + "htmlcov", + } + + +def get_excluded_files() -> Set[str]: + """Get set of file names to exclude from deployment.""" + return { + ".pre-commit-config.yaml", + "mkdocs.yml", + "uv.lock", + "AGENTS.txt", + "CONTRIBUTING.md", + ".env", + ".env.local", + "*.local", + ".DS_Store", + "Thumbs.db", + "*.log", + ".coverage", + "coverage.xml", + } + + +def should_exclude(path: Path, excluded_dirs: Set[str], excluded_files: Set[str]) -> bool: + """Check if a path should be excluded from deployment.""" + # Check if any parent directory is excluded + for parent in path.parents: + if parent.name in excluded_dirs: + return True + + # Check if the path itself is a directory that should be excluded + if path.is_dir() and path.name in excluded_dirs: + return True + + # Check if the file name matches excluded patterns + if path.is_file(): + # Check exact match + if path.name in excluded_files: + return True + # Check pattern matches (simple wildcard support) + for pattern in excluded_files: + if "*" in pattern: + # Simple pattern matching (e.g., "*.log") + suffix = pattern.replace("*", "") + if path.name.endswith(suffix): + return True + + return False + + +def deploy_to_hf_space() -> None: + """Deploy repository to Hugging Face Space. + + Supports both user and organization Spaces: + - User Space: username/space-name + - Organization Space: organization-name/space-name + + Works with both classic tokens and fine-grained tokens. + """ + # Get configuration from environment variables + hf_token = os.getenv("HF_TOKEN") + hf_username = os.getenv("HF_USERNAME") # Can be username or organization name + space_name = os.getenv("HF_SPACE_NAME") + + if not all([hf_token, hf_username, space_name]): + raise ValueError( + "Missing required environment variables: HF_TOKEN, HF_USERNAME, HF_SPACE_NAME" + ) + + # HF_USERNAME can be either a username or organization name + # Format: {username|organization}/{space_name} + repo_id = f"{hf_username}/{space_name}" + local_dir = "hf_space" + + print(f"๐Ÿš€ Deploying to Hugging Face Space: {repo_id}") + + # Initialize HF API + api = HfApi(token=hf_token) + + # Clone or create repository + try: + repo = Repository( + local_dir=local_dir, + clone_from=repo_id, + token=hf_token, + repo_type="space", + ) + print(f"โœ… Cloned existing Space: {repo_id}") + except Exception as e: + print(f"โš ๏ธ Could not clone Space (may not exist yet): {e}") + # Create new repository + api.create_repo( + repo_id=space_name, + repo_type="space", + space_sdk="gradio", + token=hf_token, + exist_ok=True, + ) + repo = Repository( + local_dir=local_dir, + clone_from=repo_id, + token=hf_token, + repo_type="space", + ) + print(f"โœ… Created new Space: {repo_id}") + + # Get exclusion sets + excluded_dirs = get_excluded_dirs() + excluded_files = get_excluded_files() + + # Remove all existing files in HF Space (except .git) + print("๐Ÿงน Cleaning existing files...") + for item in Path(local_dir).iterdir(): + if item.name == ".git": + continue + if item.is_dir(): + shutil.rmtree(item) + else: + item.unlink() + + # Copy files from repository root + print("๐Ÿ“ฆ Copying files...") + repo_root = Path(".") + files_copied = 0 + dirs_copied = 0 + + for item in repo_root.rglob("*"): + # Skip if in .git directory + if ".git" in item.parts: + continue + + # Skip if should be excluded + if should_exclude(item, excluded_dirs, excluded_files): + continue + + # Calculate relative path + try: + rel_path = item.relative_to(repo_root) + except ValueError: + # Item is outside repo root, skip + continue + + # Skip if in excluded directory + if any(part in excluded_dirs for part in rel_path.parts): + continue + + # Destination path + dest_path = Path(local_dir) / rel_path + + # Create parent directories + dest_path.parent.mkdir(parents=True, exist_ok=True) + + # Copy file or directory + if item.is_file(): + shutil.copy2(item, dest_path) + files_copied += 1 + elif item.is_dir(): + # Directory will be created by parent mkdir, but we track it + dirs_copied += 1 + + print(f"โœ… Copied {files_copied} files and {dirs_copied} directories") + + # Commit and push changes + print("๐Ÿ’พ Committing changes...") + repo.git_add(auto_lfs_track=True) + + # Check if there are changes to commit + try: + # Try to check if repo is clean (may not be available in all versions) + if hasattr(repo, "is_repo_clean") and repo.is_repo_clean(): + print("โ„น๏ธ No changes to commit (repository is up to date)") + else: + repo.git_commit("Deploy to Hugging Face Space [skip ci]") + print("๐Ÿ“ค Pushing to Hugging Face Space...") + repo.git_push() + print("โœ… Deployment complete!") + except Exception as e: + # If check fails, try to commit anyway (will fail gracefully if no changes) + try: + repo.git_commit("Deploy to Hugging Face Space [skip ci]") + print("๐Ÿ“ค Pushing to Hugging Face Space...") + repo.git_push() + print("โœ… Deployment complete!") + except Exception as commit_error: + # If commit fails, likely no changes + if "nothing to commit" in str(commit_error).lower(): + print("โ„น๏ธ No changes to commit (repository is up to date)") + else: + print(f"โš ๏ธ Warning during commit: {commit_error}") + raise + + print(f"๐ŸŽ‰ Successfully deployed to: https://huggingface.co/spaces/{repo_id}") + + +if __name__ == "__main__": + deploy_to_hf_space() + diff --git a/.github/workflows/deploy-hf-space.yml b/.github/workflows/deploy-hf-space.yml new file mode 100644 index 00000000..5e788686 --- /dev/null +++ b/.github/workflows/deploy-hf-space.yml @@ -0,0 +1,44 @@ +name: Deploy to Hugging Face Space + +on: + push: + branches: [main] + workflow_dispatch: # Allow manual triggering + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + # No write permissions needed for GitHub repo (we're pushing to HF Space) + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + pip install --upgrade pip + pip install huggingface-hub + + - name: Deploy to Hugging Face Space + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + HF_USERNAME: ${{ secrets.HF_USERNAME }} + HF_SPACE_NAME: ${{ secrets.HF_SPACE_NAME }} + run: | + python .github/scripts/deploy_to_hf_space.py + + - name: Verify deployment + if: success() + run: | + echo "โœ… Deployment completed successfully!" + echo "Space URL: https://huggingface.co/spaces/${{ secrets.HF_USERNAME }}/${{ secrets.HF_SPACE_NAME }}" + diff --git a/dev/__init__.py b/dev/__init__.py index a894aae9..d1ee8372 100644 --- a/dev/__init__.py +++ b/dev/__init__.py @@ -3,3 +3,4 @@ + diff --git a/docs/license.md b/docs/LICENSE.md similarity index 99% rename from docs/license.md rename to docs/LICENSE.md index a1f9be9c..7a0c1fad 100644 --- a/docs/license.md +++ b/docs/LICENSE.md @@ -23,3 +23,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + diff --git a/docs/MKDOCS_IMPROVEMENTS_ASSESSMENT.md b/docs/MKDOCS_IMPROVEMENTS_ASSESSMENT.md deleted file mode 100644 index 9885f033..00000000 --- a/docs/MKDOCS_IMPROVEMENTS_ASSESSMENT.md +++ /dev/null @@ -1,642 +0,0 @@ -# MkDocs & Material UI Improvement Assessment - -## Current Configuration Analysis - -Your current `mkdocs.yml` already includes many excellent features: -- โœ… Material theme with light/dark mode toggle -- โœ… Navigation tabs, sections, expand, and top navigation -- โœ… Search with suggestions and highlighting -- โœ… Code annotation and copy buttons -- โœ… Mermaid diagram support -- โœ… Code include plugin -- โœ… Minification for performance -- โœ… Comprehensive markdown extensions - -## Recommended Improvements - -### 1. **Versioning & Multi-Version Documentation** โญ High Priority - -If you plan to maintain multiple versions or branches: - -```yaml -plugins: - - search - - mermaid2 - - codeinclude - - minify: - minify_html: true - minify_js: true - minify_css: true - - git-revision-date-localized: - enable_creation_date: true - type: timeago - # Optional: For versioning - # - versioning: - # version: ['dev', 'main'] -``` - -**Benefits**: Shows when pages were last updated, helps users understand document freshness. - -### 2. **Git Integration & Revision Information** โญ High Priority - -Add revision dates and authors to pages: - -```yaml -plugins: - - git-revision-date-localized: - enable_creation_date: true - type: timeago - fallback_to_build_date: true - - git-committers: - repository: DeepCritical/GradioDemo - branch: dev -``` - -**Benefits**: Users see when content was last updated, builds trust in documentation freshness. - -### 3. **Enhanced Navigation Features** โญ High Priority - -Add breadcrumbs and improve navigation: - -```yaml -theme: - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - navigation.indexes # Add index pages - - navigation.instant # Instant page loads - - navigation.tracking # Track scroll position - - navigation.smooth # Smooth scrolling - - search.suggest - - search.highlight - - content.code.annotate - - content.code.copy - - content.tabs.link # Link to specific tabs - - content.tooltips # Tooltips for abbreviations -``` - -**Benefits**: Better UX, easier navigation, professional feel. - -### 4. **Content Tabs for Code Examples** โญ High Priority - -Perfect for showing multiple code examples (Python, TypeScript, etc.): - -```yaml -markdown_extensions: - - pymdownx.tabbed: - alternate_style: true - combine_header_slug: true # Add this -``` - -**Usage in docs**: -````markdown -=== "Python" - ```python - def example(): - pass - ``` - -=== "TypeScript" - ```typescript - function example() {} - ``` -```` - -**Benefits**: Clean way to show multiple implementations without cluttering pages. - -### 5. **Enhanced Admonitions** โญ Medium Priority - -Add more admonition types and better styling: - -```yaml -markdown_extensions: - - admonition - - pymdownx.details - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - # Add custom admonition fences - - name: danger - class: danger - format: !!python/name:pymdownx.superfences.fence_code_format -``` - -**Usage**: -```markdown -!!! danger "Important" - This is a critical warning. -``` - -**Benefits**: Better visual hierarchy for warnings, tips, and important information. - -### 6. **Math Formula Support** โญ Medium Priority (if needed) - -If your documentation includes mathematical formulas: - -```yaml -markdown_extensions: - - pymdownx.arithmatex: - generic: true - - pymdownx.superfences: - custom_fences: - - name: math - class: arithmetic - format: !!python/name:pymdownx.superfences.fence_code_format - -extra_javascript: - - javascripts/mathjax.js - - https://polyfill.io/v3/polyfill.min.js?features=es6 - - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js -``` - -**Benefits**: Essential for scientific/technical documentation with formulas. - -### 7. **Better Code Highlighting** โญ Medium Priority - -Add more language support and better themes: - -```yaml -markdown_extensions: - - pymdownx.highlight: - anchor_linenums: true - line_spans: __span - pygments_lang_class: true - use_pygments: true - noclasses: false # Use CSS classes instead of inline styles -``` - -**Benefits**: Better syntax highlighting, more language support. - -### 8. **Social Links Enhancement** โญ Low Priority - -Add more social platforms and better icons: - -```yaml -extra: - social: - - icon: fontawesome/brands/github - link: https://github.com/DeepCritical/GradioDemo - name: GitHub - - icon: fontawesome/brands/twitter - link: https://twitter.com/yourhandle - name: Twitter - - icon: material/web - link: https://huggingface.co/spaces/DataQuests/DeepCritical - name: HuggingFace Space - - icon: fontawesome/brands/discord - link: https://discord.gg/yourserver - name: Discord -``` - -**Benefits**: Better community engagement, more ways to connect. - -### 9. **Analytics Integration** โญ Medium Priority - -Add privacy-respecting analytics: - -```yaml -extra: - analytics: - provider: google - property: G-XXXXXXXXXX - # Or use privacy-focused alternative: - # analytics: - # provider: plausible - # domain: yourdomain.com -``` - -**Benefits**: Understand how users interact with your documentation. - -### 10. **Custom CSS/JS for Branding** โญ Low Priority - -Add custom styling: - -```yaml -extra_css: - - stylesheets/extra.css - -extra_javascript: - - javascripts/extra.js -``` - -**Benefits**: Customize appearance, add interactive features. - -### 11. **Better Table of Contents** โญ Medium Priority - -Enhance TOC with more options: - -```yaml -markdown_extensions: - - toc: - permalink: true - permalink_title: "Anchor link to this section" - baselevel: 1 - toc_depth: 3 - slugify: !!python/object/apply:pymdownx.slugs.slugify - kwds: - case: lower -``` - -**Benefits**: Better navigation within long pages, SEO-friendly anchor links. - -### 12. **Image Optimization** โญ Medium Priority - -Add image handling plugin: - -```yaml -plugins: - - search - - mermaid2 - - codeinclude - - minify: - minify_html: true - minify_js: true - minify_css: true - - git-revision-date-localized: - enable_creation_date: true - type: timeago - # Optional: Image optimization - # - awesome-pages # For better page organization -``` - -**Benefits**: Faster page loads, better mobile experience. - -### 13. **Keyboard Shortcuts** โญ Low Priority - -Enable keyboard navigation: - -```yaml -theme: - keyboard_shortcuts: - search: true - previous: true - next: true -``` - -**Benefits**: Power users can navigate faster. - -### 14. **Print Styles** โญ Low Priority - -Better printing experience: - -```yaml -theme: - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - navigation.indexes - - navigation.instant - - navigation.tracking - - navigation.smooth - - search.suggest - - search.highlight - - content.code.annotate - - content.code.copy - - content.tabs.link - - content.tooltips - - content.action.edit # Edit button - - content.action.view # View source -``` - -**Benefits**: Users can print documentation cleanly. - -### 15. **Better Search Configuration** โญ Medium Priority - -Enhance search capabilities: - -```yaml -plugins: - - search: - lang: - - en - separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|&' - prebuild_index: true # For faster search - indexing: full # Full-text indexing -``` - -**Benefits**: Faster, more accurate search results. - -### 16. **API Documentation Enhancements** โญ High Priority (for your API docs) - -Since you have extensive API documentation, consider: - -```yaml -markdown_extensions: - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - preserve_tabs: true - # Add API-specific features - - attr_list - - md_in_html - - pymdownx.caret - - pymdownx.tilde -``` - -**Benefits**: Better formatting for API endpoints, parameters, responses. - -### 17. **Blog/News Section** โญ Low Priority (if needed) - -If you want to add a blog: - -```yaml -plugins: - - blog: - blog_dir: blog - blog_description: "News and updates" - post_date_format: full - post_url_format: '{slug}' - archive: true -``` - -**Benefits**: Keep users updated with changelog, announcements. - -### 18. **Tags and Categories** โญ Low Priority - -Organize content with tags: - -```yaml -markdown_extensions: - - meta -``` - -Then in frontmatter: -```markdown ---- -tags: - - api - - agents - - getting-started ---- -``` - -**Benefits**: Better content organization, related content discovery. - -### 19. **Better Mobile Experience** โญ High Priority - -Ensure mobile optimization: - -```yaml -theme: - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - navigation.instant # Helps on mobile - - navigation.tracking - - navigation.smooth - - search.suggest - - search.highlight - - content.code.annotate - - content.code.copy - - content.tabs.link - - content.tooltips - - toc.integrate # Better mobile TOC -``` - -**Benefits**: Better experience for mobile users (growing segment). - -### 20. **Feedback Mechanism** โญ Medium Priority - -Add feedback buttons: - -```yaml -extra: - feedback: - title: "Was this page helpful?" - ratings: - - icon: material/thumb-up-outline - name: "This page was helpful" - - icon: material/thumb-down-outline - name: "This page could be improved" -``` - -**Benefits**: Understand what content needs improvement. - -## Priority Recommendations - -### Immediate (High Impact, Easy Implementation) -1. โœ… **Git revision dates** - Shows content freshness -2. โœ… **Enhanced navigation features** - Better UX -3. โœ… **Content tabs** - Perfect for code examples -4. โœ… **Better search configuration** - Faster search - -### Short-term (High Impact, Medium Effort) -5. โœ… **API documentation enhancements** - Better API docs -6. โœ… **Enhanced admonitions** - Better visual hierarchy -7. โœ… **Mobile optimization** - Better mobile experience -8. โœ… **Analytics** - Understand user behavior - -### Long-term (Nice to Have) -9. โš ๏ธ **Versioning** - If you need multiple versions -10. โš ๏ธ **Math formulas** - If you have mathematical content -11. โš ๏ธ **Blog section** - If you want to publish updates -12. โš ๏ธ **Custom CSS/JS** - For advanced customization - -## Implementation Example - -Here's an enhanced `mkdocs.yml` with the high-priority improvements: - -```yaml -site_name: The DETERMINATOR -site_description: Generalist Deep Research Agent that Stops at Nothing -site_author: The DETERMINATOR Team -site_url: https://deepcritical.github.io/GradioDemo/ - -repo_name: DeepCritical/GradioDemo -repo_url: https://github.com/DeepCritical/GradioDemo -edit_uri: edit/dev/docs/ - -strict: false - -theme: - name: material - palette: - - scheme: default - primary: orange - accent: red - toggle: - icon: material/brightness-7 - name: Switch to dark mode - - scheme: slate - primary: orange - accent: red - toggle: - icon: material/brightness-4 - name: Switch to light mode - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - navigation.indexes - - navigation.instant - - navigation.tracking - - navigation.smooth - - search.suggest - - search.highlight - - content.code.annotate - - content.code.copy - - content.tabs.link - - content.tooltips - - toc.integrate - icon: - repo: fontawesome/brands/github - language: en - -plugins: - - search: - lang: - - en - separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|&' - prebuild_index: true - indexing: full - - mermaid2 - - codeinclude - - git-revision-date-localized: - enable_creation_date: true - type: timeago - fallback_to_build_date: true - - minify: - minify_html: true - minify_js: true - minify_css: true - -markdown_extensions: - - dev.docs_plugins: - base_path: "." - - pymdownx.highlight: - anchor_linenums: true - line_spans: __span - pygments_lang_class: true - use_pygments: true - noclasses: false - - pymdownx.inlinehilite - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - preserve_tabs: true - - pymdownx.tabbed: - alternate_style: true - combine_header_slug: true - - pymdownx.tasklist: - custom_checkbox: true - - pymdownx.emoji: - emoji_generator: !!python/name:pymdownx.emoji.to_svg - emoji_index: !!python/name:pymdownx.emoji.twemoji - - pymdownx.snippets - - admonition - - pymdownx.details - - attr_list - - md_in_html - - tables - - meta - - toc: - permalink: true - permalink_title: "Anchor link to this section" - baselevel: 1 - toc_depth: 3 - slugify: !!python/object/apply:pymdownx.slugs.slugify - kwds: - case: lower - -nav: - - Home: index.md - - Overview: - - overview/architecture.md - - overview/features.md - - Getting Started: - - getting-started/installation.md - - getting-started/quick-start.md - - getting-started/mcp-integration.md - - getting-started/examples.md - - Configuration: - - configuration/index.md - - Architecture: - - "Graph Orchestration": architecture/graph_orchestration.md - - "Workflow Diagrams": architecture/workflow-diagrams.md - - "Agents": architecture/agents.md - - "Orchestrators": architecture/orchestrators.md - - "Tools": architecture/tools.md - - "Middleware": architecture/middleware.md - - "Services": architecture/services.md - - API Reference: - - api/agents.md - - api/tools.md - - api/orchestrators.md - - api/services.md - - api/models.md - - Contributing: - - contributing/index.md - - contributing/code-quality.md - - contributing/code-style.md - - contributing/error-handling.md - - contributing/implementation-patterns.md - - contributing/prompt-engineering.md - - contributing/testing.md - - License: LICENSE.md - - Team: team.md - -extra: - social: - - icon: fontawesome/brands/github - link: https://github.com/DeepCritical/GradioDemo - name: GitHub - - icon: material/web - link: https://huggingface.co/spaces/DataQuests/DeepCritical - name: HuggingFace Space - version: - provider: mike - generator: - enabled: false - -copyright: Copyright © 2024 DeepCritical Team -``` - -## Additional Documentation Improvements - -### Content Structure -1. **Add a changelog page** - Keep users informed of updates -2. **Add a FAQ section** - Address common questions -3. **Add a glossary** - Define technical terms -4. **Add a troubleshooting guide** - Help users solve common issues -5. **Add video tutorials** - Embed videos for complex topics - -### Visual Enhancements -1. **Add diagrams** - Use more Mermaid diagrams for complex flows -2. **Add screenshots** - Visual guides for UI features -3. **Add code examples** - More practical examples -4. **Add comparison tables** - Compare different approaches/options - -### SEO & Discoverability -1. **Add meta descriptions** - Better search engine results -2. **Add Open Graph tags** - Better social media sharing -3. **Add sitemap** - Help search engines index your docs -4. **Add robots.txt** - Control search engine crawling - -## Next Steps - -1. Review this assessment -2. Prioritize features based on your needs -3. Test changes in a branch -4. Gather user feedback -5. Iterate and improve - -## Resources - -- [MkDocs User Guide](https://www.mkdocs.org/user-guide/) -- [Material for MkDocs Documentation](https://squidfunk.github.io/mkdocs-material/) -- [Material for MkDocs Reference](https://squidfunk.github.io/mkdocs-material/reference/) -- [MkDocs Plugins](https://github.com/mkdocs/mkdocs/wiki/MkDocs-Plugins) - diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 3e51d5c5..00000000 --- a/examples/README.md +++ /dev/null @@ -1,184 +0,0 @@ -# The DETERMINATOR Examples - -**NO MOCKS. NO FAKE DATA. REAL SCIENCE.** - -These demos run the REAL deep research pipeline with actual API calls. - ---- - -## Prerequisites - -You MUST have API keys configured: - -```bash -# Copy the example and add your keys -cp .env.example .env - -# Required (pick one): -OPENAI_API_KEY=sk-... -ANTHROPIC_API_KEY=sk-ant-... - -# Optional (higher PubMed rate limits): -NCBI_API_KEY=your-key -``` - ---- - -## Examples - -### 1. Search Demo (No LLM Required) - -Demonstrates REAL parallel search across PubMed, ClinicalTrials.gov, and Europe PMC. - -```bash -uv run python examples/search_demo/run_search.py "metformin cancer" -``` - -**What's REAL:** -- Actual NCBI E-utilities API calls (PubMed) -- Actual ClinicalTrials.gov API calls -- Actual Europe PMC API calls (includes preprints) -- Real papers, real trials, real preprints - ---- - -### 2. Embeddings Demo (No LLM Required) - -Demonstrates REAL semantic search and deduplication. - -```bash -uv run python examples/embeddings_demo/run_embeddings.py -``` - -**What's REAL:** -- Actual sentence-transformers model (all-MiniLM-L6-v2) -- Actual ChromaDB vector storage -- Real cosine similarity computations -- Real semantic deduplication - ---- - -### 3. Orchestrator Demo (LLM Required) - -Demonstrates the REAL search-judge-synthesize loop. - -```bash -uv run python examples/orchestrator_demo/run_agent.py "metformin cancer" -uv run python examples/orchestrator_demo/run_agent.py "aspirin alzheimer" --iterations 5 -``` - -**What's REAL:** -- Real PubMed + ClinicalTrials + Europe PMC searches -- Real LLM judge evaluating evidence quality -- Real iterative refinement based on LLM decisions -- Real research synthesis - ---- - -### 4. Magentic Demo (OpenAI Required) - -Demonstrates REAL multi-agent coordination using Microsoft Agent Framework. - -```bash -# Requires OPENAI_API_KEY specifically -uv run python examples/orchestrator_demo/run_magentic.py "metformin cancer" -``` - -**What's REAL:** -- Real MagenticBuilder orchestration -- Real SearchAgent, JudgeAgent, HypothesisAgent, ReportAgent -- Real manager-based coordination - ---- - -### 5. Hypothesis Demo (LLM Required) - -Demonstrates REAL mechanistic hypothesis generation. - -```bash -uv run python examples/hypothesis_demo/run_hypothesis.py "metformin Alzheimer's" -uv run python examples/hypothesis_demo/run_hypothesis.py "sildenafil heart failure" -``` - -**What's REAL:** -- Real PubMed + Web search first -- Real embedding-based deduplication -- Real LLM generating Drug -> Target -> Pathway -> Effect chains -- Real knowledge gap identification - ---- - -### 6. Full-Stack Demo (LLM Required) - -**THE COMPLETE PIPELINE** - All phases working together. - -```bash -uv run python examples/full_stack_demo/run_full.py "metformin Alzheimer's" -uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" -i 3 -``` - -**What's REAL:** -1. Real PubMed + ClinicalTrials + Europe PMC evidence collection -2. Real embedding-based semantic deduplication -3. Real LLM mechanistic hypothesis generation -4. Real LLM evidence quality assessment -5. Real LLM structured scientific report generation - -Output: Publication-quality research report with validated citations. - ---- - -## API Key Requirements - -| Example | LLM Required | Keys | -|---------|--------------|------| -| search_demo | No | Optional: `NCBI_API_KEY` | -| embeddings_demo | No | None | -| orchestrator_demo | Yes | `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` | -| run_magentic | Yes | `OPENAI_API_KEY` (Magentic requires OpenAI) | -| hypothesis_demo | Yes | `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` | -| full_stack_demo | Yes | `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` | - ---- - -## Architecture - -```text -User Query - | - v -[REAL Search] --> PubMed + ClinicalTrials + Europe PMC APIs - | - v -[REAL Embeddings] --> Actual sentence-transformers - | - v -[REAL Hypothesis] --> Actual LLM reasoning - | - v -[REAL Judge] --> Actual LLM assessment - | - +---> Need more? --> Loop back to Search - | - +---> Sufficient --> Continue - | - v -[REAL Report] --> Actual LLM synthesis - | - v -Publication-Quality Research Report -``` - ---- - -## Why No Mocks? - -> "Authenticity is the feature." - -Mocks belong in `tests/unit/`, not in demos. When you run these examples, you see: -- Real papers from real databases -- Real AI reasoning about real evidence -- Real scientific hypotheses -- Real research reports - -This is what The DETERMINATOR actually does. No fake data. No canned responses. diff --git a/examples/embeddings_demo/run_embeddings.py b/examples/embeddings_demo/run_embeddings.py deleted file mode 100644 index 26ba4d37..00000000 --- a/examples/embeddings_demo/run_embeddings.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Semantic Search & Deduplication (Phase 6). - -This script demonstrates embedding-based capabilities using REAL data: -- Fetches REAL abstracts from PubMed -- Embeds text with sentence-transformers -- Performs semantic deduplication on LIVE research data - -Usage: - uv run python examples/embeddings_demo/run_embeddings.py -""" - -import asyncio - -from src.services.embeddings import EmbeddingService -from src.tools.pubmed import PubMedTool - - -def create_fresh_service(name_suffix: str = "") -> EmbeddingService: - """Create a fresh embedding service with unique collection name.""" - import uuid - - # Create service with unique collection by modifying the internal collection - service = EmbeddingService.__new__(EmbeddingService) - service._model = __import__("sentence_transformers").SentenceTransformer("all-MiniLM-L6-v2") - service._client = __import__("chromadb").Client() - collection_name = f"demo_{name_suffix}_{uuid.uuid4().hex[:8]}" - service._collection = service._client.create_collection( - name=collection_name, metadata={"hnsw:space": "cosine"} - ) - return service - - -async def demo_real_pipeline() -> None: - """Run the demo using REAL PubMed data.""" - print("\n" + "=" * 60) - print("DeepCritical Embeddings Demo (REAL DATA)") - print("=" * 60) - - # 1. Fetch Real Data - query = "metformin mechanism of action" - print(f"\n[1] Fetching real papers for: '{query}'...") - pubmed = PubMedTool() - # Fetch enough results to likely get some overlap/redundancy - evidence = await pubmed.search(query, max_results=10) - - print(f" Found {len(evidence)} papers.") - print("\n Sample Titles:") - for i, e in enumerate(evidence[:3], 1): - print(f" {i}. {e.citation.title[:80]}...") - - # 2. Embed Data - print("\n[2] Embedding abstracts (sentence-transformers)...") - service = create_fresh_service("real_demo") - - # 3. Semantic Search - print("\n[3] Semantic Search Demo") - print(" Indexing evidence...") - for e in evidence: - # Use URL as ID for uniqueness - await service.add_evidence( - evidence_id=e.citation.url, - content=e.content, - metadata={ - "source": e.citation.source, - "title": e.citation.title, - "date": e.citation.date, - }, - ) - - semantic_query = "activation of AMPK pathway" - print(f" Searching for concept: '{semantic_query}'") - results = await service.search_similar(semantic_query, n_results=2) - - print(" Top matches:") - for i, r in enumerate(results, 1): - similarity = 1 - r["distance"] - print(f" {i}. [{similarity:.1%} match] {r['metadata']['title'][:70]}...") - - # 4. Semantic Deduplication - print("\n[4] Semantic Deduplication Demo") - # Create a FRESH service for deduplication so we don't clash with Step 3's index - dedup_service = create_fresh_service("dedup_demo") - - print(" Checking for redundant papers (threshold=0.85)...") - - # To force a duplicate for demo purposes, let's double the evidence list - # simulating finding the same papers again or very similar ones - duplicated_evidence = evidence + evidence[:2] - print(f" Input pool: {len(duplicated_evidence)} items (with artificial duplicates added)") - - unique = await dedup_service.deduplicate(duplicated_evidence, threshold=0.85) - - print(f" Output pool: {len(unique)} unique items") - print(f" Removed {len(duplicated_evidence) - len(unique)} duplicates.") - - print("\n" + "=" * 60) - print("Demo complete! Verified with REAL PubMed data.") - print("=" * 60 + "\n") - - -if __name__ == "__main__": - asyncio.run(demo_real_pipeline()) diff --git a/examples/full_stack_demo/run_full.py b/examples/full_stack_demo/run_full.py deleted file mode 100644 index c3728df7..00000000 --- a/examples/full_stack_demo/run_full.py +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Full Stack DETERMINATOR Agent (Phases 1-8). - -This script demonstrates the COMPLETE REAL deep research pipeline: -- Phase 2: REAL Search (PubMed + ClinicalTrials + Europe PMC) -- Phase 6: REAL Embeddings (sentence-transformers + ChromaDB) -- Phase 7: REAL Hypothesis (LLM mechanistic reasoning) -- Phase 3: REAL Judge (LLM evidence assessment) -- Phase 8: REAL Report (LLM structured scientific report) - -NO MOCKS. NO FAKE DATA. REAL SCIENCE. - -Usage: - uv run python examples/full_stack_demo/run_full.py "metformin Alzheimer's" - uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" -i 3 - -Requires: OPENAI_API_KEY or ANTHROPIC_API_KEY -""" - -import argparse -import asyncio -import os -import sys -from typing import Any - -from src.utils.models import Evidence - - -def print_header(title: str) -> None: - """Print a formatted section header.""" - print(f"\n{'=' * 70}") - print(f" {title}") - print(f"{'=' * 70}\n") - - -def print_step(step: int, name: str) -> None: - """Print a step indicator.""" - print(f"\n[Step {step}] {name}") - print("-" * 50) - - -_MAX_DISPLAY_LEN = 600 - - -def _print_truncated(text: str) -> None: - """Print text, truncating if too long.""" - if len(text) > _MAX_DISPLAY_LEN: - print(text[:_MAX_DISPLAY_LEN] + "\n... [truncated for display]") - else: - print(text) - - -async def _run_search_iteration( - query: str, - iteration: int, - evidence_store: dict[str, Any], - all_evidence: list[Evidence], - search_handler: Any, - embedding_service: Any, -) -> list[Evidence]: - """Run a single search iteration with deduplication.""" - search_queries = [query] - if evidence_store.get("hypotheses"): - for h in evidence_store["hypotheses"][-2:]: - search_queries.extend(h.search_suggestions[:1]) - - for q in search_queries[:2]: - result = await search_handler.execute(q, max_results_per_tool=5) - print(f" '{q}' -> {result.total_found} results") - new_unique = await embedding_service.deduplicate(result.evidence) - print(f" After dedup: {len(new_unique)} unique") - all_evidence.extend(new_unique) - - evidence_store["current"] = all_evidence - evidence_store["iteration_count"] = iteration - return all_evidence - - -async def _handle_judge_step( - judge_handler: Any, query: str, all_evidence: list[Evidence], evidence_store: dict[str, Any] -) -> tuple[bool, str]: - """Handle the judge assessment step. Returns (should_stop, next_query).""" - print("\n[Judge] Assessing evidence quality (REAL LLM)...") - assessment = await judge_handler.assess(query, all_evidence) - print(f" Mechanism Score: {assessment.details.mechanism_score}/10") - print(f" Clinical Score: {assessment.details.clinical_evidence_score}/10") - print(f" Confidence: {assessment.confidence:.0%}") - print(f" Recommendation: {assessment.recommendation.upper()}") - - if assessment.recommendation == "synthesize": - print("\n[Judge] Evidence sufficient! Proceeding to report generation...") - evidence_store["last_assessment"] = assessment.details.model_dump() - return True, query - - next_queries = assessment.next_search_queries[:2] if assessment.next_search_queries else [] - if next_queries: - print(f"\n[Judge] Need more evidence. Next queries: {next_queries}") - return False, next_queries[0] - - print("\n[Judge] Need more evidence but no suggested queries. Continuing with original query.") - return False, query - - -async def run_full_demo(query: str, max_iterations: int) -> None: - """Run the REAL full stack pipeline.""" - print_header("DeepCritical Full Stack Demo (REAL)") - print(f"Query: {query}") - print(f"Max iterations: {max_iterations}") - print("Mode: REAL (All live API calls - no mocks)\n") - - # Import real components - from src.agent_factory.judges import JudgeHandler - from src.agents.hypothesis_agent import HypothesisAgent - from src.agents.report_agent import ReportAgent - from src.services.embeddings import EmbeddingService - from src.tools.clinicaltrials import ClinicalTrialsTool - from src.tools.europepmc import EuropePMCTool - from src.tools.pubmed import PubMedTool - from src.tools.search_handler import SearchHandler - - # Initialize REAL services - print("[Init] Loading embedding model...") - embedding_service = EmbeddingService() - search_handler = SearchHandler( - tools=[PubMedTool(), ClinicalTrialsTool(), EuropePMCTool()], timeout=30.0 - ) - judge_handler = JudgeHandler() - - # Shared evidence store - evidence_store: dict[str, Any] = {"current": [], "hypotheses": [], "iteration_count": 0} - all_evidence: list[Evidence] = [] - - for iteration in range(1, max_iterations + 1): - print_step(iteration, f"ITERATION {iteration}/{max_iterations}") - - # Step 1: REAL Search - print("\n[Search] Querying PubMed + ClinicalTrials + Europe PMC (REAL API calls)...") - all_evidence = await _run_search_iteration( - query, iteration, evidence_store, all_evidence, search_handler, embedding_service - ) - - if not all_evidence: - print("\nNo evidence found. Try a different query.") - return - - # Step 2: REAL Hypothesis generation (first iteration only) - if iteration == 1: - print("\n[Hypothesis] Generating mechanistic hypotheses (REAL LLM)...") - hypothesis_agent = HypothesisAgent(evidence_store, embedding_service) - hyp_response = await hypothesis_agent.run(query) - _print_truncated(hyp_response.messages[0].text) - - # Step 3: REAL Judge - should_stop, query = await _handle_judge_step( - judge_handler, query, all_evidence, evidence_store - ) - if should_stop: - break - - # Step 4: REAL Report generation - print_step(iteration + 1, "REPORT GENERATION (REAL LLM)") - report_agent = ReportAgent(evidence_store, embedding_service) - report_response = await report_agent.run(query) - - print("\n" + "=" * 70) - print(" FINAL RESEARCH REPORT") - print("=" * 70) - print(report_response.messages[0].text) - - -async def main() -> None: - """Entry point.""" - parser = argparse.ArgumentParser( - description="DeepCritical Full Stack Demo - REAL, No Mocks", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -This demo runs the COMPLETE pipeline with REAL API calls: - 1. REAL search: Actual PubMed queries - 2. REAL embeddings: Actual sentence-transformers model - 3. REAL hypothesis: Actual LLM generating mechanistic chains - 4. REAL judge: Actual LLM assessing evidence quality - 5. REAL report: Actual LLM generating structured report - -Examples: - uv run python examples/full_stack_demo/run_full.py "metformin Alzheimer's" - uv run python examples/full_stack_demo/run_full.py "sildenafil heart failure" -i 3 - uv run python examples/full_stack_demo/run_full.py "aspirin cancer prevention" - """, - ) - parser.add_argument( - "query", - help="Research query (e.g., 'metformin Alzheimer's disease')", - ) - parser.add_argument( - "-i", - "--iterations", - type=int, - default=2, - help="Max search iterations (default: 2)", - ) - - args = parser.parse_args() - - if args.iterations < 1: - print("Error: iterations must be at least 1") - sys.exit(1) - - # Fail fast: require API key - if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")): - print("=" * 70) - print("ERROR: This demo requires a real LLM.") - print() - print("Set one of the following in your .env file:") - print(" OPENAI_API_KEY=sk-...") - print(" ANTHROPIC_API_KEY=sk-ant-...") - print() - print("This is a REAL demo. No mocks. No fake data.") - print("=" * 70) - sys.exit(1) - - await run_full_demo(args.query, args.iterations) - - print("\n" + "=" * 70) - print(" DeepCritical Full Stack Demo Complete!") - print(" ") - print(" Everything you just saw was REAL:") - print(" - Real PubMed + ClinicalTrials + Europe PMC searches") - print(" - Real embedding computations") - print(" - Real LLM reasoning") - print(" - Real scientific report") - print("=" * 70 + "\n") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/hypothesis_demo/run_hypothesis.py b/examples/hypothesis_demo/run_hypothesis.py deleted file mode 100644 index 65a24224..00000000 --- a/examples/hypothesis_demo/run_hypothesis.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Hypothesis Generation (Phase 7). - -This script demonstrates the REAL hypothesis generation pipeline: -1. REAL search: PubMed + ClinicalTrials + Europe PMC (actual API calls) -2. REAL embeddings: Semantic deduplication -3. REAL LLM: Mechanistic hypothesis generation - -Usage: - # Requires OPENAI_API_KEY or ANTHROPIC_API_KEY - uv run python examples/hypothesis_demo/run_hypothesis.py "metformin Alzheimer's" - uv run python examples/hypothesis_demo/run_hypothesis.py "sildenafil heart failure" -""" - -import argparse -import asyncio -import os -import sys -from typing import Any - -from src.agents.hypothesis_agent import HypothesisAgent -from src.services.embeddings import EmbeddingService -from src.tools.clinicaltrials import ClinicalTrialsTool -from src.tools.europepmc import EuropePMCTool -from src.tools.pubmed import PubMedTool -from src.tools.search_handler import SearchHandler - - -async def run_hypothesis_demo(query: str) -> None: - """Run the REAL hypothesis generation pipeline.""" - try: - print(f"\n{'=' * 60}") - print("DeepCritical Hypothesis Agent Demo (Phase 7)") - print(f"Query: {query}") - print("Mode: REAL (Live API calls)") - print(f"{'=' * 60}\n") - - # Step 1: REAL Search - print("[Step 1] Searching PubMed + ClinicalTrials + Europe PMC...") - search_handler = SearchHandler( - tools=[PubMedTool(), ClinicalTrialsTool(), EuropePMCTool()], timeout=30.0 - ) - result = await search_handler.execute(query, max_results_per_tool=5) - - print(f" Found {result.total_found} results from {result.sources_searched}") - if result.errors: - print(f" Warnings: {result.errors}") - - if not result.evidence: - print("\nNo evidence found. Try a different query.") - return - - # Step 2: REAL Embeddings - Deduplicate - print("\n[Step 2] Semantic deduplication...") - embedding_service = EmbeddingService() - unique_evidence = await embedding_service.deduplicate(result.evidence, threshold=0.85) - print(f" {len(result.evidence)} -> {len(unique_evidence)} unique papers") - - # Show what we found - print("\n[Evidence collected]") - max_title_len = 50 - for i, e in enumerate(unique_evidence[:5], 1): - raw_title = e.citation.title - if len(raw_title) > max_title_len: - title = raw_title[:max_title_len] + "..." - else: - title = raw_title - print(f" {i}. [{e.citation.source.upper()}] {title}") - - # Step 3: REAL LLM - Generate hypotheses - print("\n[Step 3] Generating mechanistic hypotheses (LLM)...") - evidence_store: dict[str, Any] = {"current": unique_evidence, "hypotheses": []} - agent = HypothesisAgent(evidence_store, embedding_service) - - print("-" * 60) - response = await agent.run(query) - print(response.messages[0].text) - print("-" * 60) - - # Show stored hypotheses - hypotheses = evidence_store.get("hypotheses", []) - print(f"\n{len(hypotheses)} hypotheses stored") - - if hypotheses: - print("\nGenerated search queries for further investigation:") - for h in hypotheses: - queries = h.to_search_queries() - print(f" {h.drug} -> {h.target}:") - for q in queries[:3]: - print(f" - {q}") - - except Exception as e: - print(f"\nโŒ Error during hypothesis generation: {e}") - raise - - -async def main() -> None: - """Entry point.""" - parser = argparse.ArgumentParser( - description="Hypothesis Generation Demo (REAL - No Mocks)", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -Examples: - uv run python examples/hypothesis_demo/run_hypothesis.py "metformin Alzheimer's" - uv run python examples/hypothesis_demo/run_hypothesis.py "sildenafil heart failure" - uv run python examples/hypothesis_demo/run_hypothesis.py "aspirin cancer prevention" - """, - ) - parser.add_argument( - "query", - nargs="?", - default="metformin Alzheimer's disease", - help="Research query", - ) - args = parser.parse_args() - - # Fail fast: require API key - if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")): - print("=" * 60) - print("ERROR: This demo requires a real LLM.") - print() - print("Set one of the following in your .env file:") - print(" OPENAI_API_KEY=sk-...") - print(" ANTHROPIC_API_KEY=sk-ant-...") - print() - print("This is a REAL demo, not a mock. No fake data.") - print("=" * 60) - sys.exit(1) - - await run_hypothesis_demo(args.query) - - print("\n" + "=" * 60) - print("Demo complete! This was a REAL pipeline:") - print(" 1. REAL search: PubMed + ClinicalTrials + Europe PMC APIs") - print(" 2. REAL embeddings: Actual sentence-transformers") - print(" 3. REAL LLM: Actual hypothesis generation") - print("=" * 60 + "\n") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/modal_demo/run_analysis.py b/examples/modal_demo/run_analysis.py deleted file mode 100644 index 82bbe7ff..00000000 --- a/examples/modal_demo/run_analysis.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -"""Demo: Modal-powered statistical analysis. - -This script uses StatisticalAnalyzer directly (NO agent_framework dependency). - -Usage: - uv run python examples/modal_demo/run_analysis.py "metformin alzheimer" -""" - -import argparse -import asyncio -import os -import sys - -from src.services.statistical_analyzer import get_statistical_analyzer -from src.tools.pubmed import PubMedTool -from src.utils.config import settings - - -async def main() -> None: - """Run the Modal analysis demo.""" - parser = argparse.ArgumentParser(description="Modal Analysis Demo") - parser.add_argument("query", help="Research query") - args = parser.parse_args() - - if not settings.modal_available: - print("Error: Modal credentials not configured.") - sys.exit(1) - - if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")): - print("Error: No LLM API key found.") - sys.exit(1) - - print(f"\n{'=' * 60}") - print("DeepCritical Modal Analysis Demo") - print(f"Query: {args.query}") - print(f"{'=' * 60}\n") - - # Step 1: Gather Evidence - print("Step 1: Gathering evidence from PubMed...") - pubmed = PubMedTool() - evidence = await pubmed.search(args.query, max_results=5) - print(f" Found {len(evidence)} papers\n") - - # Step 2: Run Modal Analysis - print("Step 2: Running statistical analysis in Modal sandbox...") - analyzer = get_statistical_analyzer() - result = await analyzer.analyze(query=args.query, evidence=evidence) - - # Step 3: Display Results - print("\n" + "=" * 60) - print("ANALYSIS RESULTS") - print("=" * 60) - print(f"\nVerdict: {result.verdict}") - print(f"Confidence: {result.confidence:.0%}") - print("\nKey Findings:") - for finding in result.key_findings: - print(f" - {finding}") - - print("\n[Demo Complete - Code executed in Modal, not locally]") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/modal_demo/test_code_execution.py b/examples/modal_demo/test_code_execution.py deleted file mode 100644 index 7addd107..00000000 --- a/examples/modal_demo/test_code_execution.py +++ /dev/null @@ -1,169 +0,0 @@ -"""Demo script to test Modal code execution integration. - -Run with: uv run python examples/modal_demo/test_code_execution.py -""" - -import sys -from pathlib import Path - -# Add src to path -sys.path.insert(0, str(Path(__file__).parent.parent.parent)) - -from src.tools.code_execution import CodeExecutionError, get_code_executor - - -def test_basic_execution(): - """Test basic code execution.""" - print("\n=== Test 1: Basic Execution ===") - executor = get_code_executor() - - code = """ -print("Hello from Modal sandbox!") -result = 2 + 2 -print(f"2 + 2 = {result}") -""" - - result = executor.execute(code) - print(f"Success: {result['success']}") - print(f"Stdout:\n{result['stdout']}") - if result["stderr"]: - print(f"Stderr:\n{result['stderr']}") - - -def test_scientific_computing(): - """Test scientific computing libraries.""" - print("\n=== Test 2: Scientific Computing ===") - executor = get_code_executor() - - code = """ -import pandas as pd -import numpy as np - -# Create sample data -data = { - 'drug': ['DrugA', 'DrugB', 'DrugC'], - 'efficacy': [0.75, 0.82, 0.68], - 'sample_size': [100, 150, 120] -} - -df = pd.DataFrame(data) - -# Calculate weighted average -weighted_avg = np.average(df['efficacy'], weights=df['sample_size']) - -print(f"Drugs tested: {len(df)}") -print(f"Weighted average efficacy: {weighted_avg:.3f}") -print("\\nDataFrame:") -print(df.to_string()) -""" - - result = executor.execute(code) - print(f"Success: {result['success']}") - print(f"Output:\n{result['stdout']}") - - -def test_statistical_analysis(): - """Test statistical analysis.""" - print("\n=== Test 3: Statistical Analysis ===") - executor = get_code_executor() - - code = """ -import numpy as np -from scipy import stats - -# Simulate two treatment groups -np.random.seed(42) -control_group = np.random.normal(100, 15, 50) -treatment_group = np.random.normal(110, 15, 50) - -# Perform t-test -t_stat, p_value = stats.ttest_ind(treatment_group, control_group) - -print(f"Control mean: {np.mean(control_group):.2f}") -print(f"Treatment mean: {np.mean(treatment_group):.2f}") -print(f"T-statistic: {t_stat:.3f}") -print(f"P-value: {p_value:.4f}") - -if p_value < 0.05: - print("Result: Statistically significant difference") -else: - print("Result: No significant difference") -""" - - result = executor.execute(code) - print(f"Success: {result['success']}") - print(f"Output:\n{result['stdout']}") - - -def test_with_return_value(): - """Test execute_with_return method.""" - print("\n=== Test 4: Return Value ===") - executor = get_code_executor() - - code = """ -import numpy as np - -# Calculate something -data = np.array([1, 2, 3, 4, 5]) -result = { - 'mean': float(np.mean(data)), - 'std': float(np.std(data)), - 'sum': int(np.sum(data)) -} -""" - - try: - result = executor.execute_with_return(code) - print(f"Returned result: {result}") - print(f"Mean: {result['mean']}") - print(f"Std: {result['std']}") - print(f"Sum: {result['sum']}") - except CodeExecutionError as e: - print(f"Error: {e}") - - -def test_error_handling(): - """Test error handling.""" - print("\n=== Test 5: Error Handling ===") - executor = get_code_executor() - - code = """ -# This will fail -x = 1 / 0 -""" - - result = executor.execute(code) - print(f"Success: {result['success']}") - print(f"Error: {result['error']}") - - -def main(): - """Run all tests.""" - print("=" * 60) - print("Modal Code Execution Demo") - print("=" * 60) - - tests = [ - test_basic_execution, - test_scientific_computing, - test_statistical_analysis, - test_with_return_value, - test_error_handling, - ] - - for test in tests: - try: - test() - except Exception as e: - print(f"\nโŒ Test failed: {e}") - import traceback - - traceback.print_exc() - - print("\n" + "=" * 60) - print("Demo completed!") - print("=" * 60) - - -if __name__ == "__main__": - main() diff --git a/examples/modal_demo/verify_sandbox.py b/examples/modal_demo/verify_sandbox.py deleted file mode 100644 index 8ac94503..00000000 --- a/examples/modal_demo/verify_sandbox.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3 -"""Verify that Modal sandbox is properly isolated. - -This script proves to judges that code runs in Modal, not locally. -NO agent_framework dependency - uses only src.tools.code_execution. - -Usage: - uv run python examples/modal_demo/verify_sandbox.py -""" - -import asyncio -from functools import partial - -from src.tools.code_execution import CodeExecutionError, get_code_executor -from src.utils.config import settings - - -def print_result(result: dict) -> None: - """Print execution result, surfacing errors when they occur.""" - if result.get("success"): - print(f" {result['stdout'].strip()}\n") - else: - error = result.get("error") or result.get("stderr", "").strip() or "Unknown error" - print(f" ERROR: {error}\n") - - -async def main() -> None: - """Verify Modal sandbox isolation.""" - if not settings.modal_available: - print("Error: Modal credentials not configured.") - print("Set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET in .env") - return - - try: - executor = get_code_executor() - loop = asyncio.get_running_loop() - - print("=" * 60) - print("Modal Sandbox Isolation Verification") - print("=" * 60 + "\n") - - # Test 1: Hostname - print("Test 1: Check hostname (should NOT be your machine)") - code1 = "import socket; print(f'Hostname: {socket.gethostname()}')" - result1 = await loop.run_in_executor(None, partial(executor.execute, code1)) - print_result(result1) - - # Test 2: Scientific libraries - print("Test 2: Verify scientific libraries") - code2 = """ -import pandas as pd -import numpy as np -import scipy -print(f"pandas: {pd.__version__}") -print(f"numpy: {np.__version__}") -print(f"scipy: {scipy.__version__}") -""" - result2 = await loop.run_in_executor(None, partial(executor.execute, code2)) - print_result(result2) - - # Test 3: Network blocked - print("Test 3: Verify network isolation") - code3 = """ -import urllib.request -try: - urllib.request.urlopen("https://google.com", timeout=2) - print("Network: ALLOWED (unexpected!)") -except Exception: - print("Network: BLOCKED (as expected)") -""" - result3 = await loop.run_in_executor(None, partial(executor.execute, code3)) - print_result(result3) - - # Test 4: Real statistics - print("Test 4: Execute statistical analysis") - code4 = """ -import pandas as pd -import scipy.stats as stats - -data = pd.DataFrame({'effect': [0.42, 0.38, 0.51]}) -mean = data['effect'].mean() -t_stat, p_val = stats.ttest_1samp(data['effect'], 0) - -print(f"Mean Effect: {mean:.3f}") -print(f"P-value: {p_val:.4f}") -print(f"Verdict: {'SUPPORTED' if p_val < 0.05 else 'INCONCLUSIVE'}") -""" - result4 = await loop.run_in_executor(None, partial(executor.execute, code4)) - print_result(result4) - - print("=" * 60) - print("All tests complete - Modal sandbox verified!") - print("=" * 60) - - except CodeExecutionError as e: - print(f"Error: Modal code execution failed: {e}") - print("Hint: Ensure Modal SDK is installed and credentials are valid.") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/orchestrator_demo/run_agent.py b/examples/orchestrator_demo/run_agent.py deleted file mode 100644 index 44e569b0..00000000 --- a/examples/orchestrator_demo/run_agent.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: DeepCritical Agent Loop (Search + Judge + Orchestrator). - -This script demonstrates the REAL Phase 4 orchestration: -- REAL Iterative Search (PubMed + ClinicalTrials + Europe PMC) -- REAL Evidence Evaluation (LLM Judge) -- REAL Orchestration Loop -- REAL Final Synthesis - -NO MOCKS. REAL API CALLS. - -Usage: - uv run python examples/orchestrator_demo/run_agent.py "metformin cancer" - uv run python examples/orchestrator_demo/run_agent.py "sildenafil heart failure" --iterations 5 - -Requires: OPENAI_API_KEY or ANTHROPIC_API_KEY -""" - -import argparse -import asyncio -import os -import sys - -from src.agent_factory.judges import JudgeHandler -from src.orchestrator import Orchestrator -from src.tools.clinicaltrials import ClinicalTrialsTool -from src.tools.europepmc import EuropePMCTool -from src.tools.pubmed import PubMedTool -from src.tools.search_handler import SearchHandler -from src.utils.models import OrchestratorConfig - -MAX_ITERATIONS = 10 - - -async def main() -> None: - """Run the REAL agent demo.""" - parser = argparse.ArgumentParser( - description="DeepCritical Agent Demo - REAL, No Mocks", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -This demo runs the REAL search-judge-synthesize loop: - 1. REAL search: PubMed + ClinicalTrials + Europe PMC queries - 2. REAL judge: Actual LLM assessing evidence quality - 3. REAL loop: Actual iterative refinement based on LLM decisions - 4. REAL synthesis: Actual research summary generation - -Examples: - uv run python examples/orchestrator_demo/run_agent.py "metformin cancer" - uv run python examples/orchestrator_demo/run_agent.py "aspirin alzheimer" --iterations 5 - """, - ) - parser.add_argument("query", help="Research query (e.g., 'metformin cancer')") - parser.add_argument("--iterations", type=int, default=3, help="Max iterations (default: 3)") - args = parser.parse_args() - - if not 1 <= args.iterations <= MAX_ITERATIONS: - print(f"Error: iterations must be between 1 and {MAX_ITERATIONS}") - sys.exit(1) - - # Fail fast: require API key - if not (os.getenv("OPENAI_API_KEY") or os.getenv("ANTHROPIC_API_KEY")): - print("=" * 60) - print("ERROR: This demo requires a real LLM.") - print() - print("Set one of the following in your .env file:") - print(" OPENAI_API_KEY=sk-...") - print(" ANTHROPIC_API_KEY=sk-ant-...") - print() - print("This is a REAL demo. No mocks. No fake data.") - print("=" * 60) - sys.exit(1) - - print(f"\n{'=' * 60}") - print("DeepCritical Agent Demo (REAL)") - print(f"Query: {args.query}") - print(f"Max Iterations: {args.iterations}") - print("Mode: REAL (All live API calls)") - print(f"{'=' * 60}\n") - - # Setup REAL components - search_handler = SearchHandler( - tools=[PubMedTool(), ClinicalTrialsTool(), EuropePMCTool()], timeout=30.0 - ) - judge_handler = JudgeHandler() # REAL LLM judge - - config = OrchestratorConfig(max_iterations=args.iterations) - orchestrator = Orchestrator( - search_handler=search_handler, judge_handler=judge_handler, config=config - ) - - # Run the REAL loop - try: - async for event in orchestrator.run(args.query): - # Print event with icon (remove markdown bold for CLI) - print(event.to_markdown().replace("**", "")) - - # Show search results count - if event.type == "search_complete" and event.data: - print(f" -> Found {event.data.get('new_count', 0)} new items") - - except Exception as e: - print(f"\nโŒ Error: {e}") - raise - - print("\n" + "=" * 60) - print("Demo complete! Everything was REAL:") - print(" - Real PubMed + ClinicalTrials + Europe PMC searches") - print(" - Real LLM judge decisions") - print(" - Real iterative refinement") - print("=" * 60 + "\n") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/orchestrator_demo/run_magentic.py b/examples/orchestrator_demo/run_magentic.py deleted file mode 100644 index fe74450d..00000000 --- a/examples/orchestrator_demo/run_magentic.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Magentic-One Orchestrator for DeepCritical. - -This script demonstrates Phase 5 functionality: -- Multi-Agent Coordination (Searcher + Judge + Manager) -- Magentic-One Workflow - -Usage: - export OPENAI_API_KEY=... - uv run python examples/orchestrator_demo/run_magentic.py "metformin cancer" -""" - -import argparse -import asyncio -import os -import sys - -from src.agent_factory.judges import JudgeHandler -from src.orchestrator_factory import create_orchestrator -from src.tools.clinicaltrials import ClinicalTrialsTool -from src.tools.europepmc import EuropePMCTool -from src.tools.pubmed import PubMedTool -from src.tools.search_handler import SearchHandler -from src.utils.models import OrchestratorConfig - - -async def main() -> None: - """Run the magentic agent demo.""" - parser = argparse.ArgumentParser(description="Run DeepCritical Magentic Agent") - parser.add_argument("query", help="Research query (e.g., 'metformin cancer')") - parser.add_argument("--iterations", type=int, default=10, help="Max rounds") - args = parser.parse_args() - - # Check for OpenAI key specifically - Magentic requires function calling - # which is only supported by OpenAI's API (not Anthropic or HF Inference) - if not os.getenv("OPENAI_API_KEY"): - print("Error: OPENAI_API_KEY required. Magentic uses function calling") - print(" which requires OpenAI's API. For other providers, use mode='simple'.") - sys.exit(1) - - print(f"\n{'=' * 60}") - print("DeepCritical Magentic Agent Demo") - print(f"Query: {args.query}") - print("Mode: MAGENTIC (Multi-Agent)") - print(f"{'=' * 60}\n") - - # 1. Setup Search Tools - search_handler = SearchHandler( - tools=[PubMedTool(), ClinicalTrialsTool(), EuropePMCTool()], timeout=30.0 - ) - - # 2. Setup Judge - judge_handler = JudgeHandler() - - # 3. Setup Orchestrator via Factory - config = OrchestratorConfig(max_iterations=args.iterations) - orchestrator = create_orchestrator( - search_handler=search_handler, - judge_handler=judge_handler, - config=config, - mode="magentic", - ) - - if not orchestrator: - print("Failed to create Magentic orchestrator. Is agent-framework installed?") - sys.exit(1) - - # 4. Run Loop - try: - async for event in orchestrator.run(args.query): - # Print event with icon - # Clean up markdown for CLI - msg_obj = event.message - msg_text = "" - if hasattr(msg_obj, "text"): - msg_text = msg_obj.text - else: - msg_text = str(msg_obj) - - msg = msg_text.replace("\n", " ").replace("**", "")[:150] - print(f"[{event.type.upper()}] {msg}...") - - if event.type == "complete": - print("\n--- FINAL OUTPUT ---\n") - print(msg_text) - - except Exception as e: - print(f"\nโŒ Error: {e}") - import traceback - - traceback.print_exc() - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/rate_limiting_demo.py b/examples/rate_limiting_demo.py deleted file mode 100644 index 90aab639..00000000 --- a/examples/rate_limiting_demo.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -"""Demo script to verify rate limiting works correctly.""" - -import asyncio -import time - -from src.tools.pubmed import PubMedTool -from src.tools.rate_limiter import RateLimiter, get_pubmed_limiter, reset_pubmed_limiter - - -async def test_basic_limiter(): - """Test basic rate limiter behavior.""" - print("=" * 60) - print("Rate Limiting Demo") - print("=" * 60) - - # Test 1: Basic limiter - print("\n[Test 1] Testing 3/second limiter...") - limiter = RateLimiter("3/second") - - start = time.monotonic() - for i in range(6): - await limiter.acquire() - elapsed = time.monotonic() - start - print(f" Request {i + 1} at {elapsed:.2f}s") - - total = time.monotonic() - start - print(f" Total time for 6 requests: {total:.2f}s (expected ~2s)") - - -async def test_pubmed_limiter(): - """Test PubMed-specific limiter.""" - print("\n[Test 2] Testing PubMed limiter (shared)...") - - reset_pubmed_limiter() # Clean state - - # Without API key: 3/sec - limiter = get_pubmed_limiter(api_key=None) - print(f" Rate without key: {limiter.rate}") - - # Multiple tools should share the same limiter - tool1 = PubMedTool() - tool2 = PubMedTool() - - # Verify they share the limiter - print(f" Tools share limiter: {tool1._limiter is tool2._limiter}") - - -async def test_concurrent_requests(): - """Test rate limiting under concurrent load.""" - print("\n[Test 3] Testing concurrent request limiting...") - - limiter = RateLimiter("5/second") - - async def make_request(i: int): - await limiter.acquire() - return time.monotonic() - - start = time.monotonic() - # Launch 10 concurrent requests - tasks = [make_request(i) for i in range(10)] - times = await asyncio.gather(*tasks) - - # Calculate distribution - relative_times = [t - start for t in times] - print(f" Request times: {[f'{t:.2f}s' for t in sorted(relative_times)]}") - - total = max(relative_times) - print(f" All 10 requests completed in {total:.2f}s (expected ~2s)") - - -async def main(): - await test_basic_limiter() - await test_pubmed_limiter() - await test_concurrent_requests() - - print("\n" + "=" * 60) - print("Demo complete!") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/search_demo/run_search.py b/examples/search_demo/run_search.py deleted file mode 100644 index f1c480c4..00000000 --- a/examples/search_demo/run_search.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Search for biomedical research evidence. - -This script demonstrates multi-source search functionality: -- PubMed search (biomedical literature) -- ClinicalTrials.gov search (clinical trial evidence) -- SearchHandler (parallel scatter-gather orchestration) - -Usage: - # From project root: - uv run python examples/search_demo/run_search.py - - # With custom query: - uv run python examples/search_demo/run_search.py "metformin cancer" - -Requirements: - - Optional: NCBI_API_KEY in .env for higher PubMed rate limits -""" - -import asyncio -import sys - -from src.tools.clinicaltrials import ClinicalTrialsTool -from src.tools.europepmc import EuropePMCTool -from src.tools.pubmed import PubMedTool -from src.tools.search_handler import SearchHandler - - -async def main(query: str) -> None: - """Run search demo with the given query.""" - print(f"\n{'=' * 60}") - print("The DETERMINATOR Search Demo") - print(f"Query: {query}") - print(f"{'=' * 60}\n") - - # Initialize tools - pubmed = PubMedTool() - trials = ClinicalTrialsTool() - preprints = EuropePMCTool() - handler = SearchHandler(tools=[pubmed, trials, preprints], timeout=30.0) - - # Execute search - print("Searching PubMed, ClinicalTrials.gov, and Europe PMC in parallel...") - result = await handler.execute(query, max_results_per_tool=5) - - # Display results - print(f"\n{'=' * 60}") - print(f"Results: {result.total_found} pieces of evidence") - print(f"Sources: {', '.join(result.sources_searched)}") - if result.errors: - print(f"Errors: {result.errors}") - print(f"{'=' * 60}\n") - - for i, evidence in enumerate(result.evidence, 1): - print(f"[{i}] {evidence.citation.source.upper()}: {evidence.citation.title[:80]}...") - print(f" URL: {evidence.citation.url}") - print(f" Content: {evidence.content[:150]}...") - print() - - -if __name__ == "__main__": - # Default query or use command line arg - default_query = "metformin Alzheimer's disease treatment mechanisms" - query = sys.argv[1] if len(sys.argv) > 1 else default_query - - asyncio.run(main(query)) diff --git a/site/api/agents/index.html b/site/api/agents/index.html index 920ce21b..47398e7e 100644 --- a/site/api/agents/index.html +++ b/site/api/agents/index.html @@ -1 +1 @@ - Agents API Reference - The DETERMINATOR
Skip to content

Agents API Reference

This page documents the API for DeepCritical agents.

KnowledgeGapAgent

Module: src.agents.knowledge_gap

Purpose: Evaluates research state and identifies knowledge gaps.

Methods

evaluate

Evaluates research completeness and identifies outstanding knowledge gaps.

Parameters: - query: Research query string - background_context: Background context for the query (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "") - iteration: Current iteration number (default: 0) - time_elapsed_minutes: Elapsed time in minutes (default: 0.0) - max_time_minutes: Maximum time limit in minutes (default: 10)

Returns: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

ToolSelectorAgent

Module: src.agents.tool_selector

Purpose: Selects appropriate tools for addressing knowledge gaps.

Methods

select_tools

Selects tools for addressing a knowledge gap.

Parameters: - gap: The knowledge gap to address - query: Research query string - background_context: Optional background context (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "")

Returns: AgentSelectionPlan with list of AgentTask objects.

WriterAgent

Module: src.agents.writer

Purpose: Generates final reports from research findings.

Methods

write_report

Generates a markdown report from research findings.

Parameters: - query: Research query string - findings: Research findings to include in report - output_length: Optional description of desired output length (default: "") - output_instructions: Optional additional instructions for report generation (default: "")

Returns: Markdown string with numbered citations.

LongWriterAgent

Module: src.agents.long_writer

Purpose: Long-form report generation with section-by-section writing.

Methods

write_next_section

Writes the next section of a long-form report.

Parameters: - original_query: The original research query - report_draft: Current report draft as string (all sections written so far) - next_section_title: Title of the section to write - next_section_draft: Draft content for the next section

Returns: LongWriterOutput with formatted section and references.

write_report

Generates final report from draft.

Parameters: - query: Research query string - report_title: Title of the report - report_draft: Complete report draft

Returns: Final markdown report string.

ProofreaderAgent

Module: src.agents.proofreader

Purpose: Proofreads and polishes report drafts.

Methods

proofread

Proofreads and polishes a report draft.

Parameters: - query: Research query string - report_title: Title of the report - report_draft: Report draft to proofread

Returns: Polished markdown string.

ThinkingAgent

Module: src.agents.thinking

Purpose: Generates observations from conversation history.

Methods

generate_observations

Generates observations from conversation history.

Parameters: - query: Research query string - background_context: Optional background context (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "") - iteration: Current iteration number (default: 1)

Returns: Observation string.

InputParserAgent

Module: src.agents.input_parser

Purpose: Parses and improves user queries, detects research mode.

Methods

parse

Parses and improves a user query.

Parameters: - query: Original query string

Returns: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: "iterative" or "deep" - key_entities: List of key entities - research_questions: List of research questions

Factory Functions

All agents have factory functions in src.agent_factory.agents:

Parameters: - model: Optional Pydantic AI model. If None, uses get_model() from settings. - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

Returns: Agent instance.

See Also

\ No newline at end of file + Agents API Reference - The DETERMINATOR
Skip to content

Agents API Reference

This page documents the API for DeepCritical agents.

KnowledgeGapAgent

Module: src.agents.knowledge_gap

Purpose: Evaluates research state and identifies knowledge gaps.

Methods

evaluate

Evaluates research completeness and identifies outstanding knowledge gaps.

Parameters: - query: Research query string - background_context: Background context for the query (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "") - iteration: Current iteration number (default: 0) - time_elapsed_minutes: Elapsed time in minutes (default: 0.0) - max_time_minutes: Maximum time limit in minutes (default: 10)

Returns: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

ToolSelectorAgent

Module: src.agents.tool_selector

Purpose: Selects appropriate tools for addressing knowledge gaps.

Methods

select_tools

Selects tools for addressing a knowledge gap.

Parameters: - gap: The knowledge gap to address - query: Research query string - background_context: Optional background context (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "")

Returns: AgentSelectionPlan with list of AgentTask objects.

WriterAgent

Module: src.agents.writer

Purpose: Generates final reports from research findings.

Methods

write_report

Generates a markdown report from research findings.

Parameters: - query: Research query string - findings: Research findings to include in report - output_length: Optional description of desired output length (default: "") - output_instructions: Optional additional instructions for report generation (default: "")

Returns: Markdown string with numbered citations.

LongWriterAgent

Module: src.agents.long_writer

Purpose: Long-form report generation with section-by-section writing.

Methods

write_next_section

Writes the next section of a long-form report.

Parameters: - original_query: The original research query - report_draft: Current report draft as string (all sections written so far) - next_section_title: Title of the section to write - next_section_draft: Draft content for the next section

Returns: LongWriterOutput with formatted section and references.

write_report

Generates final report from draft.

Parameters: - query: Research query string - report_title: Title of the report - report_draft: Complete report draft

Returns: Final markdown report string.

ProofreaderAgent

Module: src.agents.proofreader

Purpose: Proofreads and polishes report drafts.

Methods

proofread

Proofreads and polishes a report draft.

Parameters: - query: Research query string - report_title: Title of the report - report_draft: Report draft to proofread

Returns: Polished markdown string.

ThinkingAgent

Module: src.agents.thinking

Purpose: Generates observations from conversation history.

Methods

generate_observations

Generates observations from conversation history.

Parameters: - query: Research query string - background_context: Optional background context (default: "") - conversation_history: History of actions, findings, and thoughts as string (default: "") - iteration: Current iteration number (default: 1)

Returns: Observation string.

InputParserAgent

Module: src.agents.input_parser

Purpose: Parses and improves user queries, detects research mode.

Methods

parse

Parses and improves a user query.

Parameters: - query: Original query string

Returns: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: "iterative" or "deep" - key_entities: List of key entities - research_questions: List of research questions

Factory Functions

All agents have factory functions in src.agent_factory.agents:

Parameters: - model: Optional Pydantic AI model. If None, uses get_model() from settings. - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

Returns: Agent instance.

See Also

\ No newline at end of file diff --git a/site/api/models/index.html b/site/api/models/index.html index 23736452..06a0e6db 100644 --- a/site/api/models/index.html +++ b/site/api/models/index.html @@ -1 +1 @@ - Models API Reference - The DETERMINATOR
Skip to content

Models API Reference

This page documents the Pydantic models used throughout DeepCritical.

Evidence

Module: src.utils.models

Purpose: Represents evidence from search results.

Fields: - citation: Citation information (title, URL, date, authors) - content: Evidence text content - relevance: Relevance score (0.0-1.0) - metadata: Additional metadata dictionary

Citation

Module: src.utils.models

Purpose: Citation information for evidence.

Fields: - source: Source name (e.g., "pubmed", "clinicaltrials", "europepmc", "web", "rag") - title: Article/trial title - url: Source URL - date: Publication date (YYYY-MM-DD or "Unknown") - authors: List of authors (optional)

KnowledgeGapOutput

Module: src.utils.models

Purpose: Output from knowledge gap evaluation.

Fields: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

AgentSelectionPlan

Module: src.utils.models

Purpose: Plan for tool/agent selection.

Fields: - tasks: List of agent tasks to execute

AgentTask

Module: src.utils.models

Purpose: Individual agent task.

Fields: - gap: The knowledge gap being addressed (optional) - agent: Name of agent to use - query: The specific query for the agent - entity_website: The website of the entity being researched, if known (optional)

ReportDraft

Module: src.utils.models

Purpose: Draft structure for long-form reports.

Fields: - sections: List of report sections

ReportSection

Module: src.utils.models

Purpose: Individual section in a report draft.

Fields: - section_title: The title of the section - section_content: The content of the section

ParsedQuery

Module: src.utils.models

Purpose: Parsed and improved query.

Fields: - original_query: Original query string - improved_query: Refined query string - research_mode: Research mode ("iterative" or "deep") - key_entities: List of key entities - research_questions: List of research questions

Conversation

Module: src.utils.models

Purpose: Conversation history with iterations.

Fields: - history: List of iteration data

IterationData

Module: src.utils.models

Purpose: Data for a single iteration.

Fields: - gap: The gap addressed in the iteration - tool_calls: The tool calls made - findings: The findings collected from tool calls - thought: The thinking done to reflect on the success of the iteration and next steps

AgentEvent

Module: src.utils.models

Purpose: Event emitted during research execution.

Fields: - type: Event type (e.g., "started", "search_complete", "complete") - iteration: Iteration number (optional) - data: Event data dictionary

BudgetStatus

Module: src.utils.models

Purpose: Current budget status.

Fields: - tokens_used: Total tokens used - tokens_limit: Token budget limit - time_elapsed_seconds: Time elapsed in seconds - time_limit_seconds: Time budget limit (default: 600.0 seconds / 10 minutes) - iterations: Number of iterations completed - iterations_limit: Maximum iterations (default: 10) - iteration_tokens: Tokens used per iteration (iteration number -> token count)

See Also

\ No newline at end of file + Models API Reference - The DETERMINATOR
Skip to content

Models API Reference

This page documents the Pydantic models used throughout DeepCritical.

Evidence

Module: src.utils.models

Purpose: Represents evidence from search results.

Fields: - citation: Citation information (title, URL, date, authors) - content: Evidence text content - relevance: Relevance score (0.0-1.0) - metadata: Additional metadata dictionary

Citation

Module: src.utils.models

Purpose: Citation information for evidence.

Fields: - source: Source name (e.g., "pubmed", "clinicaltrials", "europepmc", "web", "rag") - title: Article/trial title - url: Source URL - date: Publication date (YYYY-MM-DD or "Unknown") - authors: List of authors (optional)

KnowledgeGapOutput

Module: src.utils.models

Purpose: Output from knowledge gap evaluation.

Fields: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

AgentSelectionPlan

Module: src.utils.models

Purpose: Plan for tool/agent selection.

Fields: - tasks: List of agent tasks to execute

AgentTask

Module: src.utils.models

Purpose: Individual agent task.

Fields: - gap: The knowledge gap being addressed (optional) - agent: Name of agent to use - query: The specific query for the agent - entity_website: The website of the entity being researched, if known (optional)

ReportDraft

Module: src.utils.models

Purpose: Draft structure for long-form reports.

Fields: - sections: List of report sections

ReportSection

Module: src.utils.models

Purpose: Individual section in a report draft.

Fields: - section_title: The title of the section - section_content: The content of the section

ParsedQuery

Module: src.utils.models

Purpose: Parsed and improved query.

Fields: - original_query: Original query string - improved_query: Refined query string - research_mode: Research mode ("iterative" or "deep") - key_entities: List of key entities - research_questions: List of research questions

Conversation

Module: src.utils.models

Purpose: Conversation history with iterations.

Fields: - history: List of iteration data

IterationData

Module: src.utils.models

Purpose: Data for a single iteration.

Fields: - gap: The gap addressed in the iteration - tool_calls: The tool calls made - findings: The findings collected from tool calls - thought: The thinking done to reflect on the success of the iteration and next steps

AgentEvent

Module: src.utils.models

Purpose: Event emitted during research execution.

Fields: - type: Event type (e.g., "started", "search_complete", "complete") - iteration: Iteration number (optional) - data: Event data dictionary

BudgetStatus

Module: src.utils.models

Purpose: Current budget status.

Fields: - tokens_used: Total tokens used - tokens_limit: Token budget limit - time_elapsed_seconds: Time elapsed in seconds - time_limit_seconds: Time budget limit (default: 600.0 seconds / 10 minutes) - iterations: Number of iterations completed - iterations_limit: Maximum iterations (default: 10) - iteration_tokens: Tokens used per iteration (iteration number -> token count)

See Also

\ No newline at end of file diff --git a/site/api/orchestrators/index.html b/site/api/orchestrators/index.html index 756118eb..ac74f554 100644 --- a/site/api/orchestrators/index.html +++ b/site/api/orchestrators/index.html @@ -1 +1 @@ - Orchestrators API Reference - The DETERMINATOR
Skip to content

Orchestrators API Reference

This page documents the API for DeepCritical orchestrators.

IterativeResearchFlow

Module: src.orchestrator.research_flow

Purpose: Single-loop research with search-judge-synthesize cycles.

Methods

run

Runs iterative research flow.

Parameters: - query: Research query string - background_context: Background context (default: "") - output_length: Optional description of desired output length (default: "") - output_instructions: Optional additional instructions for report generation (default: "")

Returns: Final report string.

Note: max_iterations, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

DeepResearchFlow

Module: src.orchestrator.research_flow

Purpose: Multi-section parallel research with planning and synthesis.

Methods

run

Runs deep research flow.

Parameters: - query: Research query string

Returns: Final report string.

Note: max_iterations_per_section, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

GraphOrchestrator

Module: src.orchestrator.graph_orchestrator

Purpose: Graph-based execution using Pydantic AI agents as nodes.

Methods

run

Runs graph-based research orchestration.

Parameters: - query: Research query string

Yields: AgentEvent objects during graph execution.

Note: research_mode and use_graph are constructor parameters, not run() parameters.

Orchestrator Factory

Module: src.orchestrator_factory

Purpose: Factory for creating orchestrators.

Functions

create_orchestrator

Creates an orchestrator instance.

Parameters: - search_handler: Search handler protocol implementation (optional, required for simple mode) - judge_handler: Judge handler protocol implementation (optional, required for simple mode) - config: Configuration object (optional) - mode: Orchestrator mode ("simple", "advanced", "magentic", "iterative", "deep", "auto", or None for auto-detect) - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

Returns: Orchestrator instance.

Raises: - ValueError: If requirements not met

Modes: - "simple": Legacy orchestrator - "advanced" or "magentic": Magentic orchestrator (requires OpenAI API key) - None: Auto-detect based on API key availability

MagenticOrchestrator

Module: src.orchestrator_magentic

Purpose: Multi-agent coordination using Microsoft Agent Framework.

Methods

run

Runs Magentic orchestration.

Parameters: - query: Research query string

Yields: AgentEvent objects converted from Magentic events.

Note: max_rounds and max_stalls are constructor parameters, not run() parameters.

Requirements: - agent-framework-core package - OpenAI API key

See Also

\ No newline at end of file + Orchestrators API Reference - The DETERMINATOR
Skip to content

Orchestrators API Reference

This page documents the API for DeepCritical orchestrators.

IterativeResearchFlow

Module: src.orchestrator.research_flow

Purpose: Single-loop research with search-judge-synthesize cycles.

Methods

run

Runs iterative research flow.

Parameters: - query: Research query string - background_context: Background context (default: "") - output_length: Optional description of desired output length (default: "") - output_instructions: Optional additional instructions for report generation (default: "")

Returns: Final report string.

Note: max_iterations, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

DeepResearchFlow

Module: src.orchestrator.research_flow

Purpose: Multi-section parallel research with planning and synthesis.

Methods

run

Runs deep research flow.

Parameters: - query: Research query string

Returns: Final report string.

Note: max_iterations_per_section, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

GraphOrchestrator

Module: src.orchestrator.graph_orchestrator

Purpose: Graph-based execution using Pydantic AI agents as nodes.

Methods

run

Runs graph-based research orchestration.

Parameters: - query: Research query string

Yields: AgentEvent objects during graph execution.

Note: research_mode and use_graph are constructor parameters, not run() parameters.

Orchestrator Factory

Module: src.orchestrator_factory

Purpose: Factory for creating orchestrators.

Functions

create_orchestrator

Creates an orchestrator instance.

Parameters: - search_handler: Search handler protocol implementation (optional, required for simple mode) - judge_handler: Judge handler protocol implementation (optional, required for simple mode) - config: Configuration object (optional) - mode: Orchestrator mode ("simple", "advanced", "magentic", "iterative", "deep", "auto", or None for auto-detect) - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

Returns: Orchestrator instance.

Raises: - ValueError: If requirements not met

Modes: - "simple": Legacy orchestrator - "advanced" or "magentic": Magentic orchestrator (requires OpenAI API key) - None: Auto-detect based on API key availability

MagenticOrchestrator

Module: src.orchestrator_magentic

Purpose: Multi-agent coordination using Microsoft Agent Framework.

Methods

run

Runs Magentic orchestration.

Parameters: - query: Research query string

Yields: AgentEvent objects converted from Magentic events.

Note: max_rounds and max_stalls are constructor parameters, not run() parameters.

Requirements: - agent-framework-core package - OpenAI API key

See Also

\ No newline at end of file diff --git a/site/api/services/index.html b/site/api/services/index.html index a231d587..b9d99cd3 100644 --- a/site/api/services/index.html +++ b/site/api/services/index.html @@ -46,4 +46,4 @@ evidence: list[Evidence], hypothesis: dict[str, Any] | None = None ) -> AnalysisResult -

Analyzes a research question using statistical methods.

Parameters: - query: The research question - evidence: List of Evidence objects to analyze - hypothesis: Optional hypothesis dict with drug, target, pathway, effect, confidence keys

Returns: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - confidence: Confidence in verdict (0.0-1.0) - statistical_evidence: Summary of statistical findings - code_generated: Python code that was executed - execution_output: Output from code execution - key_takeaways: Key takeaways from analysis - limitations: List of limitations

Note: Requires Modal credentials for sandbox execution.

See Also

\ No newline at end of file +

Analyzes a research question using statistical methods.

Parameters: - query: The research question - evidence: List of Evidence objects to analyze - hypothesis: Optional hypothesis dict with drug, target, pathway, effect, confidence keys

Returns: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - confidence: Confidence in verdict (0.0-1.0) - statistical_evidence: Summary of statistical findings - code_generated: Python code that was executed - execution_output: Output from code execution - key_takeaways: Key takeaways from analysis - limitations: List of limitations

Note: Requires Modal credentials for sandbox execution.

See Also

\ No newline at end of file diff --git a/site/api/tools/index.html b/site/api/tools/index.html index d88763af..d5798e8b 100644 --- a/site/api/tools/index.html +++ b/site/api/tools/index.html @@ -48,4 +48,4 @@ auto_ingest_to_rag: bool = True, oauth_token: str | None = None ) -> None -

Parameters: - tools: List of search tools to use - timeout: Timeout for each search in seconds (default: 30.0) - include_rag: Whether to include RAG tool in searches (default: False) - auto_ingest_to_rag: Whether to automatically ingest results into RAG (default: True) - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

Methods

execute

Searches multiple tools in parallel.

Parameters: - query: Search query string - max_results_per_tool: Maximum results per tool (default: 10)

Returns: SearchResult with: - query: The search query - evidence: Aggregated list of evidence - sources_searched: List of source names searched - total_found: Total number of results - errors: List of error messages from failed tools

Raises: - SearchError: If search times out

Note: Uses asyncio.gather() for parallel execution. Handles tool failures gracefully (returns errors in SearchResult.errors). Automatically ingests evidence into RAG if enabled.

See Also

\ No newline at end of file +

Parameters: - tools: List of search tools to use - timeout: Timeout for each search in seconds (default: 30.0) - include_rag: Whether to include RAG tool in searches (default: False) - auto_ingest_to_rag: Whether to automatically ingest results into RAG (default: True) - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

Methods

execute

Searches multiple tools in parallel.

Parameters: - query: Search query string - max_results_per_tool: Maximum results per tool (default: 10)

Returns: SearchResult with: - query: The search query - evidence: Aggregated list of evidence - sources_searched: List of source names searched - total_found: Total number of results - errors: List of error messages from failed tools

Raises: - SearchError: If search times out

Note: Uses asyncio.gather() for parallel execution. Handles tool failures gracefully (returns errors in SearchResult.errors). Automatically ingests evidence into RAG if enabled.

See Also

\ No newline at end of file diff --git a/site/architecture/agents/index.html b/site/architecture/agents/index.html index bd3053f8..00b7543c 100644 --- a/site/architecture/agents/index.html +++ b/site/architecture/agents/index.html @@ -1 +1 @@ - Agents - The DETERMINATOR
Skip to content

Agents Architecture

DeepCritical uses Pydantic AI agents for all AI-powered operations. All agents follow a consistent pattern and use structured output types.

Agent Pattern

Pydantic AI Agents

Pydantic AI agents use the Agent class with the following structure:

  • System Prompt: Module-level constant with date injection
  • Agent Class: __init__(model: Any | None = None)
  • Main Method: Async method (e.g., async def evaluate(), async def write_report())
  • Factory Function: def create_agent_name(model: Any | None = None, oauth_token: str | None = None) -> AgentName

Note: Factory functions accept an optional oauth_token parameter for HuggingFace authentication, which takes priority over environment variables.

Model Initialization

Agents use get_model() from src/agent_factory/judges.py if no model is provided. This supports:

  • OpenAI models
  • Anthropic models
  • HuggingFace Inference API models

The model selection is based on the configured LLM_PROVIDER in settings.

Error Handling

Agents return fallback values on failure rather than raising exceptions:

  • KnowledgeGapOutput(research_complete=False, outstanding_gaps=[...])
  • Empty strings for text outputs
  • Default structured outputs

All errors are logged with context using structlog.

Input Validation

All agents validate inputs:

  • Check that queries/inputs are not empty
  • Truncate very long inputs with warnings
  • Handle None values gracefully

Output Types

Agents use structured output types from src/utils/models.py:

  • KnowledgeGapOutput: Research completeness evaluation
  • AgentSelectionPlan: Tool selection plan
  • ReportDraft: Long-form report structure
  • ParsedQuery: Query parsing and mode detection

For text output (writer agents), agents return str directly.

Agent Types

Knowledge Gap Agent

File: src/agents/knowledge_gap.py

Purpose: Evaluates research state and identifies knowledge gaps.

Output: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

Methods: - async def evaluate(query, background_context, conversation_history, iteration, time_elapsed_minutes, max_time_minutes) -> KnowledgeGapOutput

Tool Selector Agent

File: src/agents/tool_selector.py

Purpose: Selects appropriate tools for addressing knowledge gaps.

Output: AgentSelectionPlan with list of AgentTask objects.

Available Agents: - WebSearchAgent: General web search for fresh information - SiteCrawlerAgent: Research specific entities/companies - RAGAgent: Semantic search within collected evidence

Writer Agent

File: src/agents/writer.py

Purpose: Generates final reports from research findings.

Output: Markdown string with numbered citations.

Methods: - async def write_report(query, findings, output_length, output_instructions) -> str

Features: - Validates inputs - Truncates very long findings (max 50000 chars) with warning - Retry logic for transient failures (3 retries) - Citation validation before returning

Long Writer Agent

File: src/agents/long_writer.py

Purpose: Long-form report generation with section-by-section writing.

Input/Output: Uses ReportDraft models.

Methods: - async def write_next_section(query, draft, section_title, section_content) -> LongWriterOutput - async def write_report(query, report_title, report_draft) -> str

Features: - Writes sections iteratively - Aggregates references across sections - Reformats section headings and references - Deduplicates and renumbers references

Proofreader Agent

File: src/agents/proofreader.py

Purpose: Proofreads and polishes report drafts.

Input: ReportDraft Output: Polished markdown string

Methods: - async def proofread(query, report_title, report_draft) -> str

Features: - Removes duplicate content across sections - Adds executive summary if multiple sections - Preserves all references and citations - Improves flow and readability

Thinking Agent

File: src/agents/thinking.py

Purpose: Generates observations from conversation history.

Output: Observation string

Methods: - async def generate_observations(query, background_context, conversation_history) -> str

Input Parser Agent

File: src/agents/input_parser.py

Purpose: Parses and improves user queries, detects research mode.

Output: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: "iterative" or "deep" - key_entities: List of key entities - research_questions: List of research questions

Magentic Agents

The following agents use the BaseAgent pattern from agent-framework and are used exclusively with MagenticOrchestrator:

Hypothesis Agent

File: src/agents/hypothesis_agent.py

Purpose: Generates mechanistic hypotheses based on evidence.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Uses internal Pydantic AI Agent with HypothesisAssessment output type - Accesses shared evidence_store for evidence - Uses embedding service for diverse evidence selection (MMR algorithm) - Stores hypotheses in shared context

Search Agent

File: src/agents/search_agent.py

Purpose: Wraps SearchHandler as an agent for Magentic orchestrator.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Executes searches via SearchHandlerProtocol - Deduplicates evidence using embedding service - Searches for semantically related evidence - Updates shared evidence store

Analysis Agent

File: src/agents/analysis_agent.py

Purpose: Performs statistical analysis using Modal sandbox.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Wraps StatisticalAnalyzer service - Analyzes evidence and hypotheses - Returns verdict (SUPPORTED/REFUTED/INCONCLUSIVE) - Stores analysis results in shared context

Report Agent (Magentic)

File: src/agents/report_agent.py

Purpose: Generates structured scientific reports from evidence and hypotheses.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Uses internal Pydantic AI Agent with ResearchReport output type - Accesses shared evidence store and hypotheses - Validates citations before returning - Formats report as markdown

Judge Agent

File: src/agents/judge_agent.py

Purpose: Evaluates evidence quality and determines if sufficient for synthesis.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse - async def run_stream(messages, thread, **kwargs) -> AsyncIterable[AgentRunResponseUpdate]

Features: - Wraps JudgeHandlerProtocol - Accesses shared evidence store - Returns JudgeAssessment with sufficient flag, confidence, and recommendation

Agent Patterns

DeepCritical uses two distinct agent patterns:

1. Pydantic AI Agents (Traditional Pattern)

These agents use the Pydantic AI Agent class directly and are used in iterative and deep research flows:

  • Pattern: Agent(model, output_type, system_prompt)
  • Initialization: __init__(model: Any | None = None)
  • Methods: Agent-specific async methods (e.g., async def evaluate(), async def write_report())
  • Examples: KnowledgeGapAgent, ToolSelectorAgent, WriterAgent, LongWriterAgent, ProofreaderAgent, ThinkingAgent, InputParserAgent

2. Magentic Agents (Agent-Framework Pattern)

These agents use the BaseAgent class from agent-framework and are used in Magentic orchestrator:

  • Pattern: BaseAgent from agent-framework with async def run() method
  • Initialization: __init__(evidence_store, embedding_service, ...)
  • Methods: async def run(messages, thread, **kwargs) -> AgentRunResponse
  • Examples: HypothesisAgent, SearchAgent, AnalysisAgent, ReportAgent, JudgeAgent

Note: Magentic agents are used exclusively with the MagenticOrchestrator and follow the agent-framework protocol for multi-agent coordination.

Factory Functions

All agents have factory functions in src/agent_factory/agents.py:

Factory functions: - Use get_model() if no model provided - Accept oauth_token parameter for HuggingFace authentication - Raise ConfigurationError if creation fails - Log agent creation

See Also

\ No newline at end of file + Agents - The DETERMINATOR
Skip to content

Agents Architecture

DeepCritical uses Pydantic AI agents for all AI-powered operations. All agents follow a consistent pattern and use structured output types.

Agent Pattern

Pydantic AI Agents

Pydantic AI agents use the Agent class with the following structure:

  • System Prompt: Module-level constant with date injection
  • Agent Class: __init__(model: Any | None = None)
  • Main Method: Async method (e.g., async def evaluate(), async def write_report())
  • Factory Function: def create_agent_name(model: Any | None = None, oauth_token: str | None = None) -> AgentName

Note: Factory functions accept an optional oauth_token parameter for HuggingFace authentication, which takes priority over environment variables.

Model Initialization

Agents use get_model() from src/agent_factory/judges.py if no model is provided. This supports:

  • OpenAI models
  • Anthropic models
  • HuggingFace Inference API models

The model selection is based on the configured LLM_PROVIDER in settings.

Error Handling

Agents return fallback values on failure rather than raising exceptions:

  • KnowledgeGapOutput(research_complete=False, outstanding_gaps=[...])
  • Empty strings for text outputs
  • Default structured outputs

All errors are logged with context using structlog.

Input Validation

All agents validate inputs:

  • Check that queries/inputs are not empty
  • Truncate very long inputs with warnings
  • Handle None values gracefully

Output Types

Agents use structured output types from src/utils/models.py:

  • KnowledgeGapOutput: Research completeness evaluation
  • AgentSelectionPlan: Tool selection plan
  • ReportDraft: Long-form report structure
  • ParsedQuery: Query parsing and mode detection

For text output (writer agents), agents return str directly.

Agent Types

Knowledge Gap Agent

File: src/agents/knowledge_gap.py

Purpose: Evaluates research state and identifies knowledge gaps.

Output: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

Methods: - async def evaluate(query, background_context, conversation_history, iteration, time_elapsed_minutes, max_time_minutes) -> KnowledgeGapOutput

Tool Selector Agent

File: src/agents/tool_selector.py

Purpose: Selects appropriate tools for addressing knowledge gaps.

Output: AgentSelectionPlan with list of AgentTask objects.

Available Agents: - WebSearchAgent: General web search for fresh information - SiteCrawlerAgent: Research specific entities/companies - RAGAgent: Semantic search within collected evidence

Writer Agent

File: src/agents/writer.py

Purpose: Generates final reports from research findings.

Output: Markdown string with numbered citations.

Methods: - async def write_report(query, findings, output_length, output_instructions) -> str

Features: - Validates inputs - Truncates very long findings (max 50000 chars) with warning - Retry logic for transient failures (3 retries) - Citation validation before returning

Long Writer Agent

File: src/agents/long_writer.py

Purpose: Long-form report generation with section-by-section writing.

Input/Output: Uses ReportDraft models.

Methods: - async def write_next_section(query, draft, section_title, section_content) -> LongWriterOutput - async def write_report(query, report_title, report_draft) -> str

Features: - Writes sections iteratively - Aggregates references across sections - Reformats section headings and references - Deduplicates and renumbers references

Proofreader Agent

File: src/agents/proofreader.py

Purpose: Proofreads and polishes report drafts.

Input: ReportDraft Output: Polished markdown string

Methods: - async def proofread(query, report_title, report_draft) -> str

Features: - Removes duplicate content across sections - Adds executive summary if multiple sections - Preserves all references and citations - Improves flow and readability

Thinking Agent

File: src/agents/thinking.py

Purpose: Generates observations from conversation history.

Output: Observation string

Methods: - async def generate_observations(query, background_context, conversation_history) -> str

Input Parser Agent

File: src/agents/input_parser.py

Purpose: Parses and improves user queries, detects research mode.

Output: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: "iterative" or "deep" - key_entities: List of key entities - research_questions: List of research questions

Magentic Agents

The following agents use the BaseAgent pattern from agent-framework and are used exclusively with MagenticOrchestrator:

Hypothesis Agent

File: src/agents/hypothesis_agent.py

Purpose: Generates mechanistic hypotheses based on evidence.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Uses internal Pydantic AI Agent with HypothesisAssessment output type - Accesses shared evidence_store for evidence - Uses embedding service for diverse evidence selection (MMR algorithm) - Stores hypotheses in shared context

Search Agent

File: src/agents/search_agent.py

Purpose: Wraps SearchHandler as an agent for Magentic orchestrator.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Executes searches via SearchHandlerProtocol - Deduplicates evidence using embedding service - Searches for semantically related evidence - Updates shared evidence store

Analysis Agent

File: src/agents/analysis_agent.py

Purpose: Performs statistical analysis using Modal sandbox.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Wraps StatisticalAnalyzer service - Analyzes evidence and hypotheses - Returns verdict (SUPPORTED/REFUTED/INCONCLUSIVE) - Stores analysis results in shared context

Report Agent (Magentic)

File: src/agents/report_agent.py

Purpose: Generates structured scientific reports from evidence and hypotheses.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

Features: - Uses internal Pydantic AI Agent with ResearchReport output type - Accesses shared evidence store and hypotheses - Validates citations before returning - Formats report as markdown

Judge Agent

File: src/agents/judge_agent.py

Purpose: Evaluates evidence quality and determines if sufficient for synthesis.

Pattern: BaseAgent from agent-framework

Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse - async def run_stream(messages, thread, **kwargs) -> AsyncIterable[AgentRunResponseUpdate]

Features: - Wraps JudgeHandlerProtocol - Accesses shared evidence store - Returns JudgeAssessment with sufficient flag, confidence, and recommendation

Agent Patterns

DeepCritical uses two distinct agent patterns:

1. Pydantic AI Agents (Traditional Pattern)

These agents use the Pydantic AI Agent class directly and are used in iterative and deep research flows:

  • Pattern: Agent(model, output_type, system_prompt)
  • Initialization: __init__(model: Any | None = None)
  • Methods: Agent-specific async methods (e.g., async def evaluate(), async def write_report())
  • Examples: KnowledgeGapAgent, ToolSelectorAgent, WriterAgent, LongWriterAgent, ProofreaderAgent, ThinkingAgent, InputParserAgent

2. Magentic Agents (Agent-Framework Pattern)

These agents use the BaseAgent class from agent-framework and are used in Magentic orchestrator:

  • Pattern: BaseAgent from agent-framework with async def run() method
  • Initialization: __init__(evidence_store, embedding_service, ...)
  • Methods: async def run(messages, thread, **kwargs) -> AgentRunResponse
  • Examples: HypothesisAgent, SearchAgent, AnalysisAgent, ReportAgent, JudgeAgent

Note: Magentic agents are used exclusively with the MagenticOrchestrator and follow the agent-framework protocol for multi-agent coordination.

Factory Functions

All agents have factory functions in src/agent_factory/agents.py:

Factory functions: - Use get_model() if no model provided - Accept oauth_token parameter for HuggingFace authentication - Raise ConfigurationError if creation fails - Log agent creation

See Also

\ No newline at end of file diff --git a/site/architecture/graph_orchestration/index.html b/site/architecture/graph_orchestration/index.html index be63b4de..6f35dca9 100644 --- a/site/architecture/graph_orchestration/index.html +++ b/site/architecture/graph_orchestration/index.html @@ -72,4 +72,4 @@ IterativeFlow->>JudgeHandler: assess_evidence() JudgeHandler-->>IterativeFlow: should_continue end - end

Graph Structureยถ

Nodesยถ

Graph nodes represent different stages in the research workflow:

  1. Agent Nodes: Execute Pydantic AI agents
  2. Input: Prompt/query
  3. Output: Structured or unstructured response
  4. Examples: KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent

  5. State Nodes: Update or read workflow state

  6. Input: Current state
  7. Output: Updated state
  8. Examples: Update evidence, update conversation history

  9. Decision Nodes: Make routing decisions based on conditions

  10. Input: Current state/results
  11. Output: Next node ID
  12. Examples: Continue research vs. complete research

  13. Parallel Nodes: Execute multiple nodes concurrently

  14. Input: List of node IDs
  15. Output: Aggregated results
  16. Examples: Parallel iterative research loops

Edgesยถ

Edges define transitions between nodes:

  1. Sequential Edges: Always traversed (no condition)
  2. From: Source node
  3. To: Target node
  4. Condition: None (always True)

  5. Conditional Edges: Traversed based on condition

  6. From: Source node
  7. To: Target node
  8. Condition: Callable that returns bool
  9. Example: If research complete โ†’ go to writer, else โ†’ continue loop

  10. Parallel Edges: Used for parallel execution branches

  11. From: Parallel node
  12. To: Multiple target nodes
  13. Execution: All targets run concurrently

State Managementยถ

State is managed via WorkflowState using ContextVar for thread-safe isolation:

State transitions occur at state nodes, which update the global workflow state.

Execution Flowยถ

  1. Graph Construction: Build graph from nodes and edges using create_iterative_graph() or create_deep_graph()
  2. Graph Validation: Ensure graph is valid (no cycles, all nodes reachable) via ResearchGraph.validate_structure()
  3. Graph Execution: Traverse graph from entry node using GraphOrchestrator._execute_graph()
  4. Node Execution: Execute each node based on type:
  5. Agent Nodes: Call agent.run() with transformed input
  6. State Nodes: Update workflow state via state_updater function
  7. Decision Nodes: Evaluate decision_function to get next node ID
  8. Parallel Nodes: Execute all parallel nodes concurrently via asyncio.gather()
  9. Edge Evaluation: Determine next node(s) based on edges and conditions
  10. Parallel Execution: Use asyncio.gather() for parallel nodes
  11. State Updates: Update state at state nodes via GraphExecutionContext.update_state()
  12. Event Streaming: Yield AgentEvent objects during execution for UI

GraphExecutionContextยถ

The GraphExecutionContext class manages execution state during graph traversal:

Methods: - set_node_result(node_id, result): Store result from node execution - get_node_result(node_id): Retrieve stored result - has_visited(node_id): Check if node was visited - mark_visited(node_id): Mark node as visited - update_state(updater, data): Update workflow state

Conditional Routingยถ

Decision nodes evaluate conditions and return next node IDs:

Parallel Executionยถ

Parallel nodes execute multiple nodes concurrently:

Budget Enforcementยถ

Budget constraints are enforced at decision nodes:

If any budget is exceeded, execution routes to exit node.

Error Handlingยถ

Errors are handled at multiple levels:

  1. Node Level: Catch errors in individual node execution
  2. Graph Level: Handle errors during graph traversal
  3. State Level: Rollback state changes on error

Errors are logged and yield error events for UI.

Backward Compatibilityยถ

Graph execution is optional via feature flag:

This allows gradual migration and fallback if needed.

See Alsoยถ

\ No newline at end of file + end

Graph Structureยถ

Nodesยถ

Graph nodes represent different stages in the research workflow:

  1. Agent Nodes: Execute Pydantic AI agents
  2. Input: Prompt/query
  3. Output: Structured or unstructured response
  4. Examples: KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent

  5. State Nodes: Update or read workflow state

  6. Input: Current state
  7. Output: Updated state
  8. Examples: Update evidence, update conversation history

  9. Decision Nodes: Make routing decisions based on conditions

  10. Input: Current state/results
  11. Output: Next node ID
  12. Examples: Continue research vs. complete research

  13. Parallel Nodes: Execute multiple nodes concurrently

  14. Input: List of node IDs
  15. Output: Aggregated results
  16. Examples: Parallel iterative research loops

Edgesยถ

Edges define transitions between nodes:

  1. Sequential Edges: Always traversed (no condition)
  2. From: Source node
  3. To: Target node
  4. Condition: None (always True)

  5. Conditional Edges: Traversed based on condition

  6. From: Source node
  7. To: Target node
  8. Condition: Callable that returns bool
  9. Example: If research complete โ†’ go to writer, else โ†’ continue loop

  10. Parallel Edges: Used for parallel execution branches

  11. From: Parallel node
  12. To: Multiple target nodes
  13. Execution: All targets run concurrently

State Managementยถ

State is managed via WorkflowState using ContextVar for thread-safe isolation:

State transitions occur at state nodes, which update the global workflow state.

Execution Flowยถ

  1. Graph Construction: Build graph from nodes and edges using create_iterative_graph() or create_deep_graph()
  2. Graph Validation: Ensure graph is valid (no cycles, all nodes reachable) via ResearchGraph.validate_structure()
  3. Graph Execution: Traverse graph from entry node using GraphOrchestrator._execute_graph()
  4. Node Execution: Execute each node based on type:
  5. Agent Nodes: Call agent.run() with transformed input
  6. State Nodes: Update workflow state via state_updater function
  7. Decision Nodes: Evaluate decision_function to get next node ID
  8. Parallel Nodes: Execute all parallel nodes concurrently via asyncio.gather()
  9. Edge Evaluation: Determine next node(s) based on edges and conditions
  10. Parallel Execution: Use asyncio.gather() for parallel nodes
  11. State Updates: Update state at state nodes via GraphExecutionContext.update_state()
  12. Event Streaming: Yield AgentEvent objects during execution for UI

GraphExecutionContextยถ

The GraphExecutionContext class manages execution state during graph traversal:

Methods: - set_node_result(node_id, result): Store result from node execution - get_node_result(node_id): Retrieve stored result - has_visited(node_id): Check if node was visited - mark_visited(node_id): Mark node as visited - update_state(updater, data): Update workflow state

Conditional Routingยถ

Decision nodes evaluate conditions and return next node IDs:

Parallel Executionยถ

Parallel nodes execute multiple nodes concurrently:

Budget Enforcementยถ

Budget constraints are enforced at decision nodes:

If any budget is exceeded, execution routes to exit node.

Error Handlingยถ

Errors are handled at multiple levels:

  1. Node Level: Catch errors in individual node execution
  2. Graph Level: Handle errors during graph traversal
  3. State Level: Rollback state changes on error

Errors are logged and yield error events for UI.

Backward Compatibilityยถ

Graph execution is optional via feature flag:

This allows gradual migration and fallback if needed.

See Alsoยถ

\ No newline at end of file diff --git a/site/architecture/middleware/index.html b/site/architecture/middleware/index.html index 9857e14e..54435ced 100644 --- a/site/architecture/middleware/index.html +++ b/site/architecture/middleware/index.html @@ -37,4 +37,4 @@ if not tracker.can_continue("research_loop"): # Budget exceeded, stop research pass -

Models

All middleware models are defined in src/utils/models.py:

Thread Safety

All middleware components use ContextVar for thread-safe isolation:

See Also

\ No newline at end of file +

Models

All middleware models are defined in src/utils/models.py:

Thread Safety

All middleware components use ContextVar for thread-safe isolation:

See Also

\ No newline at end of file diff --git a/site/architecture/orchestrators/index.html b/site/architecture/orchestrators/index.html index 493239f6..fcd6738c 100644 --- a/site/architecture/orchestrators/index.html +++ b/site/architecture/orchestrators/index.html @@ -1 +1 @@ - Orchestrators - The DETERMINATOR
Skip to content

Orchestrators Architecture

DeepCritical supports multiple orchestration patterns for research workflows.

Research Flows

IterativeResearchFlow

File: src/orchestrator/research_flow.py

Pattern: Generate observations โ†’ Evaluate gaps โ†’ Select tools โ†’ Execute โ†’ Judge โ†’ Continue/Complete

Agents Used: - KnowledgeGapAgent: Evaluates research completeness - ToolSelectorAgent: Selects tools for addressing gaps - ThinkingAgent: Generates observations - WriterAgent: Creates final report - JudgeHandler: Assesses evidence sufficiency

Features: - Tracks iterations, time, budget - Supports graph execution (use_graph=True) and agent chains (use_graph=False) - Iterates until research complete or constraints met

Usage:

DeepResearchFlow

File: src/orchestrator/research_flow.py

Pattern: Planner โ†’ Parallel iterative loops per section โ†’ Synthesizer

Agents Used: - PlannerAgent: Breaks query into report sections - IterativeResearchFlow: Per-section research (parallel) - LongWriterAgent or ProofreaderAgent: Final synthesis

Features: - Uses WorkflowManager for parallel execution - Budget tracking per section and globally - State synchronization across parallel loops - Supports graph execution and agent chains

Usage:

Graph Orchestrator

File: src/orchestrator/graph_orchestrator.py

Purpose: Graph-based execution using Pydantic AI agents as nodes

Features: - Uses graph execution (use_graph=True) or agent chains (use_graph=False) as fallback - Routes based on research mode (iterative/deep/auto) - Streams AgentEvent objects for UI - Uses GraphExecutionContext to manage execution state

Node Types: - Agent Nodes: Execute Pydantic AI agents - State Nodes: Update or read workflow state - Decision Nodes: Make routing decisions - Parallel Nodes: Execute multiple nodes concurrently

Edge Types: - Sequential Edges: Always traversed - Conditional Edges: Traversed based on condition - Parallel Edges: Used for parallel execution branches

Special Node Handling:

The GraphOrchestrator has special handling for certain nodes:

  • execute_tools node: State node that uses search_handler to execute searches and add evidence to workflow state
  • parallel_loops node: Parallel node that executes IterativeResearchFlow instances for each section in deep research mode
  • synthesizer node: Agent node that calls LongWriterAgent.write_report() directly with ReportDraft instead of using agent.run()
  • writer node: Agent node that calls WriterAgent.write_report() directly with findings instead of using agent.run()

GraphExecutionContext:

The orchestrator uses GraphExecutionContext to manage execution state: - Tracks current node, visited nodes, and node results - Manages workflow state and budget tracker - Provides methods to store and retrieve node execution results

Orchestrator Factory

File: src/orchestrator_factory.py

Purpose: Factory for creating orchestrators

Modes: - Simple: Legacy orchestrator (backward compatible) - Advanced: Magentic orchestrator (requires OpenAI API key) - Auto-detect: Chooses based on API key availability

Usage:

Magentic Orchestrator

File: src/orchestrator_magentic.py

Purpose: Multi-agent coordination using Microsoft Agent Framework

Features: - Uses agent-framework-core - ChatAgent pattern with internal LLMs per agent - MagenticBuilder with participants: - searcher: SearchAgent (wraps SearchHandler) - hypothesizer: HypothesisAgent (generates hypotheses) - judge: JudgeAgent (evaluates evidence) - reporter: ReportAgent (generates final report) - Manager orchestrates agents via chat client (OpenAI or HuggingFace) - Event-driven: converts Magentic events to AgentEvent for UI streaming via _process_event() method - Supports max rounds, stall detection, and reset handling

Event Processing:

The orchestrator processes Magentic events and converts them to AgentEvent: - MagenticOrchestratorMessageEvent โ†’ AgentEvent with type based on message content - MagenticAgentMessageEvent โ†’ AgentEvent with type based on agent name - MagenticAgentDeltaEvent โ†’ AgentEvent for streaming updates - MagenticFinalResultEvent โ†’ AgentEvent with type "complete"

Requirements: - agent-framework-core package - OpenAI API key or HuggingFace authentication

Hierarchical Orchestrator

File: src/orchestrator_hierarchical.py

Purpose: Hierarchical orchestrator using middleware and sub-teams

Features: - Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge - Adapts Magentic ChatAgent to SubIterationTeam protocol - Event-driven via asyncio.Queue for coordination - Supports sub-iteration patterns for complex research tasks

Legacy Simple Mode

File: src/legacy_orchestrator.py

Purpose: Linear search-judge-synthesize loop

Features: - Uses SearchHandlerProtocol and JudgeHandlerProtocol - Generator-based design yielding AgentEvent objects - Backward compatibility for simple use cases

State Initialization

All orchestrators must initialize workflow state:

Event Streaming

All orchestrators yield AgentEvent objects:

Event Types: - started: Research started - searching: Search in progress - search_complete: Search completed - judging: Evidence evaluation in progress - judge_complete: Evidence evaluation completed - looping: Iteration in progress - hypothesizing: Generating hypotheses - analyzing: Statistical analysis in progress - analysis_complete: Statistical analysis completed - synthesizing: Synthesizing results - complete: Research completed - error: Error occurred - streaming: Streaming update (delta events)

Event Structure:

See Also

\ No newline at end of file + Orchestrators - The DETERMINATOR
Skip to content

Orchestrators Architecture

DeepCritical supports multiple orchestration patterns for research workflows.

Research Flows

IterativeResearchFlow

File: src/orchestrator/research_flow.py

Pattern: Generate observations โ†’ Evaluate gaps โ†’ Select tools โ†’ Execute โ†’ Judge โ†’ Continue/Complete

Agents Used: - KnowledgeGapAgent: Evaluates research completeness - ToolSelectorAgent: Selects tools for addressing gaps - ThinkingAgent: Generates observations - WriterAgent: Creates final report - JudgeHandler: Assesses evidence sufficiency

Features: - Tracks iterations, time, budget - Supports graph execution (use_graph=True) and agent chains (use_graph=False) - Iterates until research complete or constraints met

Usage:

DeepResearchFlow

File: src/orchestrator/research_flow.py

Pattern: Planner โ†’ Parallel iterative loops per section โ†’ Synthesizer

Agents Used: - PlannerAgent: Breaks query into report sections - IterativeResearchFlow: Per-section research (parallel) - LongWriterAgent or ProofreaderAgent: Final synthesis

Features: - Uses WorkflowManager for parallel execution - Budget tracking per section and globally - State synchronization across parallel loops - Supports graph execution and agent chains

Usage:

Graph Orchestrator

File: src/orchestrator/graph_orchestrator.py

Purpose: Graph-based execution using Pydantic AI agents as nodes

Features: - Uses graph execution (use_graph=True) or agent chains (use_graph=False) as fallback - Routes based on research mode (iterative/deep/auto) - Streams AgentEvent objects for UI - Uses GraphExecutionContext to manage execution state

Node Types: - Agent Nodes: Execute Pydantic AI agents - State Nodes: Update or read workflow state - Decision Nodes: Make routing decisions - Parallel Nodes: Execute multiple nodes concurrently

Edge Types: - Sequential Edges: Always traversed - Conditional Edges: Traversed based on condition - Parallel Edges: Used for parallel execution branches

Special Node Handling:

The GraphOrchestrator has special handling for certain nodes:

  • execute_tools node: State node that uses search_handler to execute searches and add evidence to workflow state
  • parallel_loops node: Parallel node that executes IterativeResearchFlow instances for each section in deep research mode
  • synthesizer node: Agent node that calls LongWriterAgent.write_report() directly with ReportDraft instead of using agent.run()
  • writer node: Agent node that calls WriterAgent.write_report() directly with findings instead of using agent.run()

GraphExecutionContext:

The orchestrator uses GraphExecutionContext to manage execution state: - Tracks current node, visited nodes, and node results - Manages workflow state and budget tracker - Provides methods to store and retrieve node execution results

Orchestrator Factory

File: src/orchestrator_factory.py

Purpose: Factory for creating orchestrators

Modes: - Simple: Legacy orchestrator (backward compatible) - Advanced: Magentic orchestrator (requires OpenAI API key) - Auto-detect: Chooses based on API key availability

Usage:

Magentic Orchestrator

File: src/orchestrator_magentic.py

Purpose: Multi-agent coordination using Microsoft Agent Framework

Features: - Uses agent-framework-core - ChatAgent pattern with internal LLMs per agent - MagenticBuilder with participants: - searcher: SearchAgent (wraps SearchHandler) - hypothesizer: HypothesisAgent (generates hypotheses) - judge: JudgeAgent (evaluates evidence) - reporter: ReportAgent (generates final report) - Manager orchestrates agents via chat client (OpenAI or HuggingFace) - Event-driven: converts Magentic events to AgentEvent for UI streaming via _process_event() method - Supports max rounds, stall detection, and reset handling

Event Processing:

The orchestrator processes Magentic events and converts them to AgentEvent: - MagenticOrchestratorMessageEvent โ†’ AgentEvent with type based on message content - MagenticAgentMessageEvent โ†’ AgentEvent with type based on agent name - MagenticAgentDeltaEvent โ†’ AgentEvent for streaming updates - MagenticFinalResultEvent โ†’ AgentEvent with type "complete"

Requirements: - agent-framework-core package - OpenAI API key or HuggingFace authentication

Hierarchical Orchestrator

File: src/orchestrator_hierarchical.py

Purpose: Hierarchical orchestrator using middleware and sub-teams

Features: - Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge - Adapts Magentic ChatAgent to SubIterationTeam protocol - Event-driven via asyncio.Queue for coordination - Supports sub-iteration patterns for complex research tasks

Legacy Simple Mode

File: src/legacy_orchestrator.py

Purpose: Linear search-judge-synthesize loop

Features: - Uses SearchHandlerProtocol and JudgeHandlerProtocol - Generator-based design yielding AgentEvent objects - Backward compatibility for simple use cases

State Initialization

All orchestrators must initialize workflow state:

Event Streaming

All orchestrators yield AgentEvent objects:

Event Types: - started: Research started - searching: Search in progress - search_complete: Search completed - judging: Evidence evaluation in progress - judge_complete: Evidence evaluation completed - looping: Iteration in progress - hypothesizing: Generating hypotheses - analyzing: Statistical analysis in progress - analysis_complete: Statistical analysis completed - synthesizing: Synthesizing results - complete: Research completed - error: Error occurred - streaming: Streaming update (delta events)

Event Structure:

See Also

\ No newline at end of file diff --git a/site/architecture/services/index.html b/site/architecture/services/index.html index f09467c7..100a2966 100644 --- a/site/architecture/services/index.html +++ b/site/architecture/services/index.html @@ -27,4 +27,4 @@ if settings.has_openai_key: # Use OpenAI embeddings for RAG pass -

See Also

\ No newline at end of file +

See Also

\ No newline at end of file diff --git a/site/architecture/tools/index.html b/site/architecture/tools/index.html index afaefe04..0efb987e 100644 --- a/site/architecture/tools/index.html +++ b/site/architecture/tools/index.html @@ -16,4 +16,4 @@ # Execute search result = await search_handler.execute("query", max_results_per_tool=10) -

See Also

\ No newline at end of file +

See Also

\ No newline at end of file diff --git a/site/architecture/workflow-diagrams/index.html b/site/architecture/workflow-diagrams/index.html index 5f530164..418df642 100644 --- a/site/architecture/workflow-diagrams/index.html +++ b/site/architecture/workflow-diagrams/index.html @@ -485,4 +485,4 @@ Formatting :r3, after r2, 10s section Manager Synthesis - Final synthesis :f1, after r3, 10s

Key Differences from Original Designยถ

Aspect Original (Judge-in-Loop) New (Magentic)
Control Flow Fixed sequential phases Dynamic agent selection
Quality Control Separate Judge Agent Manager assessment built-in
Retry Logic Phase-level with feedback Agent-level with adaptation
Flexibility Rigid 4-phase pipeline Adaptive workflow
Complexity 5 agents (including Judge) 4 agents (no Judge)
Progress Tracking Manual state management Built-in round/stall detection
Agent Coordination Sequential handoff Manager-driven dynamic selection
Error Recovery Retry same phase Try different agent or replan

Simplified Design Principlesยถ

  1. Manager is Intelligent: LLM-powered manager handles planning, selection, and quality assessment
  2. No Separate Judge: Manager's assessment phase replaces dedicated Judge Agent
  3. Dynamic Workflow: Agents can be called multiple times in any order based on need
  4. Built-in Safety: max_round_count (15) and max_stall_count (3) prevent infinite loops
  5. Event-Driven UI: Real-time streaming updates to Gradio interface
  6. MCP-Powered Tools: All external capabilities via Model Context Protocol
  7. Shared Context: Centralized state accessible to all agents
  8. Progress Awareness: Manager tracks what's been done and what's needed

Legendยถ


Implementation Highlightsยถ

Simple 4-Agent Setup:

Manager handles quality assessment in its instructions: - Checks hypothesis quality (testable, novel, clear) - Validates search results (relevant, authoritative, recent) - Assesses analysis soundness (methodology, evidence, conclusions) - Ensures report completeness (all sections, proper citations)

No separate Judge Agent needed - manager does it all!


Document Version: 2.0 (Magentic Simplified) Last Updated: 2025-11-24 Architecture: Microsoft Magentic Orchestration Pattern Agents: 4 (Hypothesis, Search, Analysis, Report) + 1 Manager License: MIT

See Alsoยถ

\ No newline at end of file + Final synthesis :f1, after r3, 10s

Key Differences from Original Designยถ

Aspect Original (Judge-in-Loop) New (Magentic)
Control Flow Fixed sequential phases Dynamic agent selection
Quality Control Separate Judge Agent Manager assessment built-in
Retry Logic Phase-level with feedback Agent-level with adaptation
Flexibility Rigid 4-phase pipeline Adaptive workflow
Complexity 5 agents (including Judge) 4 agents (no Judge)
Progress Tracking Manual state management Built-in round/stall detection
Agent Coordination Sequential handoff Manager-driven dynamic selection
Error Recovery Retry same phase Try different agent or replan

Simplified Design Principlesยถ

  1. Manager is Intelligent: LLM-powered manager handles planning, selection, and quality assessment
  2. No Separate Judge: Manager's assessment phase replaces dedicated Judge Agent
  3. Dynamic Workflow: Agents can be called multiple times in any order based on need
  4. Built-in Safety: max_round_count (15) and max_stall_count (3) prevent infinite loops
  5. Event-Driven UI: Real-time streaming updates to Gradio interface
  6. MCP-Powered Tools: All external capabilities via Model Context Protocol
  7. Shared Context: Centralized state accessible to all agents
  8. Progress Awareness: Manager tracks what's been done and what's needed

Legendยถ


Implementation Highlightsยถ

Simple 4-Agent Setup:

Manager handles quality assessment in its instructions: - Checks hypothesis quality (testable, novel, clear) - Validates search results (relevant, authoritative, recent) - Assesses analysis soundness (methodology, evidence, conclusions) - Ensures report completeness (all sections, proper citations)

No separate Judge Agent needed - manager does it all!


Document Version: 2.0 (Magentic Simplified) Last Updated: 2025-11-24 Architecture: Microsoft Magentic Orchestration Pattern Agents: 4 (Hypothesis, Search, Analysis, Report) + 1 Manager License: MIT

See Alsoยถ

\ No newline at end of file diff --git a/site/configuration/index.html b/site/configuration/index.html index a6801b4a..b71cff6b 100644 --- a/site/configuration/index.html +++ b/site/configuration/index.html @@ -121,4 +121,4 @@ # Web search is configured pass

API Key Retrieval

Get the API key for the configured provider:

For OpenAI-specific operations (e.g., Magentic mode):

Configuration Usage in Codebase

The configuration system is used throughout the codebase:

LLM Factory

The LLM factory uses settings to create appropriate models:

Embedding Service

The embedding service uses local embedding model configuration:

Orchestrator Factory

The orchestrator factory uses settings to determine mode:

Environment Variables Reference

Required (at least one LLM)

LLM Configuration Variables

Embedding Configuration Variables

Web Search Configuration Variables

PubMed Configuration Variables

Agent Configuration Variables

Budget Configuration Variables

RAG Configuration Variables

ChromaDB Configuration Variables

External Services Variables

Logging Configuration Variables

Validation

Settings are validated on load using Pydantic validation:

Validation Examples

The max_iterations field has range validation:

The llm_provider field has literal validation:

Error Handling

Configuration errors raise ConfigurationError from src/utils/exceptions.py:

```22:25:src/utils/exceptions.py class ConfigurationError(DeepCriticalError): """Raised when configuration is invalid."""

pass
-

```

Error Handling Example

python from src.utils.config import settings from src.utils.exceptions import ConfigurationError try: api_key = settings.get_api_key() except ConfigurationError as e: print(f"Configuration error: {e}")

Common Configuration Errors

  1. Missing API Key: When get_api_key() is called but the required API key is not set
  2. Invalid Provider: When llm_provider is set to an unsupported value
  3. Out of Range: When numeric values exceed their min/max constraints
  4. Invalid Literal: When enum fields receive unsupported values

Configuration Best Practices

  1. Use .env File: Store sensitive keys in .env file (add to .gitignore)
  2. Check Availability: Use properties like has_openai_key before accessing API keys
  3. Handle Errors: Always catch ConfigurationError when calling get_api_key()
  4. Validate Early: Configuration is validated on import, so errors surface immediately
  5. Use Defaults: Leverage sensible defaults for optional configuration

Future Enhancements

The following configurations are planned for future phases:

  1. Additional LLM Providers: DeepSeek, OpenRouter, Gemini, Perplexity, Azure OpenAI, Local models
  2. Model Selection: Reasoning/main/fast model configuration
  3. Service Integration: Additional service integrations and configurations
\ No newline at end of file +

```

Error Handling Example

python from src.utils.config import settings from src.utils.exceptions import ConfigurationError try: api_key = settings.get_api_key() except ConfigurationError as e: print(f"Configuration error: {e}")

Common Configuration Errors

  1. Missing API Key: When get_api_key() is called but the required API key is not set
  2. Invalid Provider: When llm_provider is set to an unsupported value
  3. Out of Range: When numeric values exceed their min/max constraints
  4. Invalid Literal: When enum fields receive unsupported values

Configuration Best Practices

  1. Use .env File: Store sensitive keys in .env file (add to .gitignore)
  2. Check Availability: Use properties like has_openai_key before accessing API keys
  3. Handle Errors: Always catch ConfigurationError when calling get_api_key()
  4. Validate Early: Configuration is validated on import, so errors surface immediately
  5. Use Defaults: Leverage sensible defaults for optional configuration

Future Enhancements

The following configurations are planned for future phases:

  1. Additional LLM Providers: DeepSeek, OpenRouter, Gemini, Perplexity, Azure OpenAI, Local models
  2. Model Selection: Reasoning/main/fast model configuration
  3. Service Integration: Additional service integrations and configurations
\ No newline at end of file diff --git a/site/contributing/code-quality/index.html b/site/contributing/code-quality/index.html index 932d4fe6..33d5cee4 100644 --- a/site/contributing/code-quality/index.html +++ b/site/contributing/code-quality/index.html @@ -9,4 +9,4 @@ # Serve documentation locally (http://127.0.0.1:8000) uv run mkdocs serve -

The documentation site is published at: https://deepcritical.github.io/GradioDemo/

Docstrings

Example:

Code Comments

See Also

\ No newline at end of file +

The documentation site is published at: https://deepcritical.github.io/GradioDemo/

Docstrings

Example:

Code Comments

See Also

\ No newline at end of file diff --git a/site/contributing/code-style/index.html b/site/contributing/code-style/index.html index df91363a..e99db77e 100644 --- a/site/contributing/code-style/index.html +++ b/site/contributing/code-style/index.html @@ -20,4 +20,4 @@ uv run mypy src

This ensures commands run in the correct virtual environment managed by uv.

Type Safety

Pydantic Models

Async Patterns

loop = asyncio.get_running_loop()
 result = await loop.run_in_executor(None, cpu_bound_function, args)
-

Common Pitfalls

  1. Blocking the event loop: Never use sync I/O in async functions
  2. Missing type hints: All functions must have complete type annotations
  3. Global mutable state: Use ContextVar or pass via parameters
  4. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)

See Also

\ No newline at end of file +

Common Pitfalls

  1. Blocking the event loop: Never use sync I/O in async functions
  2. Missing type hints: All functions must have complete type annotations
  3. Global mutable state: Use ContextVar or pass via parameters
  4. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)

See Also

\ No newline at end of file diff --git a/site/contributing/error-handling/index.html b/site/contributing/error-handling/index.html index e94f2a29..bd03e89e 100644 --- a/site/contributing/error-handling/index.html +++ b/site/contributing/error-handling/index.html @@ -6,4 +6,4 @@ result = await api_call() except httpx.HTTPError as e: raise SearchError(f"API call failed: {e}") from e -

See Also

\ No newline at end of file +

See Also

\ No newline at end of file diff --git a/site/contributing/implementation-patterns/index.html b/site/contributing/implementation-patterns/index.html index 59825fb4..05c64674 100644 --- a/site/contributing/implementation-patterns/index.html +++ b/site/contributing/implementation-patterns/index.html @@ -7,4 +7,4 @@ async def search(self, query: str, max_results: int = 10) -> list[Evidence]: # Implementation return evidence_list -

Judge Handlers

Agent Factory Pattern

State Management

Singleton Pattern

Use @lru_cache(maxsize=1) for singletons:

See Also

\ No newline at end of file +

Judge Handlers

Agent Factory Pattern

State Management

Singleton Pattern

Use @lru_cache(maxsize=1) for singletons:

See Also

\ No newline at end of file diff --git a/site/contributing/index.html b/site/contributing/index.html index d84a1158..baa6ee0e 100644 --- a/site/contributing/index.html +++ b/site/contributing/index.html @@ -49,4 +49,4 @@ uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m "not openai" -p no:logfire
  1. Commit and push:
git commit -m "Description of changes"
 git push origin yourname-feature-name
-
  1. Create a pull request on GitHub

Development Guidelines

Code Style

Error Handling

Testing

Implementation Patterns

Prompt Engineering

Code Quality

MCP Integration

MCP Tools

Gradio MCP Server

Common Pitfalls

  1. Blocking the event loop: Never use sync I/O in async functions
  2. Missing type hints: All functions must have complete type annotations
  3. Hallucinated citations: Always validate references
  4. Global mutable state: Use ContextVar or pass via parameters
  5. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
  6. Rate limiting: Always implement for external APIs
  7. Error chaining: Always use from e when raising exceptions

Key Principles

  1. Type Safety First: All code must pass mypy --strict
  2. Async Everything: All I/O must be async
  3. Test-Driven: Write tests before implementation
  4. No Hallucinations: Validate all citations
  5. Graceful Degradation: Support free tier (HF Inference) when no API keys
  6. Lazy Loading: Don't require optional dependencies at import time
  7. Structured Logging: Use structlog, never print()
  8. Error Chaining: Always preserve exception context

Pull Request Process

  1. Ensure all checks pass: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m "not openai" -p no:logfire
  2. Update documentation if needed
  3. Add tests for new features
  4. Update CHANGELOG if applicable
  5. Request review from maintainers
  6. Address review feedback
  7. Wait for approval before merging

Project Structure

Questions?

Thank you for contributing to The DETERMINATOR!

\ No newline at end of file +
  1. Create a pull request on GitHub

Development Guidelines

Code Style

Error Handling

Testing

Implementation Patterns

Prompt Engineering

Code Quality

MCP Integration

MCP Tools

Gradio MCP Server

Common Pitfalls

  1. Blocking the event loop: Never use sync I/O in async functions
  2. Missing type hints: All functions must have complete type annotations
  3. Hallucinated citations: Always validate references
  4. Global mutable state: Use ContextVar or pass via parameters
  5. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
  6. Rate limiting: Always implement for external APIs
  7. Error chaining: Always use from e when raising exceptions

Key Principles

  1. Type Safety First: All code must pass mypy --strict
  2. Async Everything: All I/O must be async
  3. Test-Driven: Write tests before implementation
  4. No Hallucinations: Validate all citations
  5. Graceful Degradation: Support free tier (HF Inference) when no API keys
  6. Lazy Loading: Don't require optional dependencies at import time
  7. Structured Logging: Use structlog, never print()
  8. Error Chaining: Always preserve exception context

Pull Request Process

  1. Ensure all checks pass: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m "not openai" -p no:logfire
  2. Update documentation if needed
  3. Add tests for new features
  4. Update CHANGELOG if applicable
  5. Request review from maintainers
  6. Address review feedback
  7. Wait for approval before merging

Project Structure

Questions?

Thank you for contributing to The DETERMINATOR!

\ No newline at end of file diff --git a/site/contributing/prompt-engineering/index.html b/site/contributing/prompt-engineering/index.html index 96e541a4..b21adf5f 100644 --- a/site/contributing/prompt-engineering/index.html +++ b/site/contributing/prompt-engineering/index.html @@ -1 +1 @@ - Prompt Engineering & Citation Validation - The DETERMINATOR
Skip to content

Prompt Engineering & Citation Validation

This document outlines prompt engineering guidelines and citation validation rules.

Judge Prompts

  • System prompt in src/prompts/judge.py
  • Format evidence with truncation (1500 chars per item)
  • Handle empty evidence case separately
  • Always request structured JSON output
  • Use format_user_prompt() and format_empty_evidence_prompt() helpers

Hypothesis Prompts

  • Use diverse evidence selection (MMR algorithm)
  • Sentence-aware truncation (truncate_at_sentence())
  • Format: Drug โ†’ Target โ†’ Pathway โ†’ Effect
  • System prompt emphasizes mechanistic reasoning
  • Use format_hypothesis_prompt() with embeddings for diversity

Report Prompts

  • Include full citation details for validation
  • Use diverse evidence selection (n=20)
  • CRITICAL: Emphasize citation validation rules
  • Format hypotheses with support/contradiction counts
  • System prompt includes explicit JSON structure requirements

Citation Validation

  • ALWAYS validate references before returning reports
  • Use validate_references() from src/utils/citation_validator.py
  • Remove hallucinated citations (URLs not in evidence)
  • Log warnings for removed citations
  • Never trust LLM-generated citations without validation

Citation Validation Rules

  1. Every reference URL must EXACTLY match a provided evidence URL
  2. Do NOT invent, fabricate, or hallucinate any references
  3. Do NOT modify paper titles, authors, dates, or URLs
  4. If unsure about a citation, OMIT it rather than guess
  5. Copy URLs exactly as provided - do not create similar-looking URLs

Evidence Selection

  • Use select_diverse_evidence() for MMR-based selection
  • Balance relevance vs diversity (lambda=0.7 default)
  • Sentence-aware truncation preserves meaning
  • Limit evidence per prompt to avoid context overflow

See Also

\ No newline at end of file + Prompt Engineering & Citation Validation - The DETERMINATOR
Skip to content

Prompt Engineering & Citation Validation

This document outlines prompt engineering guidelines and citation validation rules.

Judge Prompts

  • System prompt in src/prompts/judge.py
  • Format evidence with truncation (1500 chars per item)
  • Handle empty evidence case separately
  • Always request structured JSON output
  • Use format_user_prompt() and format_empty_evidence_prompt() helpers

Hypothesis Prompts

  • Use diverse evidence selection (MMR algorithm)
  • Sentence-aware truncation (truncate_at_sentence())
  • Format: Drug โ†’ Target โ†’ Pathway โ†’ Effect
  • System prompt emphasizes mechanistic reasoning
  • Use format_hypothesis_prompt() with embeddings for diversity

Report Prompts

  • Include full citation details for validation
  • Use diverse evidence selection (n=20)
  • CRITICAL: Emphasize citation validation rules
  • Format hypotheses with support/contradiction counts
  • System prompt includes explicit JSON structure requirements

Citation Validation

  • ALWAYS validate references before returning reports
  • Use validate_references() from src/utils/citation_validator.py
  • Remove hallucinated citations (URLs not in evidence)
  • Log warnings for removed citations
  • Never trust LLM-generated citations without validation

Citation Validation Rules

  1. Every reference URL must EXACTLY match a provided evidence URL
  2. Do NOT invent, fabricate, or hallucinate any references
  3. Do NOT modify paper titles, authors, dates, or URLs
  4. If unsure about a citation, OMIT it rather than guess
  5. Copy URLs exactly as provided - do not create similar-looking URLs

Evidence Selection

  • Use select_diverse_evidence() for MMR-based selection
  • Balance relevance vs diversity (lambda=0.7 default)
  • Sentence-aware truncation preserves meaning
  • Limit evidence per prompt to avoid context overflow

See Also

\ No newline at end of file diff --git a/site/contributing/testing/index.html b/site/contributing/testing/index.html index 077d9edd..e567e723 100644 --- a/site/contributing/testing/index.html +++ b/site/contributing/testing/index.html @@ -34,4 +34,4 @@ assert len(results) <= 3

Test Coverage

Terminal Coverage Report

uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m "not openai" -p no:logfire
 

This shows coverage with missing lines highlighted in the terminal output.

HTML Coverage Report

uv run pytest --cov=src --cov-report=html -p no:logfire
-

This generates an HTML coverage report in htmlcov/index.html. Open this file in your browser to see detailed coverage information.

Coverage Goals

See Also

\ No newline at end of file +

This generates an HTML coverage report in htmlcov/index.html. Open this file in your browser to see detailed coverage information.

Coverage Goals

See Also

\ No newline at end of file diff --git a/site/getting-started/examples/index.html b/site/getting-started/examples/index.html index 8f577a4b..f3282720 100644 --- a/site/getting-started/examples/index.html +++ b/site/getting-started/examples/index.html @@ -46,4 +46,4 @@ MAX_ITERATIONS=20 DEFAULT_TOKEN_LIMIT=200000 USE_GRAPH_EXECUTION=true -

Next Steps

\ No newline at end of file +

Next Steps

\ No newline at end of file diff --git a/site/getting-started/installation/index.html b/site/getting-started/installation/index.html index d3673d6b..840449b1 100644 --- a/site/getting-started/installation/index.html +++ b/site/getting-started/installation/index.html @@ -24,4 +24,4 @@

See the Configuration Guide for all available options.

6. Verify Installation

Run the application:

uv run gradio run src/app.py
 

Open your browser to http://localhost:7860 to verify the installation.

Development Setup

For development, install dev dependencies:

uv sync --all-extras --dev
 

Install pre-commit hooks:

uv run pre-commit install
-

Troubleshooting

Common Issues

Import Errors: - Ensure you've installed all required dependencies - Check that Python 3.11+ is being used

API Key Errors: - Verify your .env file is in the project root - Check that API keys are correctly formatted - Ensure at least one LLM provider is configured

Module Not Found: - Run uv sync or pip install -e . again - Check that you're in the correct virtual environment

Port Already in Use: - Change the port in src/app.py or use environment variable - Kill the process using port 7860

Next Steps

\ No newline at end of file +

Troubleshooting

Common Issues

Import Errors: - Ensure you've installed all required dependencies - Check that Python 3.11+ is being used

API Key Errors: - Verify your .env file is in the project root - Check that API keys are correctly formatted - Ensure at least one LLM provider is configured

Module Not Found: - Run uv sync or pip install -e . again - Check that you're in the correct virtual environment

Port Already in Use: - Change the port in src/app.py or use environment variable - Kill the process using port 7860

Next Steps

\ No newline at end of file diff --git a/site/getting-started/mcp-integration/index.html b/site/getting-started/mcp-integration/index.html index f0c0db26..be440cf9 100644 --- a/site/getting-started/mcp-integration/index.html +++ b/site/getting-started/mcp-integration/index.html @@ -32,4 +32,4 @@ } } } -

Next Steps

\ No newline at end of file +

Next Steps

\ No newline at end of file diff --git a/site/getting-started/quick-start/index.html b/site/getting-started/quick-start/index.html index 2f6bd2d7..a4bccd6e 100644 --- a/site/getting-started/quick-start/index.html +++ b/site/getting-started/quick-start/index.html @@ -41,4 +41,4 @@

Complex Query

Review the evidence for using metformin as an anti-aging intervention, 
 including clinical trials, mechanisms of action, and safety profile.
 

Clinical Trial Query

What are the active clinical trials investigating Alzheimer's disease treatments?
-

Next Steps

\ No newline at end of file +

Next Steps

\ No newline at end of file diff --git a/site/index.html b/site/index.html index 8d8741f4..99a45677 100644 --- a/site/index.html +++ b/site/index.html @@ -13,4 +13,4 @@ # Start the Gradio app uv run gradio run src/app.py -

Open your browser to http://localhost:7860.

For detailed installation and setup instructions, see the Getting Started Guide.

Architecture

The DETERMINATOR uses a Vertical Slice Architecture:

  1. Search Slice: Retrieving evidence from multiple sources (web, PubMed, ClinicalTrials.gov, Europe PMC, RAG) based on query analysis
  2. Judge Slice: Evaluating evidence quality using LLMs
  3. Orchestrator Slice: Managing the research loop and UI

The system supports three main research patterns:

Learn more about the Architecture.

Documentation

\ No newline at end of file +

Open your browser to http://localhost:7860.

For detailed installation and setup instructions, see the Getting Started Guide.

Architecture

The DETERMINATOR uses a Vertical Slice Architecture:

  1. Search Slice: Retrieving evidence from multiple sources (web, PubMed, ClinicalTrials.gov, Europe PMC, RAG) based on query analysis
  2. Judge Slice: Evaluating evidence quality using LLMs
  3. Orchestrator Slice: Managing the research loop and UI

The system supports three main research patterns:

Learn more about the Architecture.

Documentation

\ No newline at end of file diff --git a/site/license/index.html b/site/license/index.html index 74f9f7f3..9b7a624f 100644 --- a/site/license/index.html +++ b/site/license/index.html @@ -1 +1 @@ - License - The DETERMINATOR
Skip to content

License

DeepCritical is licensed under the MIT License.

MIT License

Copyright (c) 2024 DeepCritical Team

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

\ No newline at end of file + License - The DETERMINATOR

License

\ No newline at end of file diff --git a/site/overview/architecture/index.html b/site/overview/architecture/index.html index d2b148b0..ea75d5a4 100644 --- a/site/overview/architecture/index.html +++ b/site/overview/architecture/index.html @@ -1 +1 @@ - Architecture Overview - The DETERMINATOR
Skip to content

Architecture Overview

The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations). The system automatically determines if medical knowledge sources are needed and adapts its search strategy accordingly. It supports multiple orchestration patterns, graph-based execution, parallel research workflows, and long-running task management with real-time streaming.

Core Architecture

Orchestration Patterns

  1. Graph Orchestrator (src/orchestrator/graph_orchestrator.py):
  2. Graph-based execution using Pydantic AI agents as nodes
  3. Supports both iterative and deep research patterns
  4. Node types: Agent, State, Decision, Parallel
  5. Edge types: Sequential, Conditional, Parallel
  6. Conditional routing based on knowledge gaps, budget, and iterations
  7. Parallel execution for concurrent research loops
  8. Event streaming via AsyncGenerator[AgentEvent] for real-time UI updates
  9. Fallback to agent chains when graph execution is disabled

  10. Deep Research Flow (src/orchestrator/research_flow.py):

  11. Pattern: Planner โ†’ Parallel Iterative Loops (one per section) โ†’ Synthesis
  12. Uses PlannerAgent to break query into report sections
  13. Runs IterativeResearchFlow instances in parallel per section via WorkflowManager
  14. Synthesizes results using LongWriterAgent or ProofreaderAgent
  15. Supports both graph execution (use_graph=True) and agent chains (use_graph=False)
  16. Budget tracking per section and globally
  17. State synchronization across parallel loops

  18. Iterative Research Flow (src/orchestrator/research_flow.py):

  19. Pattern: Generate observations โ†’ Evaluate gaps โ†’ Select tools โ†’ Execute โ†’ Judge โ†’ Continue/Complete
  20. Uses KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent, WriterAgent
  21. JudgeHandler assesses evidence sufficiency
  22. Iterates until research complete or constraints met (iterations, time, tokens)
  23. Supports graph execution and agent chains

  24. Magentic Orchestrator (src/orchestrator_magentic.py):

  25. Multi-agent coordination using agent-framework-core
  26. ChatAgent pattern with internal LLMs per agent
  27. Uses MagenticBuilder with participants: searcher, hypothesizer, judge, reporter
  28. Manager orchestrates agents via OpenAIChatClient
  29. Requires OpenAI API key (function calling support)
  30. Event-driven: converts Magentic events to AgentEvent for UI streaming
  31. Supports long-running workflows with max rounds and stall/reset handling

  32. Hierarchical Orchestrator (src/orchestrator_hierarchical.py):

  33. Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge
  34. Adapts Magentic ChatAgent to SubIterationTeam protocol
  35. Event-driven via asyncio.Queue for coordination
  36. Supports sub-iteration patterns for complex research tasks

  37. Legacy Simple Mode (src/legacy_orchestrator.py):

  38. Linear search-judge-synthesize loop
  39. Uses SearchHandlerProtocol and JudgeHandlerProtocol
  40. Generator-based design yielding AgentEvent objects
  41. Backward compatibility for simple use cases

Long-Running Task Support

The system is designed for long-running research tasks with comprehensive state management and streaming:

  1. Event Streaming:
  2. All orchestrators yield AgentEvent objects via AsyncGenerator
  3. Real-time UI updates through Gradio chat interface
  4. Event types: started, searching, search_complete, judging, judge_complete, looping, synthesizing, hypothesizing, complete, error
  5. Metadata includes iteration numbers, tool names, result counts, durations

  6. Budget Tracking (src/middleware/budget_tracker.py):

  7. Per-loop and global budget management
  8. Tracks: tokens, time (seconds), iterations
  9. Budget enforcement at decision nodes
  10. Token estimation (~4 chars per token)
  11. Early termination when budgets exceeded
  12. Budget summaries for monitoring

  13. Workflow Manager (src/middleware/workflow_manager.py):

  14. Coordinates parallel research loops
  15. Tracks loop status: pending, running, completed, failed, cancelled
  16. Synchronizes evidence between loops and global state
  17. Handles errors per loop (doesn't fail all if one fails)
  18. Supports loop cancellation and timeout handling
  19. Evidence deduplication across parallel loops

  20. State Management (src/middleware/state_machine.py):

  21. Thread-safe isolation using ContextVar for concurrent requests
  22. WorkflowState tracks: evidence, conversation history, embedding service
  23. Evidence deduplication by URL
  24. Semantic search via embedding service
  25. State persistence across long-running workflows
  26. Supports both iterative and deep research patterns

  27. Gradio UI (src/app.py):

  28. Real-time streaming of research progress
  29. Accordion-based UI for pending/done operations
  30. OAuth integration (HuggingFace)
  31. Multiple backend support (API keys, free tier)
  32. Handles long-running tasks with progress indicators
  33. Event accumulation for pending operations

Graph Architecture

The graph orchestrator (src/orchestrator/graph_orchestrator.py) implements a flexible graph-based execution model:

Node Types:

  • Agent Nodes: Execute Pydantic AI agents (e.g., KnowledgeGapAgent, ToolSelectorAgent)
  • State Nodes: Update or read workflow state (evidence, conversation)
  • Decision Nodes: Make routing decisions (research complete?, budget exceeded?)
  • Parallel Nodes: Execute multiple nodes concurrently (parallel research loops)

Edge Types:

  • Sequential Edges: Always traversed (no condition)
  • Conditional Edges: Traversed based on condition (e.g., if research complete โ†’ writer, else โ†’ tool selector)
  • Parallel Edges: Used for parallel execution branches

Graph Patterns:

  • Iterative Graph: [Input] โ†’ [Thinking] โ†’ [Knowledge Gap] โ†’ [Decision: Complete?] โ†’ [Tool Selector] or [Writer]
  • Deep Research Graph: [Input] โ†’ [Planner] โ†’ [Parallel Iterative Loops] โ†’ [Synthesizer]

Execution Flow:

  1. Graph construction from nodes and edges
  2. Graph validation (no cycles, all nodes reachable)
  3. Graph execution from entry node
  4. Node execution based on type
  5. Edge evaluation for next node(s)
  6. Parallel execution via asyncio.gather()
  7. State updates at state nodes
  8. Event streaming for UI

Key Components

  • Orchestrators: Multiple orchestration patterns (src/orchestrator/, src/orchestrator_*.py)
  • Research Flows: Iterative and deep research patterns (src/orchestrator/research_flow.py)
  • Graph Builder: Graph construction utilities (src/agent_factory/graph_builder.py)
  • Agents: Pydantic AI agents (src/agents/, src/agent_factory/agents.py)
  • Search Tools: Neo4j knowledge graph, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG (src/tools/)
  • Judge Handler: LLM-based evidence assessment (src/agent_factory/judges.py)
  • Embeddings: Semantic search & deduplication (src/services/embeddings.py)
  • Statistical Analyzer: Modal sandbox execution (src/services/statistical_analyzer.py)
  • Multimodal Processing: Image OCR and audio STT/TTS services (src/services/multimodal_processing.py, src/services/audio_processing.py)
  • Middleware: State management, budget tracking, workflow coordination (src/middleware/)
  • MCP Tools: Claude Desktop integration (src/mcp_tools.py)
  • Gradio UI: Web interface with MCP server and streaming (src/app.py)

Research Team & Parallel Execution

The system supports complex research workflows through:

  1. WorkflowManager: Coordinates multiple parallel research loops
  2. Creates and tracks ResearchLoop instances
  3. Runs loops in parallel via asyncio.gather()
  4. Synchronizes evidence to global state
  5. Handles loop failures gracefully

  6. Deep Research Pattern: Breaks complex queries into sections

  7. Planner creates report outline with sections
  8. Each section runs as independent iterative research loop
  9. Loops execute in parallel
  10. Evidence shared across loops via global state
  11. Final synthesis combines all section results

  12. State Synchronization: Thread-safe evidence sharing

  13. Evidence deduplication by URL
  14. Global state accessible to all loops
  15. Semantic search across all collected evidence
  16. Conversation history tracking per iteration

Configuration & Modes

  • Orchestrator Factory (src/orchestrator_factory.py):
  • Auto-detects mode: "advanced" if OpenAI key available, else "simple"
  • Supports explicit mode selection: "simple", "magentic" (alias for "advanced"), "advanced", "iterative", "deep", "auto"
  • Lazy imports for optional dependencies

  • Orchestrator Modes (selected in UI or via factory):

  • simple: Legacy linear search-judge loop (Free Tier)
  • advanced or magentic: Multi-agent coordination using Microsoft Agent Framework (requires OpenAI API key)
  • iterative: Knowledge-gap-driven research with single loop (Free Tier)
  • deep: Parallel section-based research with planning (Free Tier)
  • auto: Intelligent mode detection based on query complexity (Free Tier)

  • Graph Research Modes (used within graph orchestrator, separate from orchestrator mode):

  • iterative: Single research loop pattern
  • deep: Multi-section parallel research pattern
  • auto: Auto-detect pattern based on query complexity

  • Execution Modes:

  • use_graph=True: Graph-based execution (parallel, conditional routing)
  • use_graph=False: Agent chains (sequential, backward compatible)

Note: The UI provides separate controls for orchestrator mode and graph research mode. When using graph-based orchestrators (iterative/deep/auto), the graph research mode determines the specific pattern used within the graph execution.

\ No newline at end of file + Architecture Overview - The DETERMINATOR
Skip to content

Architecture Overview

The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations). The system automatically determines if medical knowledge sources are needed and adapts its search strategy accordingly. It supports multiple orchestration patterns, graph-based execution, parallel research workflows, and long-running task management with real-time streaming.

Core Architecture

Orchestration Patterns

  1. Graph Orchestrator (src/orchestrator/graph_orchestrator.py):
  2. Graph-based execution using Pydantic AI agents as nodes
  3. Supports both iterative and deep research patterns
  4. Node types: Agent, State, Decision, Parallel
  5. Edge types: Sequential, Conditional, Parallel
  6. Conditional routing based on knowledge gaps, budget, and iterations
  7. Parallel execution for concurrent research loops
  8. Event streaming via AsyncGenerator[AgentEvent] for real-time UI updates
  9. Fallback to agent chains when graph execution is disabled

  10. Deep Research Flow (src/orchestrator/research_flow.py):

  11. Pattern: Planner โ†’ Parallel Iterative Loops (one per section) โ†’ Synthesis
  12. Uses PlannerAgent to break query into report sections
  13. Runs IterativeResearchFlow instances in parallel per section via WorkflowManager
  14. Synthesizes results using LongWriterAgent or ProofreaderAgent
  15. Supports both graph execution (use_graph=True) and agent chains (use_graph=False)
  16. Budget tracking per section and globally
  17. State synchronization across parallel loops

  18. Iterative Research Flow (src/orchestrator/research_flow.py):

  19. Pattern: Generate observations โ†’ Evaluate gaps โ†’ Select tools โ†’ Execute โ†’ Judge โ†’ Continue/Complete
  20. Uses KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent, WriterAgent
  21. JudgeHandler assesses evidence sufficiency
  22. Iterates until research complete or constraints met (iterations, time, tokens)
  23. Supports graph execution and agent chains

  24. Magentic Orchestrator (src/orchestrator_magentic.py):

  25. Multi-agent coordination using agent-framework-core
  26. ChatAgent pattern with internal LLMs per agent
  27. Uses MagenticBuilder with participants: searcher, hypothesizer, judge, reporter
  28. Manager orchestrates agents via OpenAIChatClient
  29. Requires OpenAI API key (function calling support)
  30. Event-driven: converts Magentic events to AgentEvent for UI streaming
  31. Supports long-running workflows with max rounds and stall/reset handling

  32. Hierarchical Orchestrator (src/orchestrator_hierarchical.py):

  33. Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge
  34. Adapts Magentic ChatAgent to SubIterationTeam protocol
  35. Event-driven via asyncio.Queue for coordination
  36. Supports sub-iteration patterns for complex research tasks

  37. Legacy Simple Mode (src/legacy_orchestrator.py):

  38. Linear search-judge-synthesize loop
  39. Uses SearchHandlerProtocol and JudgeHandlerProtocol
  40. Generator-based design yielding AgentEvent objects
  41. Backward compatibility for simple use cases

Long-Running Task Support

The system is designed for long-running research tasks with comprehensive state management and streaming:

  1. Event Streaming:
  2. All orchestrators yield AgentEvent objects via AsyncGenerator
  3. Real-time UI updates through Gradio chat interface
  4. Event types: started, searching, search_complete, judging, judge_complete, looping, synthesizing, hypothesizing, complete, error
  5. Metadata includes iteration numbers, tool names, result counts, durations

  6. Budget Tracking (src/middleware/budget_tracker.py):

  7. Per-loop and global budget management
  8. Tracks: tokens, time (seconds), iterations
  9. Budget enforcement at decision nodes
  10. Token estimation (~4 chars per token)
  11. Early termination when budgets exceeded
  12. Budget summaries for monitoring

  13. Workflow Manager (src/middleware/workflow_manager.py):

  14. Coordinates parallel research loops
  15. Tracks loop status: pending, running, completed, failed, cancelled
  16. Synchronizes evidence between loops and global state
  17. Handles errors per loop (doesn't fail all if one fails)
  18. Supports loop cancellation and timeout handling
  19. Evidence deduplication across parallel loops

  20. State Management (src/middleware/state_machine.py):

  21. Thread-safe isolation using ContextVar for concurrent requests
  22. WorkflowState tracks: evidence, conversation history, embedding service
  23. Evidence deduplication by URL
  24. Semantic search via embedding service
  25. State persistence across long-running workflows
  26. Supports both iterative and deep research patterns

  27. Gradio UI (src/app.py):

  28. Real-time streaming of research progress
  29. Accordion-based UI for pending/done operations
  30. OAuth integration (HuggingFace)
  31. Multiple backend support (API keys, free tier)
  32. Handles long-running tasks with progress indicators
  33. Event accumulation for pending operations

Graph Architecture

The graph orchestrator (src/orchestrator/graph_orchestrator.py) implements a flexible graph-based execution model:

Node Types:

  • Agent Nodes: Execute Pydantic AI agents (e.g., KnowledgeGapAgent, ToolSelectorAgent)
  • State Nodes: Update or read workflow state (evidence, conversation)
  • Decision Nodes: Make routing decisions (research complete?, budget exceeded?)
  • Parallel Nodes: Execute multiple nodes concurrently (parallel research loops)

Edge Types:

  • Sequential Edges: Always traversed (no condition)
  • Conditional Edges: Traversed based on condition (e.g., if research complete โ†’ writer, else โ†’ tool selector)
  • Parallel Edges: Used for parallel execution branches

Graph Patterns:

  • Iterative Graph: [Input] โ†’ [Thinking] โ†’ [Knowledge Gap] โ†’ [Decision: Complete?] โ†’ [Tool Selector] or [Writer]
  • Deep Research Graph: [Input] โ†’ [Planner] โ†’ [Parallel Iterative Loops] โ†’ [Synthesizer]

Execution Flow:

  1. Graph construction from nodes and edges
  2. Graph validation (no cycles, all nodes reachable)
  3. Graph execution from entry node
  4. Node execution based on type
  5. Edge evaluation for next node(s)
  6. Parallel execution via asyncio.gather()
  7. State updates at state nodes
  8. Event streaming for UI

Key Components

  • Orchestrators: Multiple orchestration patterns (src/orchestrator/, src/orchestrator_*.py)
  • Research Flows: Iterative and deep research patterns (src/orchestrator/research_flow.py)
  • Graph Builder: Graph construction utilities (src/agent_factory/graph_builder.py)
  • Agents: Pydantic AI agents (src/agents/, src/agent_factory/agents.py)
  • Search Tools: Neo4j knowledge graph, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG (src/tools/)
  • Judge Handler: LLM-based evidence assessment (src/agent_factory/judges.py)
  • Embeddings: Semantic search & deduplication (src/services/embeddings.py)
  • Statistical Analyzer: Modal sandbox execution (src/services/statistical_analyzer.py)
  • Multimodal Processing: Image OCR and audio STT/TTS services (src/services/multimodal_processing.py, src/services/audio_processing.py)
  • Middleware: State management, budget tracking, workflow coordination (src/middleware/)
  • MCP Tools: Claude Desktop integration (src/mcp_tools.py)
  • Gradio UI: Web interface with MCP server and streaming (src/app.py)

Research Team & Parallel Execution

The system supports complex research workflows through:

  1. WorkflowManager: Coordinates multiple parallel research loops
  2. Creates and tracks ResearchLoop instances
  3. Runs loops in parallel via asyncio.gather()
  4. Synchronizes evidence to global state
  5. Handles loop failures gracefully

  6. Deep Research Pattern: Breaks complex queries into sections

  7. Planner creates report outline with sections
  8. Each section runs as independent iterative research loop
  9. Loops execute in parallel
  10. Evidence shared across loops via global state
  11. Final synthesis combines all section results

  12. State Synchronization: Thread-safe evidence sharing

  13. Evidence deduplication by URL
  14. Global state accessible to all loops
  15. Semantic search across all collected evidence
  16. Conversation history tracking per iteration

Configuration & Modes

  • Orchestrator Factory (src/orchestrator_factory.py):
  • Auto-detects mode: "advanced" if OpenAI key available, else "simple"
  • Supports explicit mode selection: "simple", "magentic" (alias for "advanced"), "advanced", "iterative", "deep", "auto"
  • Lazy imports for optional dependencies

  • Orchestrator Modes (selected in UI or via factory):

  • simple: Legacy linear search-judge loop (Free Tier)
  • advanced or magentic: Multi-agent coordination using Microsoft Agent Framework (requires OpenAI API key)
  • iterative: Knowledge-gap-driven research with single loop (Free Tier)
  • deep: Parallel section-based research with planning (Free Tier)
  • auto: Intelligent mode detection based on query complexity (Free Tier)

  • Graph Research Modes (used within graph orchestrator, separate from orchestrator mode):

  • iterative: Single research loop pattern
  • deep: Multi-section parallel research pattern
  • auto: Auto-detect pattern based on query complexity

  • Execution Modes:

  • use_graph=True: Graph-based execution (parallel, conditional routing)
  • use_graph=False: Agent chains (sequential, backward compatible)

Note: The UI provides separate controls for orchestrator mode and graph research mode. When using graph-based orchestrators (iterative/deep/auto), the graph research mode determines the specific pattern used within the graph execution.

\ No newline at end of file diff --git a/site/overview/features/index.html b/site/overview/features/index.html index 3fdb0faf..218b8ba7 100644 --- a/site/overview/features/index.html +++ b/site/overview/features/index.html @@ -1 +1 @@ - Features - The DETERMINATOR
Skip to content

Features

The DETERMINATOR provides a comprehensive set of features for AI-assisted research:

Core Features

  • General Web Search: Search general knowledge sources for any domain
  • Neo4j Knowledge Graph: Search structured knowledge graph for papers and disease relationships
  • PubMed: Search peer-reviewed biomedical literature via NCBI E-utilities (automatically used when medical knowledge needed)
  • ClinicalTrials.gov: Search interventional clinical trials (automatically used when medical knowledge needed)
  • Europe PMC: Search preprints and peer-reviewed articles (includes bioRxiv/medRxiv)
  • RAG: Semantic search within collected evidence using LlamaIndex
  • Automatic Source Selection: Automatically determines which sources are needed based on query analysis

MCP Integration

  • Model Context Protocol: Expose search tools via MCP server
  • Claude Desktop: Use The DETERMINATOR tools directly from Claude Desktop
  • MCP Clients: Compatible with any MCP-compatible client

Authentication

  • REQUIRED: Authentication is mandatory before using the application
  • HuggingFace OAuth: Sign in with HuggingFace account for automatic API token usage (recommended)
  • Manual API Keys: Support for HuggingFace API keys via environment variables (HF_TOKEN or HUGGINGFACE_API_KEY)
  • Free Tier Support: Automatic fallback to HuggingFace Inference API (public models) when no API key is available
  • Authentication Check: The application will display an error message if authentication is not provided

Secure Code Execution

  • Modal Sandbox: Secure execution of AI-generated statistical code
  • Isolated Environment: Network isolation and package version pinning
  • Safe Execution: Prevents malicious code execution

Semantic Search & RAG

  • LlamaIndex Integration: Advanced RAG capabilities
  • Vector Storage: ChromaDB for embedding storage
  • Semantic Deduplication: Automatic detection of similar evidence
  • Embedding Service: Local sentence-transformers (no API key required)

Orchestration Patterns

  • Graph-Based Execution: Flexible graph orchestration with conditional routing
  • Parallel Research Loops: Run multiple research tasks concurrently
  • Iterative Research: Single-loop research with search-judge-synthesize cycles that continues until precise answers are found
  • Deep Research: Multi-section parallel research with planning and synthesis
  • Magentic Orchestration: Multi-agent coordination using Microsoft Agent Framework (alias: "advanced" mode)
  • Stops at Nothing: Only stops at configured limits (budget, time, iterations), otherwise continues until finding precise answers

Orchestrator Modes: - simple: Legacy linear search-judge loop - advanced (or magentic): Multi-agent coordination (requires OpenAI API key) - iterative: Knowledge-gap-driven research with single loop - deep: Parallel section-based research with planning - auto: Intelligent mode detection based on query complexity

Graph Research Modes (used within graph orchestrator): - iterative: Single research loop pattern - deep: Multi-section parallel research pattern - auto: Auto-detect pattern based on query complexity

Execution Modes: - use_graph=True: Graph-based execution with parallel and conditional routing - use_graph=False: Agent chains with sequential execution (backward compatible)

Real-Time Streaming

  • Event Streaming: Real-time updates via AsyncGenerator[AgentEvent]
  • Progress Tracking: Monitor research progress with detailed event metadata
  • UI Integration: Seamless integration with Gradio chat interface

Budget Management

  • Token Budget: Track and limit LLM token usage
  • Time Budget: Enforce time limits per research loop
  • Iteration Budget: Limit maximum iterations
  • Per-Loop Budgets: Independent budgets for parallel research loops

State Management

  • Thread-Safe Isolation: ContextVar-based state management
  • Evidence Deduplication: Automatic URL-based deduplication
  • Conversation History: Track iteration history and agent interactions
  • State Synchronization: Share evidence across parallel loops

Multimodal Input & Output

  • Image Input (OCR): Upload images and extract text using optical character recognition
  • Audio Input (STT): Record or upload audio files and transcribe to text using speech-to-text
  • Audio Output (TTS): Generate audio responses with text-to-speech synthesis
  • Configurable Settings: Enable/disable multimodal features via sidebar settings
  • Voice Selection: Choose from multiple TTS voices (American English: af_, am_)
  • Speech Speed Control: Adjust TTS speech speed (0.5x to 2.0x)
  • Multimodal Processing Service: Integrated service for processing images and audio files

Advanced Features

Agent System

  • Pydantic AI Agents: Type-safe agent implementation
  • Structured Output: Pydantic models for agent responses
  • Agent Factory: Centralized agent creation with fallback support
  • Specialized Agents: Knowledge gap, tool selector, writer, proofreader, and more

Search Tools

  • Rate Limiting: Built-in rate limiting for external APIs
  • Retry Logic: Automatic retry with exponential backoff
  • Query Preprocessing: Automatic query enhancement and synonym expansion
  • Evidence Conversion: Automatic conversion to structured Evidence objects

Error Handling

  • Custom Exceptions: Hierarchical exception system
  • Error Chaining: Preserve exception context
  • Structured Logging: Comprehensive logging with structlog
  • Graceful Degradation: Fallback handlers for missing dependencies

Configuration

  • Pydantic Settings: Type-safe configuration management
  • Environment Variables: Support for .env files
  • Validation: Automatic configuration validation
  • Flexible Providers: Support for multiple LLM and embedding providers

Testing

  • Unit Tests: Comprehensive unit test coverage
  • Integration Tests: Real API integration tests
  • Mock Support: Extensive mocking utilities
  • Coverage Reports: Code coverage tracking

UI Features

Gradio Interface

  • Real-Time Chat: Interactive chat interface with multimodal support
  • Streaming Updates: Live progress updates
  • Accordion UI: Organized display of pending/done operations
  • OAuth Integration: Seamless HuggingFace authentication
  • Multimodal Input: Support for text, images, and audio input in the same interface
  • Sidebar Settings: Configuration accordions for research, multimodal, and audio settings

MCP Server

  • RESTful API: HTTP-based MCP server
  • Tool Discovery: Automatic tool registration
  • Request Handling: Async request processing
  • Error Responses: Structured error responses

Development Features

Code Quality

  • Type Safety: Full type hints with mypy strict mode
  • Linting: Ruff for code quality
  • Formatting: Automatic code formatting
  • Pre-commit Hooks: Automated quality checks

Documentation

  • Comprehensive Docs: Detailed documentation for all components
  • Code Examples: Extensive code examples
  • Architecture Diagrams: Visual architecture documentation
  • API Reference: Complete API documentation
\ No newline at end of file + Features - The DETERMINATOR
Skip to content

Features

The DETERMINATOR provides a comprehensive set of features for AI-assisted research:

Core Features

  • General Web Search: Search general knowledge sources for any domain
  • Neo4j Knowledge Graph: Search structured knowledge graph for papers and disease relationships
  • PubMed: Search peer-reviewed biomedical literature via NCBI E-utilities (automatically used when medical knowledge needed)
  • ClinicalTrials.gov: Search interventional clinical trials (automatically used when medical knowledge needed)
  • Europe PMC: Search preprints and peer-reviewed articles (includes bioRxiv/medRxiv)
  • RAG: Semantic search within collected evidence using LlamaIndex
  • Automatic Source Selection: Automatically determines which sources are needed based on query analysis

MCP Integration

  • Model Context Protocol: Expose search tools via MCP server
  • Claude Desktop: Use The DETERMINATOR tools directly from Claude Desktop
  • MCP Clients: Compatible with any MCP-compatible client

Authentication

  • REQUIRED: Authentication is mandatory before using the application
  • HuggingFace OAuth: Sign in with HuggingFace account for automatic API token usage (recommended)
  • Manual API Keys: Support for HuggingFace API keys via environment variables (HF_TOKEN or HUGGINGFACE_API_KEY)
  • Free Tier Support: Automatic fallback to HuggingFace Inference API (public models) when no API key is available
  • Authentication Check: The application will display an error message if authentication is not provided

Secure Code Execution

  • Modal Sandbox: Secure execution of AI-generated statistical code
  • Isolated Environment: Network isolation and package version pinning
  • Safe Execution: Prevents malicious code execution

Semantic Search & RAG

  • LlamaIndex Integration: Advanced RAG capabilities
  • Vector Storage: ChromaDB for embedding storage
  • Semantic Deduplication: Automatic detection of similar evidence
  • Embedding Service: Local sentence-transformers (no API key required)

Orchestration Patterns

  • Graph-Based Execution: Flexible graph orchestration with conditional routing
  • Parallel Research Loops: Run multiple research tasks concurrently
  • Iterative Research: Single-loop research with search-judge-synthesize cycles that continues until precise answers are found
  • Deep Research: Multi-section parallel research with planning and synthesis
  • Magentic Orchestration: Multi-agent coordination using Microsoft Agent Framework (alias: "advanced" mode)
  • Stops at Nothing: Only stops at configured limits (budget, time, iterations), otherwise continues until finding precise answers

Orchestrator Modes: - simple: Legacy linear search-judge loop - advanced (or magentic): Multi-agent coordination (requires OpenAI API key) - iterative: Knowledge-gap-driven research with single loop - deep: Parallel section-based research with planning - auto: Intelligent mode detection based on query complexity

Graph Research Modes (used within graph orchestrator): - iterative: Single research loop pattern - deep: Multi-section parallel research pattern - auto: Auto-detect pattern based on query complexity

Execution Modes: - use_graph=True: Graph-based execution with parallel and conditional routing - use_graph=False: Agent chains with sequential execution (backward compatible)

Real-Time Streaming

  • Event Streaming: Real-time updates via AsyncGenerator[AgentEvent]
  • Progress Tracking: Monitor research progress with detailed event metadata
  • UI Integration: Seamless integration with Gradio chat interface

Budget Management

  • Token Budget: Track and limit LLM token usage
  • Time Budget: Enforce time limits per research loop
  • Iteration Budget: Limit maximum iterations
  • Per-Loop Budgets: Independent budgets for parallel research loops

State Management

  • Thread-Safe Isolation: ContextVar-based state management
  • Evidence Deduplication: Automatic URL-based deduplication
  • Conversation History: Track iteration history and agent interactions
  • State Synchronization: Share evidence across parallel loops

Multimodal Input & Output

  • Image Input (OCR): Upload images and extract text using optical character recognition
  • Audio Input (STT): Record or upload audio files and transcribe to text using speech-to-text
  • Audio Output (TTS): Generate audio responses with text-to-speech synthesis
  • Configurable Settings: Enable/disable multimodal features via sidebar settings
  • Voice Selection: Choose from multiple TTS voices (American English: af_, am_)
  • Speech Speed Control: Adjust TTS speech speed (0.5x to 2.0x)
  • Multimodal Processing Service: Integrated service for processing images and audio files

Advanced Features

Agent System

  • Pydantic AI Agents: Type-safe agent implementation
  • Structured Output: Pydantic models for agent responses
  • Agent Factory: Centralized agent creation with fallback support
  • Specialized Agents: Knowledge gap, tool selector, writer, proofreader, and more

Search Tools

  • Rate Limiting: Built-in rate limiting for external APIs
  • Retry Logic: Automatic retry with exponential backoff
  • Query Preprocessing: Automatic query enhancement and synonym expansion
  • Evidence Conversion: Automatic conversion to structured Evidence objects

Error Handling

  • Custom Exceptions: Hierarchical exception system
  • Error Chaining: Preserve exception context
  • Structured Logging: Comprehensive logging with structlog
  • Graceful Degradation: Fallback handlers for missing dependencies

Configuration

  • Pydantic Settings: Type-safe configuration management
  • Environment Variables: Support for .env files
  • Validation: Automatic configuration validation
  • Flexible Providers: Support for multiple LLM and embedding providers

Testing

  • Unit Tests: Comprehensive unit test coverage
  • Integration Tests: Real API integration tests
  • Mock Support: Extensive mocking utilities
  • Coverage Reports: Code coverage tracking

UI Features

Gradio Interface

  • Real-Time Chat: Interactive chat interface with multimodal support
  • Streaming Updates: Live progress updates
  • Accordion UI: Organized display of pending/done operations
  • OAuth Integration: Seamless HuggingFace authentication
  • Multimodal Input: Support for text, images, and audio input in the same interface
  • Sidebar Settings: Configuration accordions for research, multimodal, and audio settings

MCP Server

  • RESTful API: HTTP-based MCP server
  • Tool Discovery: Automatic tool registration
  • Request Handling: Async request processing
  • Error Responses: Structured error responses

Development Features

Code Quality

  • Type Safety: Full type hints with mypy strict mode
  • Linting: Ruff for code quality
  • Formatting: Automatic code formatting
  • Pre-commit Hooks: Automated quality checks

Documentation

  • Comprehensive Docs: Detailed documentation for all components
  • Code Examples: Extensive code examples
  • Architecture Diagrams: Visual architecture documentation
  • API Reference: Complete API documentation
\ No newline at end of file diff --git a/site/overview/quick-start/index.html b/site/overview/quick-start/index.html index effa59f1..31eac8f2 100644 --- a/site/overview/quick-start/index.html +++ b/site/overview/quick-start/index.html @@ -19,4 +19,4 @@ } } } -

  • Restart Claude Desktop

  • Use DeepCritical tools directly from Claude Desktop
  • Available Tools

    Note: The application automatically uses all available search tools (Neo4j, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG) based on query analysis. Neo4j knowledge graph search is included by default for biomedical queries.

    Next Steps

    \ No newline at end of file +

  • Restart Claude Desktop

  • Use DeepCritical tools directly from Claude Desktop
  • Available Tools

    Note: The application automatically uses all available search tools (Neo4j, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG) based on query analysis. Neo4j knowledge graph search is included by default for biomedical queries.

    Next Steps

    \ No newline at end of file diff --git a/site/search/search_index.json b/site/search/search_index.json index 306ac343..295c8438 100644 --- a/site/search/search_index.json +++ b/site/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"The DETERMINATOR","text":"

    Generalist Deep Research Agent - Stops at Nothing Until Finding Precise Answers

    The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations).

    Key Features: - Generalist: Handles queries from any domain (medical, technical, business, scientific, etc.) - Automatic Source Selection: Automatically determines if medical knowledge sources (PubMed, ClinicalTrials.gov) are needed - Multi-Source Search: Web search, PubMed, ClinicalTrials.gov, Europe PMC, RAG - Iterative Refinement: Continues searching and refining until precise answers are found - Evidence Synthesis: Comprehensive reports with proper citations

    Important: The DETERMINATOR is a research tool that synthesizes evidence. It cannot provide medical advice or answer medical questions directly.

    "},{"location":"#features","title":"Features","text":""},{"location":"#quick-start","title":"Quick Start","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync dependencies\nuv sync\n\n# Start the Gradio app\nuv run gradio run src/app.py\n

    Open your browser to http://localhost:7860.

    For detailed installation and setup instructions, see the Getting Started Guide.

    "},{"location":"#architecture","title":"Architecture","text":"

    The DETERMINATOR uses a Vertical Slice Architecture:

    1. Search Slice: Retrieving evidence from multiple sources (web, PubMed, ClinicalTrials.gov, Europe PMC, RAG) based on query analysis
    2. Judge Slice: Evaluating evidence quality using LLMs
    3. Orchestrator Slice: Managing the research loop and UI

    The system supports three main research patterns:

    Learn more about the Architecture.

    "},{"location":"#documentation","title":"Documentation","text":""},{"location":"#links","title":"Links","text":""},{"location":"LICENSE/","title":"License","text":"

    DeepCritical is licensed under the MIT License.

    "},{"location":"LICENSE/#mit-license","title":"MIT License","text":"

    Copyright (c) 2024 DeepCritical Team

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/","title":"MkDocs & Material UI Improvement Assessment","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#current-configuration-analysis","title":"Current Configuration Analysis","text":"

    Your current mkdocs.yml already includes many excellent features: - \u2705 Material theme with light/dark mode toggle - \u2705 Navigation tabs, sections, expand, and top navigation - \u2705 Search with suggestions and highlighting - \u2705 Code annotation and copy buttons - \u2705 Mermaid diagram support - \u2705 Code include plugin - \u2705 Minification for performance - \u2705 Comprehensive markdown extensions

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#recommended-improvements","title":"Recommended Improvements","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#1-versioning--multi-version-documentation--high-priority","title":"1. Versioning & Multi-Version Documentation \u2b50 High Priority","text":"

    If you plan to maintain multiple versions or branches:

    plugins:\n  - search\n  - mermaid2\n  - codeinclude\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n  # Optional: For versioning\n  # - versioning:\n  #     version: ['dev', 'main']\n

    Benefits: Shows when pages were last updated, helps users understand document freshness.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#2-git-integration--revision-information--high-priority","title":"2. Git Integration & Revision Information \u2b50 High Priority","text":"

    Add revision dates and authors to pages:

    plugins:\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n      fallback_to_build_date: true\n  - git-committers:\n      repository: DeepCritical/GradioDemo\n      branch: dev\n

    Benefits: Users see when content was last updated, builds trust in documentation freshness.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#3-enhanced-navigation-features--high-priority","title":"3. Enhanced Navigation Features \u2b50 High Priority","text":"

    Add breadcrumbs and improve navigation:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes  # Add index pages\n    - navigation.instant  # Instant page loads\n    - navigation.tracking  # Track scroll position\n    - navigation.smooth  # Smooth scrolling\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link  # Link to specific tabs\n    - content.tooltips  # Tooltips for abbreviations\n

    Benefits: Better UX, easier navigation, professional feel.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#4-content-tabs-for-code-examples--high-priority","title":"4. Content Tabs for Code Examples \u2b50 High Priority","text":"

    Perfect for showing multiple code examples (Python, TypeScript, etc.):

    markdown_extensions:\n  - pymdownx.tabbed:\n      alternate_style: true\n      combine_header_slug: true  # Add this\n

    Usage in docs:

    === \"Python\"\n    ```python\n    def example():\n        pass\n    ```\n\n=== \"TypeScript\"\n    ```typescript\n    function example() {}\n    ```\n

    Benefits: Clean way to show multiple implementations without cluttering pages.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#5-enhanced-admonitions--medium-priority","title":"5. Enhanced Admonitions \u2b50 Medium Priority","text":"

    Add more admonition types and better styling:

    markdown_extensions:\n  - admonition\n  - pymdownx.details\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n        # Add custom admonition fences\n        - name: danger\n          class: danger\n          format: !!python/name:pymdownx.superfences.fence_code_format\n

    Usage:

    !!! danger \"Important\"\n    This is a critical warning.\n

    Benefits: Better visual hierarchy for warnings, tips, and important information.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#6-math-formula-support--medium-priority-if-needed","title":"6. Math Formula Support \u2b50 Medium Priority (if needed)","text":"

    If your documentation includes mathematical formulas:

    markdown_extensions:\n  - pymdownx.arithmatex:\n      generic: true\n  - pymdownx.superfences:\n      custom_fences:\n        - name: math\n          class: arithmetic\n          format: !!python/name:pymdownx.superfences.fence_code_format\n\nextra_javascript:\n  - javascripts/mathjax.js\n  - https://polyfill.io/v3/polyfill.min.js?features=es6\n  - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js\n

    Benefits: Essential for scientific/technical documentation with formulas.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#7-better-code-highlighting--medium-priority","title":"7. Better Code Highlighting \u2b50 Medium Priority","text":"

    Add more language support and better themes:

    markdown_extensions:\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n      use_pygments: true\n      noclasses: false  # Use CSS classes instead of inline styles\n

    Benefits: Better syntax highlighting, more language support.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#8-social-links-enhancement--low-priority","title":"8. Social Links Enhancement \u2b50 Low Priority","text":"

    Add more social platforms and better icons:

    extra:\n  social:\n    - icon: fontawesome/brands/github\n      link: https://github.com/DeepCritical/GradioDemo\n      name: GitHub\n    - icon: fontawesome/brands/twitter\n      link: https://twitter.com/yourhandle\n      name: Twitter\n    - icon: material/web\n      link: https://huggingface.co/spaces/DataQuests/DeepCritical\n      name: HuggingFace Space\n    - icon: fontawesome/brands/discord\n      link: https://discord.gg/yourserver\n      name: Discord\n

    Benefits: Better community engagement, more ways to connect.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#9-analytics-integration--medium-priority","title":"9. Analytics Integration \u2b50 Medium Priority","text":"

    Add privacy-respecting analytics:

    extra:\n  analytics:\n    provider: google\n    property: G-XXXXXXXXXX\n  # Or use privacy-focused alternative:\n  # analytics:\n  #   provider: plausible\n  #   domain: yourdomain.com\n

    Benefits: Understand how users interact with your documentation.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#10-custom-cssjs-for-branding--low-priority","title":"10. Custom CSS/JS for Branding \u2b50 Low Priority","text":"

    Add custom styling:

    extra_css:\n  - stylesheets/extra.css\n\nextra_javascript:\n  - javascripts/extra.js\n

    Benefits: Customize appearance, add interactive features.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#11-better-table-of-contents--medium-priority","title":"11. Better Table of Contents \u2b50 Medium Priority","text":"

    Enhance TOC with more options:

    markdown_extensions:\n  - toc:\n      permalink: true\n      permalink_title: \"Anchor link to this section\"\n      baselevel: 1\n      toc_depth: 3\n      slugify: !!python/object/apply:pymdownx.slugs.slugify\n        kwds:\n          case: lower\n

    Benefits: Better navigation within long pages, SEO-friendly anchor links.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#12-image-optimization--medium-priority","title":"12. Image Optimization \u2b50 Medium Priority","text":"

    Add image handling plugin:

    plugins:\n  - search\n  - mermaid2\n  - codeinclude\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n  # Optional: Image optimization\n  # - awesome-pages  # For better page organization\n

    Benefits: Faster page loads, better mobile experience.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#13-keyboard-shortcuts--low-priority","title":"13. Keyboard Shortcuts \u2b50 Low Priority","text":"

    Enable keyboard navigation:

    theme:\n  keyboard_shortcuts:\n    search: true\n    previous: true\n    next: true\n

    Benefits: Power users can navigate faster.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#14-print-styles--low-priority","title":"14. Print Styles \u2b50 Low Priority","text":"

    Better printing experience:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes\n    - navigation.instant\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - content.action.edit  # Edit button\n    - content.action.view  # View source\n

    Benefits: Users can print documentation cleanly.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#15-better-search-configuration--medium-priority","title":"15. Better Search Configuration \u2b50 Medium Priority","text":"

    Enhance search capabilities:

    plugins:\n  - search:\n      lang:\n        - en\n      separator: '[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&amp;'\n      prebuild_index: true  # For faster search\n      indexing: full  # Full-text indexing\n

    Benefits: Faster, more accurate search results.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#16-api-documentation-enhancements--high-priority-for-your-api-docs","title":"16. API Documentation Enhancements \u2b50 High Priority (for your API docs)","text":"

    Since you have extensive API documentation, consider:

    markdown_extensions:\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n      preserve_tabs: true\n  # Add API-specific features\n  - attr_list\n  - md_in_html\n  - pymdownx.caret\n  - pymdownx.tilde\n

    Benefits: Better formatting for API endpoints, parameters, responses.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#17-blognews-section--low-priority-if-needed","title":"17. Blog/News Section \u2b50 Low Priority (if needed)","text":"

    If you want to add a blog:

    plugins:\n  - blog:\n      blog_dir: blog\n      blog_description: \"News and updates\"\n      post_date_format: full\n      post_url_format: '{slug}'\n      archive: true\n

    Benefits: Keep users updated with changelog, announcements.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#18-tags-and-categories--low-priority","title":"18. Tags and Categories \u2b50 Low Priority","text":"

    Organize content with tags:

    markdown_extensions:\n  - meta\n

    Then in frontmatter:

    ---\ntags:\n  - api\n  - agents\n  - getting-started\n---\n

    Benefits: Better content organization, related content discovery.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#19-better-mobile-experience--high-priority","title":"19. Better Mobile Experience \u2b50 High Priority","text":"

    Ensure mobile optimization:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.instant  # Helps on mobile\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - toc.integrate  # Better mobile TOC\n

    Benefits: Better experience for mobile users (growing segment).

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#20-feedback-mechanism--medium-priority","title":"20. Feedback Mechanism \u2b50 Medium Priority","text":"

    Add feedback buttons:

    extra:\n  feedback:\n    title: \"Was this page helpful?\"\n    ratings:\n      - icon: material/thumb-up-outline\n        name: \"This page was helpful\"\n      - icon: material/thumb-down-outline\n        name: \"This page could be improved\"\n

    Benefits: Understand what content needs improvement.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#priority-recommendations","title":"Priority Recommendations","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#immediate-high-impact-easy-implementation","title":"Immediate (High Impact, Easy Implementation)","text":"
    1. \u2705 Git revision dates - Shows content freshness
    2. \u2705 Enhanced navigation features - Better UX
    3. \u2705 Content tabs - Perfect for code examples
    4. \u2705 Better search configuration - Faster search
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#short-term-high-impact-medium-effort","title":"Short-term (High Impact, Medium Effort)","text":"
    1. \u2705 API documentation enhancements - Better API docs
    2. \u2705 Enhanced admonitions - Better visual hierarchy
    3. \u2705 Mobile optimization - Better mobile experience
    4. \u2705 Analytics - Understand user behavior
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#long-term-nice-to-have","title":"Long-term (Nice to Have)","text":"
    1. \u26a0\ufe0f Versioning - If you need multiple versions
    2. \u26a0\ufe0f Math formulas - If you have mathematical content
    3. \u26a0\ufe0f Blog section - If you want to publish updates
    4. \u26a0\ufe0f Custom CSS/JS - For advanced customization
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#implementation-example","title":"Implementation Example","text":"

    Here's an enhanced mkdocs.yml with the high-priority improvements:

    site_name: The DETERMINATOR\nsite_description: Generalist Deep Research Agent that Stops at Nothing\nsite_author: The DETERMINATOR Team\nsite_url: https://deepcritical.github.io/GradioDemo/\n\nrepo_name: DeepCritical/GradioDemo\nrepo_url: https://github.com/DeepCritical/GradioDemo\nedit_uri: edit/dev/docs/\n\nstrict: false\n\ntheme:\n  name: material\n  palette:\n    - scheme: default\n      primary: orange\n      accent: red\n      toggle:\n        icon: material/brightness-7\n        name: Switch to dark mode\n    - scheme: slate\n      primary: orange\n      accent: red\n      toggle:\n        icon: material/brightness-4\n        name: Switch to light mode\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes\n    - navigation.instant\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - toc.integrate\n  icon:\n    repo: fontawesome/brands/github\n  language: en\n\nplugins:\n  - search:\n      lang:\n        - en\n      separator: '[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&amp;'\n      prebuild_index: true\n      indexing: full\n  - mermaid2\n  - codeinclude\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n      fallback_to_build_date: true\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n\nmarkdown_extensions:\n  - dev.docs_plugins:\n      base_path: \".\"\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n      use_pygments: true\n      noclasses: false\n  - pymdownx.inlinehilite\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n      preserve_tabs: true\n  - pymdownx.tabbed:\n      alternate_style: true\n      combine_header_slug: true\n  - pymdownx.tasklist:\n      custom_checkbox: true\n  - pymdownx.emoji:\n      emoji_generator: !!python/name:pymdownx.emoji.to_svg\n      emoji_index: !!python/name:pymdownx.emoji.twemoji\n  - pymdownx.snippets\n  - admonition\n  - pymdownx.details\n  - attr_list\n  - md_in_html\n  - tables\n  - meta\n  - toc:\n      permalink: true\n      permalink_title: \"Anchor link to this section\"\n      baselevel: 1\n      toc_depth: 3\n      slugify: !!python/object/apply:pymdownx.slugs.slugify\n        kwds:\n          case: lower\n\nnav:\n  - Home: index.md\n  - Overview:\n    - overview/architecture.md\n    - overview/features.md\n  - Getting Started:\n    - getting-started/installation.md\n    - getting-started/quick-start.md\n    - getting-started/mcp-integration.md\n    - getting-started/examples.md\n  - Configuration:\n    - configuration/index.md\n  - Architecture:\n    - \"Graph Orchestration\": architecture/graph_orchestration.md\n    - \"Workflow Diagrams\": architecture/workflow-diagrams.md\n    - \"Agents\": architecture/agents.md\n    - \"Orchestrators\": architecture/orchestrators.md\n    - \"Tools\": architecture/tools.md\n    - \"Middleware\": architecture/middleware.md\n    - \"Services\": architecture/services.md\n  - API Reference:\n    - api/agents.md\n    - api/tools.md\n    - api/orchestrators.md\n    - api/services.md\n    - api/models.md\n  - Contributing:\n    - contributing/index.md\n    - contributing/code-quality.md\n    - contributing/code-style.md\n    - contributing/error-handling.md\n    - contributing/implementation-patterns.md\n    - contributing/prompt-engineering.md\n    - contributing/testing.md\n  - License: LICENSE.md\n  - Team: team.md\n\nextra:\n  social:\n    - icon: fontawesome/brands/github\n      link: https://github.com/DeepCritical/GradioDemo\n      name: GitHub\n    - icon: material/web\n      link: https://huggingface.co/spaces/DataQuests/DeepCritical\n      name: HuggingFace Space\n  version:\n    provider: mike\n  generator:\n    enabled: false\n\ncopyright: Copyright &copy; 2024 DeepCritical Team\n
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#additional-documentation-improvements","title":"Additional Documentation Improvements","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#content-structure","title":"Content Structure","text":"
    1. Add a changelog page - Keep users informed of updates
    2. Add a FAQ section - Address common questions
    3. Add a glossary - Define technical terms
    4. Add a troubleshooting guide - Help users solve common issues
    5. Add video tutorials - Embed videos for complex topics
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#visual-enhancements","title":"Visual Enhancements","text":"
    1. Add diagrams - Use more Mermaid diagrams for complex flows
    2. Add screenshots - Visual guides for UI features
    3. Add code examples - More practical examples
    4. Add comparison tables - Compare different approaches/options
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#seo--discoverability","title":"SEO & Discoverability","text":"
    1. Add meta descriptions - Better search engine results
    2. Add Open Graph tags - Better social media sharing
    3. Add sitemap - Help search engines index your docs
    4. Add robots.txt - Control search engine crawling
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#next-steps","title":"Next Steps","text":"
    1. Review this assessment
    2. Prioritize features based on your needs
    3. Test changes in a branch
    4. Gather user feedback
    5. Iterate and improve
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#resources","title":"Resources","text":""},{"location":"team/","title":"Team","text":"

    DeepCritical is developed by a team of researchers and developers working on AI-assisted research.

    "},{"location":"team/#team-members","title":"Team Members","text":""},{"location":"team/#zj","title":"ZJ","text":""},{"location":"team/#mario-aderman","title":"Mario Aderman","text":""},{"location":"team/#joseph-pollack","title":"Joseph Pollack","text":""},{"location":"team/#virat-chauran","title":"Virat Chauran","text":""},{"location":"team/#anna-bossler","title":"Anna Bossler","text":""},{"location":"team/#about","title":"About","text":"

    The DeepCritical team met online in the Alzheimer's Critical Literature Review Group in the Hugging Science initiative. We're building the agent framework we want to use for AI-assisted research to turn the vast amounts of clinical data into cures.

    "},{"location":"team/#contributing","title":"Contributing","text":"

    We welcome contributions! See the Contributing Guide for details.

    "},{"location":"team/#links","title":"Links","text":""},{"location":"api/agents/","title":"Agents API Reference","text":"

    This page documents the API for DeepCritical agents.

    "},{"location":"api/agents/#knowledgegapagent","title":"KnowledgeGapAgent","text":"

    Module: src.agents.knowledge_gap

    Purpose: Evaluates research state and identifies knowledge gaps.

    "},{"location":"api/agents/#methods","title":"Methods","text":""},{"location":"api/agents/#evaluate","title":"evaluate","text":"

    Evaluates research completeness and identifies outstanding knowledge gaps.

    Parameters: - query: Research query string - background_context: Background context for the query (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\") - iteration: Current iteration number (default: 0) - time_elapsed_minutes: Elapsed time in minutes (default: 0.0) - max_time_minutes: Maximum time limit in minutes (default: 10)

    Returns: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    "},{"location":"api/agents/#toolselectoragent","title":"ToolSelectorAgent","text":"

    Module: src.agents.tool_selector

    Purpose: Selects appropriate tools for addressing knowledge gaps.

    "},{"location":"api/agents/#methods_1","title":"Methods","text":""},{"location":"api/agents/#select_tools","title":"select_tools","text":"

    Selects tools for addressing a knowledge gap.

    Parameters: - gap: The knowledge gap to address - query: Research query string - background_context: Optional background context (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\")

    Returns: AgentSelectionPlan with list of AgentTask objects.

    "},{"location":"api/agents/#writeragent","title":"WriterAgent","text":"

    Module: src.agents.writer

    Purpose: Generates final reports from research findings.

    "},{"location":"api/agents/#methods_2","title":"Methods","text":""},{"location":"api/agents/#write_report","title":"write_report","text":"

    Generates a markdown report from research findings.

    Parameters: - query: Research query string - findings: Research findings to include in report - output_length: Optional description of desired output length (default: \"\") - output_instructions: Optional additional instructions for report generation (default: \"\")

    Returns: Markdown string with numbered citations.

    "},{"location":"api/agents/#longwriteragent","title":"LongWriterAgent","text":"

    Module: src.agents.long_writer

    Purpose: Long-form report generation with section-by-section writing.

    "},{"location":"api/agents/#methods_3","title":"Methods","text":""},{"location":"api/agents/#write_next_section","title":"write_next_section","text":"

    Writes the next section of a long-form report.

    Parameters: - original_query: The original research query - report_draft: Current report draft as string (all sections written so far) - next_section_title: Title of the section to write - next_section_draft: Draft content for the next section

    Returns: LongWriterOutput with formatted section and references.

    "},{"location":"api/agents/#write_report_1","title":"write_report","text":"

    Generates final report from draft.

    Parameters: - query: Research query string - report_title: Title of the report - report_draft: Complete report draft

    Returns: Final markdown report string.

    "},{"location":"api/agents/#proofreaderagent","title":"ProofreaderAgent","text":"

    Module: src.agents.proofreader

    Purpose: Proofreads and polishes report drafts.

    "},{"location":"api/agents/#methods_4","title":"Methods","text":""},{"location":"api/agents/#proofread","title":"proofread","text":"

    Proofreads and polishes a report draft.

    Parameters: - query: Research query string - report_title: Title of the report - report_draft: Report draft to proofread

    Returns: Polished markdown string.

    "},{"location":"api/agents/#thinkingagent","title":"ThinkingAgent","text":"

    Module: src.agents.thinking

    Purpose: Generates observations from conversation history.

    "},{"location":"api/agents/#methods_5","title":"Methods","text":""},{"location":"api/agents/#generate_observations","title":"generate_observations","text":"

    Generates observations from conversation history.

    Parameters: - query: Research query string - background_context: Optional background context (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\") - iteration: Current iteration number (default: 1)

    Returns: Observation string.

    "},{"location":"api/agents/#inputparseragent","title":"InputParserAgent","text":"

    Module: src.agents.input_parser

    Purpose: Parses and improves user queries, detects research mode.

    "},{"location":"api/agents/#methods_6","title":"Methods","text":""},{"location":"api/agents/#parse","title":"parse","text":"

    Parses and improves a user query.

    Parameters: - query: Original query string

    Returns: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: \"iterative\" or \"deep\" - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"api/agents/#factory-functions","title":"Factory Functions","text":"

    All agents have factory functions in src.agent_factory.agents:

    Parameters: - model: Optional Pydantic AI model. If None, uses get_model() from settings. - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Returns: Agent instance.

    "},{"location":"api/agents/#see-also","title":"See Also","text":""},{"location":"api/models/","title":"Models API Reference","text":"

    This page documents the Pydantic models used throughout DeepCritical.

    "},{"location":"api/models/#evidence","title":"Evidence","text":"

    Module: src.utils.models

    Purpose: Represents evidence from search results.

    Fields: - citation: Citation information (title, URL, date, authors) - content: Evidence text content - relevance: Relevance score (0.0-1.0) - metadata: Additional metadata dictionary

    "},{"location":"api/models/#citation","title":"Citation","text":"

    Module: src.utils.models

    Purpose: Citation information for evidence.

    Fields: - source: Source name (e.g., \"pubmed\", \"clinicaltrials\", \"europepmc\", \"web\", \"rag\") - title: Article/trial title - url: Source URL - date: Publication date (YYYY-MM-DD or \"Unknown\") - authors: List of authors (optional)

    "},{"location":"api/models/#knowledgegapoutput","title":"KnowledgeGapOutput","text":"

    Module: src.utils.models

    Purpose: Output from knowledge gap evaluation.

    Fields: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    "},{"location":"api/models/#agentselectionplan","title":"AgentSelectionPlan","text":"

    Module: src.utils.models

    Purpose: Plan for tool/agent selection.

    Fields: - tasks: List of agent tasks to execute

    "},{"location":"api/models/#agenttask","title":"AgentTask","text":"

    Module: src.utils.models

    Purpose: Individual agent task.

    Fields: - gap: The knowledge gap being addressed (optional) - agent: Name of agent to use - query: The specific query for the agent - entity_website: The website of the entity being researched, if known (optional)

    "},{"location":"api/models/#reportdraft","title":"ReportDraft","text":"

    Module: src.utils.models

    Purpose: Draft structure for long-form reports.

    Fields: - sections: List of report sections

    "},{"location":"api/models/#reportsection","title":"ReportSection","text":"

    Module: src.utils.models

    Purpose: Individual section in a report draft.

    Fields: - section_title: The title of the section - section_content: The content of the section

    "},{"location":"api/models/#parsedquery","title":"ParsedQuery","text":"

    Module: src.utils.models

    Purpose: Parsed and improved query.

    Fields: - original_query: Original query string - improved_query: Refined query string - research_mode: Research mode (\"iterative\" or \"deep\") - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"api/models/#conversation","title":"Conversation","text":"

    Module: src.utils.models

    Purpose: Conversation history with iterations.

    Fields: - history: List of iteration data

    "},{"location":"api/models/#iterationdata","title":"IterationData","text":"

    Module: src.utils.models

    Purpose: Data for a single iteration.

    Fields: - gap: The gap addressed in the iteration - tool_calls: The tool calls made - findings: The findings collected from tool calls - thought: The thinking done to reflect on the success of the iteration and next steps

    "},{"location":"api/models/#agentevent","title":"AgentEvent","text":"

    Module: src.utils.models

    Purpose: Event emitted during research execution.

    Fields: - type: Event type (e.g., \"started\", \"search_complete\", \"complete\") - iteration: Iteration number (optional) - data: Event data dictionary

    "},{"location":"api/models/#budgetstatus","title":"BudgetStatus","text":"

    Module: src.utils.models

    Purpose: Current budget status.

    Fields: - tokens_used: Total tokens used - tokens_limit: Token budget limit - time_elapsed_seconds: Time elapsed in seconds - time_limit_seconds: Time budget limit (default: 600.0 seconds / 10 minutes) - iterations: Number of iterations completed - iterations_limit: Maximum iterations (default: 10) - iteration_tokens: Tokens used per iteration (iteration number -> token count)

    "},{"location":"api/models/#see-also","title":"See Also","text":""},{"location":"api/orchestrators/","title":"Orchestrators API Reference","text":"

    This page documents the API for DeepCritical orchestrators.

    "},{"location":"api/orchestrators/#iterativeresearchflow","title":"IterativeResearchFlow","text":"

    Module: src.orchestrator.research_flow

    Purpose: Single-loop research with search-judge-synthesize cycles.

    "},{"location":"api/orchestrators/#methods","title":"Methods","text":""},{"location":"api/orchestrators/#run","title":"run","text":"

    Runs iterative research flow.

    Parameters: - query: Research query string - background_context: Background context (default: \"\") - output_length: Optional description of desired output length (default: \"\") - output_instructions: Optional additional instructions for report generation (default: \"\")

    Returns: Final report string.

    Note: max_iterations, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#deepresearchflow","title":"DeepResearchFlow","text":"

    Module: src.orchestrator.research_flow

    Purpose: Multi-section parallel research with planning and synthesis.

    "},{"location":"api/orchestrators/#methods_1","title":"Methods","text":""},{"location":"api/orchestrators/#run_1","title":"run","text":"

    Runs deep research flow.

    Parameters: - query: Research query string

    Returns: Final report string.

    Note: max_iterations_per_section, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#graphorchestrator","title":"GraphOrchestrator","text":"

    Module: src.orchestrator.graph_orchestrator

    Purpose: Graph-based execution using Pydantic AI agents as nodes.

    "},{"location":"api/orchestrators/#methods_2","title":"Methods","text":""},{"location":"api/orchestrators/#run_2","title":"run","text":"

    Runs graph-based research orchestration.

    Parameters: - query: Research query string

    Yields: AgentEvent objects during graph execution.

    Note: research_mode and use_graph are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#orchestrator-factory","title":"Orchestrator Factory","text":"

    Module: src.orchestrator_factory

    Purpose: Factory for creating orchestrators.

    "},{"location":"api/orchestrators/#functions","title":"Functions","text":""},{"location":"api/orchestrators/#create_orchestrator","title":"create_orchestrator","text":"

    Creates an orchestrator instance.

    Parameters: - search_handler: Search handler protocol implementation (optional, required for simple mode) - judge_handler: Judge handler protocol implementation (optional, required for simple mode) - config: Configuration object (optional) - mode: Orchestrator mode (\"simple\", \"advanced\", \"magentic\", \"iterative\", \"deep\", \"auto\", or None for auto-detect) - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Returns: Orchestrator instance.

    Raises: - ValueError: If requirements not met

    Modes: - \"simple\": Legacy orchestrator - \"advanced\" or \"magentic\": Magentic orchestrator (requires OpenAI API key) - None: Auto-detect based on API key availability

    "},{"location":"api/orchestrators/#magenticorchestrator","title":"MagenticOrchestrator","text":"

    Module: src.orchestrator_magentic

    Purpose: Multi-agent coordination using Microsoft Agent Framework.

    "},{"location":"api/orchestrators/#methods_3","title":"Methods","text":""},{"location":"api/orchestrators/#run_3","title":"run","text":"

    Runs Magentic orchestration.

    Parameters: - query: Research query string

    Yields: AgentEvent objects converted from Magentic events.

    Note: max_rounds and max_stalls are constructor parameters, not run() parameters.

    Requirements: - agent-framework-core package - OpenAI API key

    "},{"location":"api/orchestrators/#see-also","title":"See Also","text":""},{"location":"api/services/","title":"Services API Reference","text":"

    This page documents the API for DeepCritical services.

    "},{"location":"api/services/#embeddingservice","title":"EmbeddingService","text":"

    Module: src.services.embeddings

    Purpose: Local sentence-transformers for semantic search and deduplication.

    "},{"location":"api/services/#methods","title":"Methods","text":""},{"location":"api/services/#embed","title":"embed","text":"

    Generates embedding for a text string.

    Parameters: - text: Text to embed

    Returns: Embedding vector as list of floats.

    "},{"location":"api/services/#embed_batch","title":"embed_batch","text":"
    async def embed_batch(self, texts: list[str]) -> list[list[float]]\n

    Generates embeddings for multiple texts.

    Parameters: - texts: List of texts to embed

    Returns: List of embedding vectors.

    "},{"location":"api/services/#similarity","title":"similarity","text":"
    async def similarity(self, text1: str, text2: str) -> float\n

    Calculates similarity between two texts.

    Parameters: - text1: First text - text2: Second text

    Returns: Similarity score (0.0-1.0).

    "},{"location":"api/services/#find_duplicates","title":"find_duplicates","text":"
    async def find_duplicates(\n    self,\n    texts: list[str],\n    threshold: float = 0.85\n) -> list[tuple[int, int]]\n

    Finds duplicate texts based on similarity threshold.

    Parameters: - texts: List of texts to check - threshold: Similarity threshold (default: 0.85)

    Returns: List of (index1, index2) tuples for duplicate pairs.

    "},{"location":"api/services/#add_evidence","title":"add_evidence","text":"
    async def add_evidence(\n    self,\n    evidence_id: str,\n    content: str,\n    metadata: dict[str, Any]\n) -> None\n

    Adds evidence to vector store for semantic search.

    Parameters: - evidence_id: Unique identifier for the evidence - content: Evidence text content - metadata: Additional metadata dictionary

    "},{"location":"api/services/#search_similar","title":"search_similar","text":"
    async def search_similar(\n    self,\n    query: str,\n    n_results: int = 5\n) -> list[dict[str, Any]]\n

    Finds semantically similar evidence.

    Parameters: - query: Search query string - n_results: Number of results to return (default: 5)

    Returns: List of dictionaries with id, content, metadata, and distance keys.

    "},{"location":"api/services/#deduplicate","title":"deduplicate","text":"
    async def deduplicate(\n    self,\n    new_evidence: list[Evidence],\n    threshold: float = 0.9\n) -> list[Evidence]\n

    Removes semantically duplicate evidence.

    Parameters: - new_evidence: List of evidence items to deduplicate - threshold: Similarity threshold (default: 0.9, where 0.9 = 90% similar is duplicate)

    Returns: List of unique evidence items (not already in vector store).

    "},{"location":"api/services/#factory-function","title":"Factory Function","text":""},{"location":"api/services/#get_embedding_service","title":"get_embedding_service","text":"
    @lru_cache(maxsize=1)\ndef get_embedding_service() -> EmbeddingService\n

    Returns singleton EmbeddingService instance.

    "},{"location":"api/services/#llamaindexragservice","title":"LlamaIndexRAGService","text":"

    Module: src.services.rag

    Purpose: Retrieval-Augmented Generation using LlamaIndex.

    "},{"location":"api/services/#methods_1","title":"Methods","text":""},{"location":"api/services/#ingest_evidence","title":"ingest_evidence","text":"

    Ingests evidence into RAG service.

    Parameters: - evidence_list: List of Evidence objects to ingest

    Note: Supports multiple embedding providers (OpenAI, local sentence-transformers, Hugging Face).

    "},{"location":"api/services/#retrieve","title":"retrieve","text":"
    def retrieve(\n    self,\n    query: str,\n    top_k: int | None = None\n) -> list[dict[str, Any]]\n

    Retrieves relevant documents for a query.

    Parameters: - query: Search query string - top_k: Number of top results to return (defaults to similarity_top_k from constructor)

    Returns: List of dictionaries with text, score, and metadata keys.

    "},{"location":"api/services/#query","title":"query","text":"
    def query(\n    self,\n    query_str: str,\n    top_k: int | None = None\n) -> str\n

    Queries RAG service and returns synthesized response.

    Parameters: - query_str: Query string - top_k: Number of results to use (defaults to similarity_top_k from constructor)

    Returns: Synthesized response string.

    Raises: - ConfigurationError: If no LLM API key is available for query synthesis

    "},{"location":"api/services/#ingest_documents","title":"ingest_documents","text":"
    def ingest_documents(self, documents: list[Any]) -> None\n

    Ingests raw LlamaIndex Documents.

    Parameters: - documents: List of LlamaIndex Document objects

    "},{"location":"api/services/#clear_collection","title":"clear_collection","text":"
    def clear_collection(self) -> None\n

    Clears all documents from the collection.

    "},{"location":"api/services/#factory-function_1","title":"Factory Function","text":""},{"location":"api/services/#get_rag_service","title":"get_rag_service","text":"
    def get_rag_service(\n    collection_name: str = \"deepcritical_evidence\",\n    oauth_token: str | None = None,\n    **kwargs: Any\n) -> LlamaIndexRAGService\n

    Get or create a RAG service instance.

    Parameters: - collection_name: Name of the ChromaDB collection (default: \"deepcritical_evidence\") - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars) - **kwargs: Additional arguments for LlamaIndexRAGService (e.g., use_openai_embeddings=False)

    Returns: Configured LlamaIndexRAGService instance.

    Note: By default, uses local embeddings (sentence-transformers) which require no API keys.

    "},{"location":"api/services/#statisticalanalyzer","title":"StatisticalAnalyzer","text":"

    Module: src.services.statistical_analyzer

    Purpose: Secure execution of AI-generated statistical code.

    "},{"location":"api/services/#methods_2","title":"Methods","text":""},{"location":"api/services/#analyze","title":"analyze","text":"
    async def analyze(\n    self,\n    query: str,\n    evidence: list[Evidence],\n    hypothesis: dict[str, Any] | None = None\n) -> AnalysisResult\n

    Analyzes a research question using statistical methods.

    Parameters: - query: The research question - evidence: List of Evidence objects to analyze - hypothesis: Optional hypothesis dict with drug, target, pathway, effect, confidence keys

    Returns: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - confidence: Confidence in verdict (0.0-1.0) - statistical_evidence: Summary of statistical findings - code_generated: Python code that was executed - execution_output: Output from code execution - key_takeaways: Key takeaways from analysis - limitations: List of limitations

    Note: Requires Modal credentials for sandbox execution.

    "},{"location":"api/services/#see-also","title":"See Also","text":""},{"location":"api/tools/","title":"Tools API Reference","text":"

    This page documents the API for DeepCritical search tools.

    "},{"location":"api/tools/#searchtool-protocol","title":"SearchTool Protocol","text":"

    All tools implement the SearchTool protocol:

    class SearchTool(Protocol):\n    @property\n    def name(self) -> str: ...\n    \n    async def search(\n        self, \n        query: str, \n        max_results: int = 10\n    ) -> list[Evidence]: ...\n
    "},{"location":"api/tools/#pubmedtool","title":"PubMedTool","text":"

    Module: src.tools.pubmed

    Purpose: Search peer-reviewed biomedical literature from PubMed.

    "},{"location":"api/tools/#properties","title":"Properties","text":""},{"location":"api/tools/#name","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"pubmed\"

    "},{"location":"api/tools/#methods","title":"Methods","text":""},{"location":"api/tools/#search","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches PubMed for articles.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with PubMed articles.

    Raises: - SearchError: If search fails (timeout, HTTP error, XML parsing error) - RateLimitError: If rate limit is exceeded (429 status code)

    Note: Uses NCBI E-utilities (ESearch \u2192 EFetch). Rate limit: 0.34s between requests. Handles single vs. multiple articles.

    "},{"location":"api/tools/#clinicaltrialstool","title":"ClinicalTrialsTool","text":"

    Module: src.tools.clinicaltrials

    Purpose: Search ClinicalTrials.gov for interventional studies.

    "},{"location":"api/tools/#properties_1","title":"Properties","text":""},{"location":"api/tools/#name_1","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"clinicaltrials\"

    "},{"location":"api/tools/#methods_1","title":"Methods","text":""},{"location":"api/tools/#search_1","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches ClinicalTrials.gov for trials.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with clinical trials.

    Note: Only returns interventional studies with status: COMPLETED, ACTIVE_NOT_RECRUITING, RECRUITING, ENROLLING_BY_INVITATION. Uses requests library (NOT httpx - WAF blocks httpx). Runs in thread pool for async compatibility.

    Raises: - SearchError: If search fails (HTTP error, request exception)

    "},{"location":"api/tools/#europepmctool","title":"EuropePMCTool","text":"

    Module: src.tools.europepmc

    Purpose: Search Europe PMC for preprints and peer-reviewed articles.

    "},{"location":"api/tools/#properties_2","title":"Properties","text":""},{"location":"api/tools/#name_2","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"europepmc\"

    "},{"location":"api/tools/#methods_2","title":"Methods","text":""},{"location":"api/tools/#search_2","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches Europe PMC for articles and preprints.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with articles/preprints.

    Note: Includes both preprints (marked with [PREPRINT - Not peer-reviewed]) and peer-reviewed articles. Handles preprint markers. Builds URLs from DOI or PMID.

    Raises: - SearchError: If search fails (HTTP error, connection error)

    "},{"location":"api/tools/#ragtool","title":"RAGTool","text":"

    Module: src.tools.rag_tool

    Purpose: Semantic search within collected evidence.

    "},{"location":"api/tools/#initialization","title":"Initialization","text":"
    def __init__(\n    self,\n    rag_service: LlamaIndexRAGService | None = None,\n    oauth_token: str | None = None\n) -> None\n

    Parameters: - rag_service: Optional RAG service instance. If None, will be lazy-initialized. - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

    "},{"location":"api/tools/#properties_3","title":"Properties","text":""},{"location":"api/tools/#name_3","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"rag\"

    "},{"location":"api/tools/#methods_3","title":"Methods","text":""},{"location":"api/tools/#search_3","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches collected evidence using semantic similarity.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects from collected evidence.

    Raises: - ConfigurationError: If RAG service is unavailable

    Note: Requires evidence to be ingested into RAG service first. Wraps LlamaIndexRAGService. Returns Evidence from RAG results.

    "},{"location":"api/tools/#searchhandler","title":"SearchHandler","text":"

    Module: src.tools.search_handler

    Purpose: Orchestrates parallel searches across multiple tools.

    "},{"location":"api/tools/#initialization_1","title":"Initialization","text":"
    def __init__(\n    self,\n    tools: list[SearchTool],\n    timeout: float = 30.0,\n    include_rag: bool = False,\n    auto_ingest_to_rag: bool = True,\n    oauth_token: str | None = None\n) -> None\n

    Parameters: - tools: List of search tools to use - timeout: Timeout for each search in seconds (default: 30.0) - include_rag: Whether to include RAG tool in searches (default: False) - auto_ingest_to_rag: Whether to automatically ingest results into RAG (default: True) - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

    "},{"location":"api/tools/#methods_4","title":"Methods","text":""},{"location":"api/tools/#execute","title":"execute","text":"

    Searches multiple tools in parallel.

    Parameters: - query: Search query string - max_results_per_tool: Maximum results per tool (default: 10)

    Returns: SearchResult with: - query: The search query - evidence: Aggregated list of evidence - sources_searched: List of source names searched - total_found: Total number of results - errors: List of error messages from failed tools

    Raises: - SearchError: If search times out

    Note: Uses asyncio.gather() for parallel execution. Handles tool failures gracefully (returns errors in SearchResult.errors). Automatically ingests evidence into RAG if enabled.

    "},{"location":"api/tools/#see-also","title":"See Also","text":""},{"location":"architecture/agents/","title":"Agents Architecture","text":"

    DeepCritical uses Pydantic AI agents for all AI-powered operations. All agents follow a consistent pattern and use structured output types.

    "},{"location":"architecture/agents/#agent-pattern","title":"Agent Pattern","text":""},{"location":"architecture/agents/#pydantic-ai-agents","title":"Pydantic AI Agents","text":"

    Pydantic AI agents use the Agent class with the following structure:

    Note: Factory functions accept an optional oauth_token parameter for HuggingFace authentication, which takes priority over environment variables.

    "},{"location":"architecture/agents/#model-initialization","title":"Model Initialization","text":"

    Agents use get_model() from src/agent_factory/judges.py if no model is provided. This supports:

    The model selection is based on the configured LLM_PROVIDER in settings.

    "},{"location":"architecture/agents/#error-handling","title":"Error Handling","text":"

    Agents return fallback values on failure rather than raising exceptions:

    All errors are logged with context using structlog.

    "},{"location":"architecture/agents/#input-validation","title":"Input Validation","text":"

    All agents validate inputs:

    "},{"location":"architecture/agents/#output-types","title":"Output Types","text":"

    Agents use structured output types from src/utils/models.py:

    For text output (writer agents), agents return str directly.

    "},{"location":"architecture/agents/#agent-types","title":"Agent Types","text":""},{"location":"architecture/agents/#knowledge-gap-agent","title":"Knowledge Gap Agent","text":"

    File: src/agents/knowledge_gap.py

    Purpose: Evaluates research state and identifies knowledge gaps.

    Output: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    Methods: - async def evaluate(query, background_context, conversation_history, iteration, time_elapsed_minutes, max_time_minutes) -> KnowledgeGapOutput

    "},{"location":"architecture/agents/#tool-selector-agent","title":"Tool Selector Agent","text":"

    File: src/agents/tool_selector.py

    Purpose: Selects appropriate tools for addressing knowledge gaps.

    Output: AgentSelectionPlan with list of AgentTask objects.

    Available Agents: - WebSearchAgent: General web search for fresh information - SiteCrawlerAgent: Research specific entities/companies - RAGAgent: Semantic search within collected evidence

    "},{"location":"architecture/agents/#writer-agent","title":"Writer Agent","text":"

    File: src/agents/writer.py

    Purpose: Generates final reports from research findings.

    Output: Markdown string with numbered citations.

    Methods: - async def write_report(query, findings, output_length, output_instructions) -> str

    Features: - Validates inputs - Truncates very long findings (max 50000 chars) with warning - Retry logic for transient failures (3 retries) - Citation validation before returning

    "},{"location":"architecture/agents/#long-writer-agent","title":"Long Writer Agent","text":"

    File: src/agents/long_writer.py

    Purpose: Long-form report generation with section-by-section writing.

    Input/Output: Uses ReportDraft models.

    Methods: - async def write_next_section(query, draft, section_title, section_content) -> LongWriterOutput - async def write_report(query, report_title, report_draft) -> str

    Features: - Writes sections iteratively - Aggregates references across sections - Reformats section headings and references - Deduplicates and renumbers references

    "},{"location":"architecture/agents/#proofreader-agent","title":"Proofreader Agent","text":"

    File: src/agents/proofreader.py

    Purpose: Proofreads and polishes report drafts.

    Input: ReportDraft Output: Polished markdown string

    Methods: - async def proofread(query, report_title, report_draft) -> str

    Features: - Removes duplicate content across sections - Adds executive summary if multiple sections - Preserves all references and citations - Improves flow and readability

    "},{"location":"architecture/agents/#thinking-agent","title":"Thinking Agent","text":"

    File: src/agents/thinking.py

    Purpose: Generates observations from conversation history.

    Output: Observation string

    Methods: - async def generate_observations(query, background_context, conversation_history) -> str

    "},{"location":"architecture/agents/#input-parser-agent","title":"Input Parser Agent","text":"

    File: src/agents/input_parser.py

    Purpose: Parses and improves user queries, detects research mode.

    Output: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: \"iterative\" or \"deep\" - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"architecture/agents/#magentic-agents","title":"Magentic Agents","text":"

    The following agents use the BaseAgent pattern from agent-framework and are used exclusively with MagenticOrchestrator:

    "},{"location":"architecture/agents/#hypothesis-agent","title":"Hypothesis Agent","text":"

    File: src/agents/hypothesis_agent.py

    Purpose: Generates mechanistic hypotheses based on evidence.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Uses internal Pydantic AI Agent with HypothesisAssessment output type - Accesses shared evidence_store for evidence - Uses embedding service for diverse evidence selection (MMR algorithm) - Stores hypotheses in shared context

    "},{"location":"architecture/agents/#search-agent","title":"Search Agent","text":"

    File: src/agents/search_agent.py

    Purpose: Wraps SearchHandler as an agent for Magentic orchestrator.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Executes searches via SearchHandlerProtocol - Deduplicates evidence using embedding service - Searches for semantically related evidence - Updates shared evidence store

    "},{"location":"architecture/agents/#analysis-agent","title":"Analysis Agent","text":"

    File: src/agents/analysis_agent.py

    Purpose: Performs statistical analysis using Modal sandbox.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Wraps StatisticalAnalyzer service - Analyzes evidence and hypotheses - Returns verdict (SUPPORTED/REFUTED/INCONCLUSIVE) - Stores analysis results in shared context

    "},{"location":"architecture/agents/#report-agent-magentic","title":"Report Agent (Magentic)","text":"

    File: src/agents/report_agent.py

    Purpose: Generates structured scientific reports from evidence and hypotheses.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Uses internal Pydantic AI Agent with ResearchReport output type - Accesses shared evidence store and hypotheses - Validates citations before returning - Formats report as markdown

    "},{"location":"architecture/agents/#judge-agent","title":"Judge Agent","text":"

    File: src/agents/judge_agent.py

    Purpose: Evaluates evidence quality and determines if sufficient for synthesis.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse - async def run_stream(messages, thread, **kwargs) -> AsyncIterable[AgentRunResponseUpdate]

    Features: - Wraps JudgeHandlerProtocol - Accesses shared evidence store - Returns JudgeAssessment with sufficient flag, confidence, and recommendation

    "},{"location":"architecture/agents/#agent-patterns","title":"Agent Patterns","text":"

    DeepCritical uses two distinct agent patterns:

    "},{"location":"architecture/agents/#1-pydantic-ai-agents-traditional-pattern","title":"1. Pydantic AI Agents (Traditional Pattern)","text":"

    These agents use the Pydantic AI Agent class directly and are used in iterative and deep research flows:

    "},{"location":"architecture/agents/#2-magentic-agents-agent-framework-pattern","title":"2. Magentic Agents (Agent-Framework Pattern)","text":"

    These agents use the BaseAgent class from agent-framework and are used in Magentic orchestrator:

    Note: Magentic agents are used exclusively with the MagenticOrchestrator and follow the agent-framework protocol for multi-agent coordination.

    "},{"location":"architecture/agents/#factory-functions","title":"Factory Functions","text":"

    All agents have factory functions in src/agent_factory/agents.py:

    Factory functions: - Use get_model() if no model provided - Accept oauth_token parameter for HuggingFace authentication - Raise ConfigurationError if creation fails - Log agent creation

    "},{"location":"architecture/agents/#see-also","title":"See Also","text":""},{"location":"architecture/graph_orchestration/","title":"Graph Orchestration Architecture","text":""},{"location":"architecture/graph_orchestration/#overview","title":"Overview","text":"

    DeepCritical implements a graph-based orchestration system for research workflows using Pydantic AI agents as nodes. This enables better parallel execution, conditional routing, and state management compared to simple agent chains.

    "},{"location":"architecture/graph_orchestration/#graph-patterns","title":"Graph Patterns","text":""},{"location":"architecture/graph_orchestration/#iterative-research-graph","title":"Iterative Research Graph","text":"

    The iterative research graph follows this pattern:

    [Input] \u2192 [Thinking] \u2192 [Knowledge Gap] \u2192 [Decision: Complete?]\n                                              \u2193 No          \u2193 Yes\n                                    [Tool Selector]    [Writer]\n                                              \u2193\n                                    [Execute Tools] \u2192 [Loop Back]\n

    Node IDs: thinking \u2192 knowledge_gap \u2192 continue_decision \u2192 tool_selector/writer \u2192 execute_tools \u2192 (loop back to thinking)

    Special Node Handling: - execute_tools: State node that uses search_handler to execute searches and add evidence to workflow state - continue_decision: Decision node that routes based on research_complete flag from KnowledgeGapOutput

    "},{"location":"architecture/graph_orchestration/#deep-research-graph","title":"Deep Research Graph","text":"

    The deep research graph follows this pattern:

    [Input] \u2192 [Planner] \u2192 [Store Plan] \u2192 [Parallel Loops] \u2192 [Collect Drafts] \u2192 [Synthesizer]\n                                        \u2193         \u2193         \u2193\n                                     [Loop1]  [Loop2]  [Loop3]\n

    Node IDs: planner \u2192 store_plan \u2192 parallel_loops \u2192 collect_drafts \u2192 synthesizer

    Special Node Handling: - planner: Agent node that creates ReportPlan with report outline - store_plan: State node that stores ReportPlan in context for parallel loops - parallel_loops: Parallel node that executes IterativeResearchFlow instances for each section - collect_drafts: State node that collects section drafts from parallel loops - synthesizer: Agent node that calls LongWriterAgent.write_report() directly with ReportDraft

    "},{"location":"architecture/graph_orchestration/#deep-research","title":"Deep Research","text":"
    \nsequenceDiagram\n    actor User\n    participant GraphOrchestrator\n    participant InputParser\n    participant GraphBuilder\n    participant GraphExecutor\n    participant Agent\n    participant BudgetTracker\n    participant WorkflowState\n\n    User->>GraphOrchestrator: run(query)\n    GraphOrchestrator->>InputParser: detect_research_mode(query)\n    InputParser-->>GraphOrchestrator: mode (iterative/deep)\n    GraphOrchestrator->>GraphBuilder: build_graph(mode)\n    GraphBuilder-->>GraphOrchestrator: ResearchGraph\n    GraphOrchestrator->>WorkflowState: init_workflow_state()\n    GraphOrchestrator->>BudgetTracker: create_budget()\n    GraphOrchestrator->>GraphExecutor: _execute_graph(graph)\n    \n    loop For each node in graph\n        GraphExecutor->>Agent: execute_node(agent_node)\n        Agent->>Agent: process_input\n        Agent-->>GraphExecutor: result\n        GraphExecutor->>WorkflowState: update_state(result)\n        GraphExecutor->>BudgetTracker: add_tokens(used)\n        GraphExecutor->>BudgetTracker: check_budget()\n        alt Budget exceeded\n            GraphExecutor->>GraphOrchestrator: emit(error_event)\n        else Continue\n            GraphExecutor->>GraphOrchestrator: emit(progress_event)\n        end\n    end\n    \n    GraphOrchestrator->>User: AsyncGenerator[AgentEvent]\n
    "},{"location":"architecture/graph_orchestration/#iterative-research","title":"Iterative Research","text":"
    sequenceDiagram\n    participant IterativeFlow\n    participant ThinkingAgent\n    participant KnowledgeGapAgent\n    participant ToolSelector\n    participant ToolExecutor\n    participant JudgeHandler\n    participant WriterAgent\n\n    IterativeFlow->>IterativeFlow: run(query)\n    \n    loop Until complete or max_iterations\n        IterativeFlow->>ThinkingAgent: generate_observations()\n        ThinkingAgent-->>IterativeFlow: observations\n        \n        IterativeFlow->>KnowledgeGapAgent: evaluate_gaps()\n        KnowledgeGapAgent-->>IterativeFlow: KnowledgeGapOutput\n        \n        alt Research complete\n            IterativeFlow->>WriterAgent: create_final_report()\n            WriterAgent-->>IterativeFlow: final_report\n        else Gaps remain\n            IterativeFlow->>ToolSelector: select_agents(gap)\n            ToolSelector-->>IterativeFlow: AgentSelectionPlan\n            \n            IterativeFlow->>ToolExecutor: execute_tool_tasks()\n            ToolExecutor-->>IterativeFlow: ToolAgentOutput[]\n            \n            IterativeFlow->>JudgeHandler: assess_evidence()\n            JudgeHandler-->>IterativeFlow: should_continue\n        end\n    end
    "},{"location":"architecture/graph_orchestration/#graph-structure","title":"Graph Structure","text":""},{"location":"architecture/graph_orchestration/#nodes","title":"Nodes","text":"

    Graph nodes represent different stages in the research workflow:

    1. Agent Nodes: Execute Pydantic AI agents
    2. Input: Prompt/query
    3. Output: Structured or unstructured response
    4. Examples: KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent

    5. State Nodes: Update or read workflow state

    6. Input: Current state
    7. Output: Updated state
    8. Examples: Update evidence, update conversation history

    9. Decision Nodes: Make routing decisions based on conditions

    10. Input: Current state/results
    11. Output: Next node ID
    12. Examples: Continue research vs. complete research

    13. Parallel Nodes: Execute multiple nodes concurrently

    14. Input: List of node IDs
    15. Output: Aggregated results
    16. Examples: Parallel iterative research loops
    "},{"location":"architecture/graph_orchestration/#edges","title":"Edges","text":"

    Edges define transitions between nodes:

    1. Sequential Edges: Always traversed (no condition)
    2. From: Source node
    3. To: Target node
    4. Condition: None (always True)

    5. Conditional Edges: Traversed based on condition

    6. From: Source node
    7. To: Target node
    8. Condition: Callable that returns bool
    9. Example: If research complete \u2192 go to writer, else \u2192 continue loop

    10. Parallel Edges: Used for parallel execution branches

    11. From: Parallel node
    12. To: Multiple target nodes
    13. Execution: All targets run concurrently
    "},{"location":"architecture/graph_orchestration/#state-management","title":"State Management","text":"

    State is managed via WorkflowState using ContextVar for thread-safe isolation:

    State transitions occur at state nodes, which update the global workflow state.

    "},{"location":"architecture/graph_orchestration/#execution-flow","title":"Execution Flow","text":"
    1. Graph Construction: Build graph from nodes and edges using create_iterative_graph() or create_deep_graph()
    2. Graph Validation: Ensure graph is valid (no cycles, all nodes reachable) via ResearchGraph.validate_structure()
    3. Graph Execution: Traverse graph from entry node using GraphOrchestrator._execute_graph()
    4. Node Execution: Execute each node based on type:
    5. Agent Nodes: Call agent.run() with transformed input
    6. State Nodes: Update workflow state via state_updater function
    7. Decision Nodes: Evaluate decision_function to get next node ID
    8. Parallel Nodes: Execute all parallel nodes concurrently via asyncio.gather()
    9. Edge Evaluation: Determine next node(s) based on edges and conditions
    10. Parallel Execution: Use asyncio.gather() for parallel nodes
    11. State Updates: Update state at state nodes via GraphExecutionContext.update_state()
    12. Event Streaming: Yield AgentEvent objects during execution for UI
    "},{"location":"architecture/graph_orchestration/#graphexecutioncontext","title":"GraphExecutionContext","text":"

    The GraphExecutionContext class manages execution state during graph traversal:

    Methods: - set_node_result(node_id, result): Store result from node execution - get_node_result(node_id): Retrieve stored result - has_visited(node_id): Check if node was visited - mark_visited(node_id): Mark node as visited - update_state(updater, data): Update workflow state

    "},{"location":"architecture/graph_orchestration/#conditional-routing","title":"Conditional Routing","text":"

    Decision nodes evaluate conditions and return next node IDs:

    "},{"location":"architecture/graph_orchestration/#parallel-execution","title":"Parallel Execution","text":"

    Parallel nodes execute multiple nodes concurrently:

    "},{"location":"architecture/graph_orchestration/#budget-enforcement","title":"Budget Enforcement","text":"

    Budget constraints are enforced at decision nodes:

    If any budget is exceeded, execution routes to exit node.

    "},{"location":"architecture/graph_orchestration/#error-handling","title":"Error Handling","text":"

    Errors are handled at multiple levels:

    1. Node Level: Catch errors in individual node execution
    2. Graph Level: Handle errors during graph traversal
    3. State Level: Rollback state changes on error

    Errors are logged and yield error events for UI.

    "},{"location":"architecture/graph_orchestration/#backward-compatibility","title":"Backward Compatibility","text":"

    Graph execution is optional via feature flag:

    This allows gradual migration and fallback if needed.

    "},{"location":"architecture/graph_orchestration/#see-also","title":"See Also","text":""},{"location":"architecture/middleware/","title":"Middleware Architecture","text":"

    DeepCritical uses middleware for state management, budget tracking, and workflow coordination.

    "},{"location":"architecture/middleware/#state-management","title":"State Management","text":""},{"location":"architecture/middleware/#workflowstate","title":"WorkflowState","text":"

    File: src/middleware/state_machine.py

    Purpose: Thread-safe state management for research workflows

    Implementation: Uses ContextVar for thread-safe isolation

    State Components: - evidence: list[Evidence]: Collected evidence from searches - conversation: Conversation: Iteration history (gaps, tool calls, findings, thoughts) - embedding_service: Any: Embedding service for semantic search

    Methods: - add_evidence(new_evidence: list[Evidence]) -> int: Adds evidence with URL-based deduplication. Returns the number of new items added (excluding duplicates). - async search_related(query: str, n_results: int = 5) -> list[Evidence]: Semantic search for related evidence using embedding service

    Initialization:

    Access:

    "},{"location":"architecture/middleware/#workflow-manager","title":"Workflow Manager","text":"

    File: src/middleware/workflow_manager.py

    Purpose: Coordinates parallel research loops

    Methods: - async add_loop(loop_id: str, query: str) -> ResearchLoop: Add a new research loop to manage - async run_loops_parallel(loop_configs: list[dict], loop_func: Callable, judge_handler: Any | None = None, budget_tracker: Any | None = None) -> list[Any]: Run multiple research loops in parallel. Takes configuration dicts and a loop function. - async update_loop_status(loop_id: str, status: LoopStatus, error: str | None = None): Update loop status - async sync_loop_evidence_to_state(loop_id: str): Synchronize evidence from a specific loop to global state

    Features: - Uses asyncio.gather() for parallel execution - Handles errors per loop (doesn't fail all if one fails) - Tracks loop status: pending, running, completed, failed, cancelled - Evidence deduplication across parallel loops

    Usage:

    from src.middleware.workflow_manager import WorkflowManager\n\nmanager = WorkflowManager()\nawait manager.add_loop(\"loop1\", \"Research query 1\")\nawait manager.add_loop(\"loop2\", \"Research query 2\")\n\nasync def run_research(config: dict) -> str:\n    loop_id = config[\"loop_id\"]\n    query = config[\"query\"]\n    # ... research logic ...\n    return \"report\"\n\nresults = await manager.run_loops_parallel(\n    loop_configs=[\n        {\"loop_id\": \"loop1\", \"query\": \"Research query 1\"},\n        {\"loop_id\": \"loop2\", \"query\": \"Research query 2\"},\n    ],\n    loop_func=run_research,\n)\n

    "},{"location":"architecture/middleware/#budget-tracker","title":"Budget Tracker","text":"

    File: src/middleware/budget_tracker.py

    Purpose: Tracks and enforces resource limits

    Budget Components: - Tokens: LLM token usage - Time: Elapsed time in seconds - Iterations: Number of iterations

    Methods: - create_budget(loop_id: str, tokens_limit: int = 100000, time_limit_seconds: float = 600.0, iterations_limit: int = 10) -> BudgetStatus: Create a budget for a specific loop - add_tokens(loop_id: str, tokens: int): Add token usage to a loop's budget - start_timer(loop_id: str): Start time tracking for a loop - update_timer(loop_id: str): Update elapsed time for a loop - increment_iteration(loop_id: str): Increment iteration count for a loop - check_budget(loop_id: str) -> tuple[bool, str]: Check if a loop's budget has been exceeded. Returns (exceeded: bool, reason: str) - can_continue(loop_id: str) -> bool: Check if a loop can continue based on budget

    Token Estimation: - estimate_tokens(text: str) -> int: ~4 chars per token - estimate_llm_call_tokens(prompt: str, response: str) -> int: Estimate LLM call tokens

    Usage:

    from src.middleware.budget_tracker import BudgetTracker\n\ntracker = BudgetTracker()\nbudget = tracker.create_budget(\n    loop_id=\"research_loop\",\n    tokens_limit=100000,\n    time_limit_seconds=600,\n    iterations_limit=10\n)\ntracker.start_timer(\"research_loop\")\n# ... research operations ...\ntracker.add_tokens(\"research_loop\", 5000)\ntracker.update_timer(\"research_loop\")\nexceeded, reason = tracker.check_budget(\"research_loop\")\nif exceeded:\n    # Budget exceeded, stop research\n    pass\nif not tracker.can_continue(\"research_loop\"):\n    # Budget exceeded, stop research\n    pass\n

    "},{"location":"architecture/middleware/#models","title":"Models","text":"

    All middleware models are defined in src/utils/models.py:

    "},{"location":"architecture/middleware/#thread-safety","title":"Thread Safety","text":"

    All middleware components use ContextVar for thread-safe isolation:

    "},{"location":"architecture/middleware/#see-also","title":"See Also","text":""},{"location":"architecture/orchestrators/","title":"Orchestrators Architecture","text":"

    DeepCritical supports multiple orchestration patterns for research workflows.

    "},{"location":"architecture/orchestrators/#research-flows","title":"Research Flows","text":""},{"location":"architecture/orchestrators/#iterativeresearchflow","title":"IterativeResearchFlow","text":"

    File: src/orchestrator/research_flow.py

    Pattern: Generate observations \u2192 Evaluate gaps \u2192 Select tools \u2192 Execute \u2192 Judge \u2192 Continue/Complete

    Agents Used: - KnowledgeGapAgent: Evaluates research completeness - ToolSelectorAgent: Selects tools for addressing gaps - ThinkingAgent: Generates observations - WriterAgent: Creates final report - JudgeHandler: Assesses evidence sufficiency

    Features: - Tracks iterations, time, budget - Supports graph execution (use_graph=True) and agent chains (use_graph=False) - Iterates until research complete or constraints met

    Usage:

    "},{"location":"architecture/orchestrators/#deepresearchflow","title":"DeepResearchFlow","text":"

    File: src/orchestrator/research_flow.py

    Pattern: Planner \u2192 Parallel iterative loops per section \u2192 Synthesizer

    Agents Used: - PlannerAgent: Breaks query into report sections - IterativeResearchFlow: Per-section research (parallel) - LongWriterAgent or ProofreaderAgent: Final synthesis

    Features: - Uses WorkflowManager for parallel execution - Budget tracking per section and globally - State synchronization across parallel loops - Supports graph execution and agent chains

    Usage:

    "},{"location":"architecture/orchestrators/#graph-orchestrator","title":"Graph Orchestrator","text":"

    File: src/orchestrator/graph_orchestrator.py

    Purpose: Graph-based execution using Pydantic AI agents as nodes

    Features: - Uses graph execution (use_graph=True) or agent chains (use_graph=False) as fallback - Routes based on research mode (iterative/deep/auto) - Streams AgentEvent objects for UI - Uses GraphExecutionContext to manage execution state

    Node Types: - Agent Nodes: Execute Pydantic AI agents - State Nodes: Update or read workflow state - Decision Nodes: Make routing decisions - Parallel Nodes: Execute multiple nodes concurrently

    Edge Types: - Sequential Edges: Always traversed - Conditional Edges: Traversed based on condition - Parallel Edges: Used for parallel execution branches

    Special Node Handling:

    The GraphOrchestrator has special handling for certain nodes:

    GraphExecutionContext:

    The orchestrator uses GraphExecutionContext to manage execution state: - Tracks current node, visited nodes, and node results - Manages workflow state and budget tracker - Provides methods to store and retrieve node execution results

    "},{"location":"architecture/orchestrators/#orchestrator-factory","title":"Orchestrator Factory","text":"

    File: src/orchestrator_factory.py

    Purpose: Factory for creating orchestrators

    Modes: - Simple: Legacy orchestrator (backward compatible) - Advanced: Magentic orchestrator (requires OpenAI API key) - Auto-detect: Chooses based on API key availability

    Usage:

    "},{"location":"architecture/orchestrators/#magentic-orchestrator","title":"Magentic Orchestrator","text":"

    File: src/orchestrator_magentic.py

    Purpose: Multi-agent coordination using Microsoft Agent Framework

    Features: - Uses agent-framework-core - ChatAgent pattern with internal LLMs per agent - MagenticBuilder with participants: - searcher: SearchAgent (wraps SearchHandler) - hypothesizer: HypothesisAgent (generates hypotheses) - judge: JudgeAgent (evaluates evidence) - reporter: ReportAgent (generates final report) - Manager orchestrates agents via chat client (OpenAI or HuggingFace) - Event-driven: converts Magentic events to AgentEvent for UI streaming via _process_event() method - Supports max rounds, stall detection, and reset handling

    Event Processing:

    The orchestrator processes Magentic events and converts them to AgentEvent: - MagenticOrchestratorMessageEvent \u2192 AgentEvent with type based on message content - MagenticAgentMessageEvent \u2192 AgentEvent with type based on agent name - MagenticAgentDeltaEvent \u2192 AgentEvent for streaming updates - MagenticFinalResultEvent \u2192 AgentEvent with type \"complete\"

    Requirements: - agent-framework-core package - OpenAI API key or HuggingFace authentication

    "},{"location":"architecture/orchestrators/#hierarchical-orchestrator","title":"Hierarchical Orchestrator","text":"

    File: src/orchestrator_hierarchical.py

    Purpose: Hierarchical orchestrator using middleware and sub-teams

    Features: - Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge - Adapts Magentic ChatAgent to SubIterationTeam protocol - Event-driven via asyncio.Queue for coordination - Supports sub-iteration patterns for complex research tasks

    "},{"location":"architecture/orchestrators/#legacy-simple-mode","title":"Legacy Simple Mode","text":"

    File: src/legacy_orchestrator.py

    Purpose: Linear search-judge-synthesize loop

    Features: - Uses SearchHandlerProtocol and JudgeHandlerProtocol - Generator-based design yielding AgentEvent objects - Backward compatibility for simple use cases

    "},{"location":"architecture/orchestrators/#state-initialization","title":"State Initialization","text":"

    All orchestrators must initialize workflow state:

    "},{"location":"architecture/orchestrators/#event-streaming","title":"Event Streaming","text":"

    All orchestrators yield AgentEvent objects:

    Event Types: - started: Research started - searching: Search in progress - search_complete: Search completed - judging: Evidence evaluation in progress - judge_complete: Evidence evaluation completed - looping: Iteration in progress - hypothesizing: Generating hypotheses - analyzing: Statistical analysis in progress - analysis_complete: Statistical analysis completed - synthesizing: Synthesizing results - complete: Research completed - error: Error occurred - streaming: Streaming update (delta events)

    Event Structure:

    "},{"location":"architecture/orchestrators/#see-also","title":"See Also","text":""},{"location":"architecture/services/","title":"Services Architecture","text":"

    DeepCritical provides several services for embeddings, RAG, and statistical analysis.

    "},{"location":"architecture/services/#embedding-service","title":"Embedding Service","text":"

    File: src/services/embeddings.py

    Purpose: Local sentence-transformers for semantic search and deduplication

    Features: - No API Key Required: Uses local sentence-transformers models - Async-Safe: All operations use run_in_executor() to avoid blocking the event loop - ChromaDB Storage: In-memory vector storage for embeddings - Deduplication: 0.9 similarity threshold by default (90% similarity = duplicate, configurable)

    Model: Configurable via settings.local_embedding_model (default: all-MiniLM-L6-v2)

    Methods: - async def embed(text: str) -> list[float]: Generate embeddings (async-safe via run_in_executor()) - async def embed_batch(texts: list[str]) -> list[list[float]]: Batch embedding (more efficient) - async def add_evidence(evidence_id: str, content: str, metadata: dict[str, Any]) -> None: Add evidence to vector store - async def search_similar(query: str, n_results: int = 5) -> list[dict[str, Any]]: Find semantically similar evidence - async def deduplicate(new_evidence: list[Evidence], threshold: float = 0.9) -> list[Evidence]: Remove semantically duplicate evidence

    Usage:

    from src.services.embeddings import get_embedding_service\n\nservice = get_embedding_service()\nembedding = await service.embed(\"text to embed\")\n

    "},{"location":"architecture/services/#llamaindex-rag-service","title":"LlamaIndex RAG Service","text":"

    File: src/services/llamaindex_rag.py

    Purpose: Retrieval-Augmented Generation using LlamaIndex

    Features: - Multiple Embedding Providers: OpenAI embeddings (requires OPENAI_API_KEY) or local sentence-transformers (no API key) - Multiple LLM Providers: HuggingFace LLM (preferred) or OpenAI LLM (fallback) for query synthesis - ChromaDB Storage: Vector database for document storage (supports in-memory mode) - Metadata Preservation: Preserves source, title, URL, date, authors - Lazy Initialization: Graceful fallback if dependencies not available

    Initialization Parameters: - use_openai_embeddings: bool | None: Force OpenAI embeddings (None = auto-detect) - use_in_memory: bool: Use in-memory ChromaDB client (useful for tests) - oauth_token: str | None: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Methods: - async def ingest_evidence(evidence: list[Evidence]) -> None: Ingest evidence into RAG - async def retrieve(query: str, top_k: int = 5) -> list[Document]: Retrieve relevant documents - async def query(query: str, top_k: int = 5) -> str: Query with RAG

    Usage:

    from src.services.llamaindex_rag import get_rag_service\n\nservice = get_rag_service(\n    use_openai_embeddings=False,  # Use local embeddings\n    use_in_memory=True,  # Use in-memory ChromaDB\n    oauth_token=token  # Optional HuggingFace token\n)\nif service:\n    documents = await service.retrieve(\"query\", top_k=5)\n

    "},{"location":"architecture/services/#statistical-analyzer","title":"Statistical Analyzer","text":"

    File: src/services/statistical_analyzer.py

    Purpose: Secure execution of AI-generated statistical code

    Features: - Modal Sandbox: Secure, isolated execution environment - Code Generation: Generates Python code via LLM - Library Pinning: Version-pinned libraries in SANDBOX_LIBRARIES - Network Isolation: block_network=True by default

    Libraries Available: - pandas, numpy, scipy - matplotlib, scikit-learn - statsmodels

    Output: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - code: Generated analysis code - output: Execution output - error: Error message if execution failed

    Usage:

    from src.services.statistical_analyzer import StatisticalAnalyzer\n\nanalyzer = StatisticalAnalyzer()\nresult = await analyzer.analyze(\n    hypothesis=\"Metformin reduces cancer risk\",\n    evidence=evidence_list\n)\n

    "},{"location":"architecture/services/#singleton-pattern","title":"Singleton Pattern","text":"

    Services use singleton patterns for lazy initialization:

    EmbeddingService: Uses a global variable pattern:

    LlamaIndexRAGService: Direct instantiation (no caching):

    This ensures: - Single instance per process - Lazy initialization - No dependencies required at import time

    "},{"location":"architecture/services/#service-availability","title":"Service Availability","text":"

    Services check availability before use:

    from src.utils.config import settings\n\nif settings.modal_available:\n    # Use Modal sandbox\n    pass\n\nif settings.has_openai_key:\n    # Use OpenAI embeddings for RAG\n    pass\n
    "},{"location":"architecture/services/#see-also","title":"See Also","text":""},{"location":"architecture/tools/","title":"Tools Architecture","text":"

    DeepCritical implements a protocol-based search tool system for retrieving evidence from multiple sources.

    "},{"location":"architecture/tools/#searchtool-protocol","title":"SearchTool Protocol","text":"

    All tools implement the SearchTool protocol from src/tools/base.py:

    "},{"location":"architecture/tools/#rate-limiting","title":"Rate Limiting","text":"

    All tools use the @retry decorator from tenacity:

    Tools with API rate limits implement _rate_limit() method and use shared rate limiters from src/tools/rate_limiter.py.

    "},{"location":"architecture/tools/#error-handling","title":"Error Handling","text":"

    Tools raise custom exceptions:

    Tools handle HTTP errors (429, 500, timeout) and return empty lists on non-critical errors (with warning logs).

    "},{"location":"architecture/tools/#query-preprocessing","title":"Query Preprocessing","text":"

    Tools use preprocess_query() from src/tools/query_utils.py to:

    "},{"location":"architecture/tools/#evidence-conversion","title":"Evidence Conversion","text":"

    All tools convert API responses to Evidence objects with:

    Missing fields are handled gracefully with defaults.

    "},{"location":"architecture/tools/#tool-implementations","title":"Tool Implementations","text":""},{"location":"architecture/tools/#pubmed-tool","title":"PubMed Tool","text":"

    File: src/tools/pubmed.py

    API: NCBI E-utilities (ESearch \u2192 EFetch)

    Rate Limiting: - 0.34s between requests (3 req/sec without API key) - 0.1s between requests (10 req/sec with NCBI API key)

    Features: - XML parsing with xmltodict - Handles single vs. multiple articles - Query preprocessing - Evidence conversion with metadata extraction

    "},{"location":"architecture/tools/#clinicaltrials-tool","title":"ClinicalTrials Tool","text":"

    File: src/tools/clinicaltrials.py

    API: ClinicalTrials.gov API v2

    Important: Uses requests library (NOT httpx) because WAF blocks httpx TLS fingerprint.

    Execution: Runs in thread pool: await asyncio.to_thread(requests.get, ...)

    Filtering: - Only interventional studies - Status: COMPLETED, ACTIVE_NOT_RECRUITING, RECRUITING, ENROLLING_BY_INVITATION

    Features: - Parses nested JSON structure - Extracts trial metadata - Evidence conversion

    "},{"location":"architecture/tools/#europe-pmc-tool","title":"Europe PMC Tool","text":"

    File: src/tools/europepmc.py

    API: Europe PMC REST API

    Features: - Handles preprint markers: [PREPRINT - Not peer-reviewed] - Builds URLs from DOI or PMID - Checks pubTypeList for preprint detection - Includes both preprints and peer-reviewed articles

    "},{"location":"architecture/tools/#rag-tool","title":"RAG Tool","text":"

    File: src/tools/rag_tool.py

    Purpose: Semantic search within collected evidence

    Implementation: Wraps LlamaIndexRAGService

    Features: - Returns Evidence from RAG results - Handles evidence ingestion - Semantic similarity search - Metadata preservation

    "},{"location":"architecture/tools/#search-handler","title":"Search Handler","text":"

    File: src/tools/search_handler.py

    Purpose: Orchestrates parallel searches across multiple tools

    Initialization Parameters: - tools: list[SearchTool]: List of search tools to use - timeout: float = 30.0: Timeout for each search in seconds - include_rag: bool = False: Whether to include RAG tool in searches - auto_ingest_to_rag: bool = True: Whether to automatically ingest results into RAG - oauth_token: str | None = None: Optional OAuth token from HuggingFace login (for RAG LLM)

    Methods: - async def execute(query: str, max_results_per_tool: int = 10) -> SearchResult: Execute search across all tools in parallel

    Features: - Uses asyncio.gather() with return_exceptions=True for parallel execution - Aggregates results into SearchResult with evidence and metadata - Handles tool failures gracefully (continues with other tools) - Deduplicates results by URL - Automatically ingests results into RAG if auto_ingest_to_rag=True - Can add RAG tool dynamically via add_rag_tool() method

    "},{"location":"architecture/tools/#tool-registration","title":"Tool Registration","text":"

    Tools are registered in the search handler:

    from src.tools.pubmed import PubMedTool\nfrom src.tools.clinicaltrials import ClinicalTrialsTool\nfrom src.tools.europepmc import EuropePMCTool\nfrom src.tools.search_handler import SearchHandler\n\nsearch_handler = SearchHandler(\n    tools=[\n        PubMedTool(),\n        ClinicalTrialsTool(),\n        EuropePMCTool(),\n    ],\n    include_rag=True,  # Include RAG tool for semantic search\n    auto_ingest_to_rag=True,  # Automatically ingest results into RAG\n    oauth_token=token  # Optional HuggingFace token for RAG LLM\n)\n\n# Execute search\nresult = await search_handler.execute(\"query\", max_results_per_tool=10)\n
    "},{"location":"architecture/tools/#see-also","title":"See Also","text":""},{"location":"architecture/workflow-diagrams/","title":"DeepCritical Workflow - Simplified Magentic Architecture","text":"

    Architecture Pattern: Microsoft Magentic Orchestration Design Philosophy: Simple, dynamic, manager-driven coordination Key Innovation: Intelligent manager replaces rigid sequential phases

    "},{"location":"architecture/workflow-diagrams/#1-high-level-magentic-workflow","title":"1. High-Level Magentic Workflow","text":"
    flowchart TD\n    Start([User Query]) --> Manager[Magentic Manager<br/>Plan \u2022 Select \u2022 Assess \u2022 Adapt]\n\n    Manager -->|Plans| Task1[Task Decomposition]\n    Task1 --> Manager\n\n    Manager -->|Selects & Executes| HypAgent[Hypothesis Agent]\n    Manager -->|Selects & Executes| SearchAgent[Search Agent]\n    Manager -->|Selects & Executes| AnalysisAgent[Analysis Agent]\n    Manager -->|Selects & Executes| ReportAgent[Report Agent]\n\n    HypAgent -->|Results| Manager\n    SearchAgent -->|Results| Manager\n    AnalysisAgent -->|Results| Manager\n    ReportAgent -->|Results| Manager\n\n    Manager -->|Assesses Quality| Decision{Good Enough?}\n    Decision -->|No - Refine| Manager\n    Decision -->|No - Different Agent| Manager\n    Decision -->|No - Stalled| Replan[Reset Plan]\n    Replan --> Manager\n\n    Decision -->|Yes| Synthesis[Synthesize Final Result]\n    Synthesis --> Output([Research Report])\n\n    style Start fill:#e1f5e1\n    style Manager fill:#ffe6e6\n    style HypAgent fill:#fff4e6\n    style SearchAgent fill:#fff4e6\n    style AnalysisAgent fill:#fff4e6\n    style ReportAgent fill:#fff4e6\n    style Decision fill:#ffd6d6\n    style Synthesis fill:#d4edda\n    style Output fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#2-magentic-manager-the-6-phase-cycle","title":"2. Magentic Manager: The 6-Phase Cycle","text":"
    flowchart LR\n    P1[1. Planning<br/>Analyze task<br/>Create strategy] --> P2[2. Agent Selection<br/>Pick best agent<br/>for subtask]\n    P2 --> P3[3. Execution<br/>Run selected<br/>agent with tools]\n    P3 --> P4[4. Assessment<br/>Evaluate quality<br/>Check progress]\n    P4 --> Decision{Quality OK?<br/>Progress made?}\n    Decision -->|Yes| P6[6. Synthesis<br/>Combine results<br/>Generate report]\n    Decision -->|No| P5[5. Iteration<br/>Adjust plan<br/>Try again]\n    P5 --> P2\n    P6 --> Done([Complete])\n\n    style P1 fill:#fff4e6\n    style P2 fill:#ffe6e6\n    style P3 fill:#e6f3ff\n    style P4 fill:#ffd6d6\n    style P5 fill:#fff3cd\n    style P6 fill:#d4edda\n    style Done fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#3-simplified-agent-architecture","title":"3. Simplified Agent Architecture","text":"
    graph TB\n    subgraph \"Orchestration Layer\"\n        Manager[Magentic Manager<br/>\u2022 Plans workflow<br/>\u2022 Selects agents<br/>\u2022 Assesses quality<br/>\u2022 Adapts strategy]\n        SharedContext[(Shared Context<br/>\u2022 Hypotheses<br/>\u2022 Search Results<br/>\u2022 Analysis<br/>\u2022 Progress)]\n        Manager <--> SharedContext\n    end\n\n    subgraph \"Specialist Agents\"\n        HypAgent[Hypothesis Agent<br/>\u2022 Domain understanding<br/>\u2022 Hypothesis generation<br/>\u2022 Testability refinement]\n        SearchAgent[Search Agent<br/>\u2022 Multi-source search<br/>\u2022 RAG retrieval<br/>\u2022 Result ranking]\n        AnalysisAgent[Analysis Agent<br/>\u2022 Evidence extraction<br/>\u2022 Statistical analysis<br/>\u2022 Code execution]\n        ReportAgent[Report Agent<br/>\u2022 Report assembly<br/>\u2022 Visualization<br/>\u2022 Citation formatting]\n    end\n\n    subgraph \"MCP Tools\"\n        WebSearch[Web Search<br/>PubMed \u2022 arXiv \u2022 bioRxiv]\n        CodeExec[Code Execution<br/>Sandboxed Python]\n        RAG[RAG Retrieval<br/>Vector DB \u2022 Embeddings]\n        Viz[Visualization<br/>Charts \u2022 Graphs]\n    end\n\n    Manager -->|Selects & Directs| HypAgent\n    Manager -->|Selects & Directs| SearchAgent\n    Manager -->|Selects & Directs| AnalysisAgent\n    Manager -->|Selects & Directs| ReportAgent\n\n    HypAgent --> SharedContext\n    SearchAgent --> SharedContext\n    AnalysisAgent --> SharedContext\n    ReportAgent --> SharedContext\n\n    SearchAgent --> WebSearch\n    SearchAgent --> RAG\n    AnalysisAgent --> CodeExec\n    ReportAgent --> CodeExec\n    ReportAgent --> Viz\n\n    style Manager fill:#ffe6e6\n    style SharedContext fill:#ffe6f0\n    style HypAgent fill:#fff4e6\n    style SearchAgent fill:#fff4e6\n    style AnalysisAgent fill:#fff4e6\n    style ReportAgent fill:#fff4e6\n    style WebSearch fill:#e6f3ff\n    style CodeExec fill:#e6f3ff\n    style RAG fill:#e6f3ff\n    style Viz fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#4-dynamic-workflow-example","title":"4. Dynamic Workflow Example","text":"
    sequenceDiagram\n    participant User\n    participant Manager\n    participant HypAgent\n    participant SearchAgent\n    participant AnalysisAgent\n    participant ReportAgent\n\n    User->>Manager: \"Research protein folding in Alzheimer's\"\n\n    Note over Manager: PLAN: Generate hypotheses \u2192 Search \u2192 Analyze \u2192 Report\n\n    Manager->>HypAgent: Generate 3 hypotheses\n    HypAgent-->>Manager: Returns 3 hypotheses\n    Note over Manager: ASSESS: Good quality, proceed\n\n    Manager->>SearchAgent: Search literature for hypothesis 1\n    SearchAgent-->>Manager: Returns 15 papers\n    Note over Manager: ASSESS: Good results, continue\n\n    Manager->>SearchAgent: Search for hypothesis 2\n    SearchAgent-->>Manager: Only 2 papers found\n    Note over Manager: ASSESS: Insufficient, refine search\n\n    Manager->>SearchAgent: Refined query for hypothesis 2\n    SearchAgent-->>Manager: Returns 12 papers\n    Note over Manager: ASSESS: Better, proceed\n\n    Manager->>AnalysisAgent: Analyze evidence for all hypotheses\n    AnalysisAgent-->>Manager: Returns analysis with code\n    Note over Manager: ASSESS: Complete, generate report\n\n    Manager->>ReportAgent: Create comprehensive report\n    ReportAgent-->>Manager: Returns formatted report\n    Note over Manager: SYNTHESIZE: Combine all results\n\n    Manager->>User: Final Research Report
    "},{"location":"architecture/workflow-diagrams/#5-manager-decision-logic","title":"5. Manager Decision Logic","text":"
    flowchart TD\n    Start([Manager Receives Task]) --> Plan[Create Initial Plan]\n\n    Plan --> Select[Select Agent for Next Subtask]\n    Select --> Execute[Execute Agent]\n    Execute --> Collect[Collect Results]\n\n    Collect --> Assess[Assess Quality & Progress]\n\n    Assess --> Q1{Quality Sufficient?}\n    Q1 -->|No| Q2{Same Agent Can Fix?}\n    Q2 -->|Yes| Feedback[Provide Specific Feedback]\n    Feedback --> Execute\n    Q2 -->|No| Different[Try Different Agent]\n    Different --> Select\n\n    Q1 -->|Yes| Q3{Task Complete?}\n    Q3 -->|No| Q4{Making Progress?}\n    Q4 -->|Yes| Select\n    Q4 -->|No - Stalled| Replan[Reset Plan & Approach]\n    Replan --> Plan\n\n    Q3 -->|Yes| Synth[Synthesize Final Result]\n    Synth --> Done([Return Report])\n\n    style Start fill:#e1f5e1\n    style Plan fill:#fff4e6\n    style Select fill:#ffe6e6\n    style Execute fill:#e6f3ff\n    style Assess fill:#ffd6d6\n    style Q1 fill:#ffe6e6\n    style Q2 fill:#ffe6e6\n    style Q3 fill:#ffe6e6\n    style Q4 fill:#ffe6e6\n    style Synth fill:#d4edda\n    style Done fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#6-hypothesis-agent-workflow","title":"6. Hypothesis Agent Workflow","text":"
    flowchart LR\n    Input[Research Query] --> Domain[Identify Domain<br/>& Key Concepts]\n    Domain --> Context[Retrieve Background<br/>Knowledge]\n    Context --> Generate[Generate 3-5<br/>Initial Hypotheses]\n    Generate --> Refine[Refine for<br/>Testability]\n    Refine --> Rank[Rank by<br/>Quality Score]\n    Rank --> Output[Return Top<br/>Hypotheses]\n\n    Output --> Struct[Hypothesis Structure:<br/>\u2022 Statement<br/>\u2022 Rationale<br/>\u2022 Testability Score<br/>\u2022 Data Requirements<br/>\u2022 Expected Outcomes]\n\n    style Input fill:#e1f5e1\n    style Output fill:#fff4e6\n    style Struct fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#7-search-agent-workflow","title":"7. Search Agent Workflow","text":"
    flowchart TD\n    Input[Hypotheses] --> Strategy[Formulate Search<br/>Strategy per Hypothesis]\n\n    Strategy --> Multi[Multi-Source Search]\n\n    Multi --> PubMed[PubMed Search<br/>via MCP]\n    Multi --> ArXiv[arXiv Search<br/>via MCP]\n    Multi --> BioRxiv[bioRxiv Search<br/>via MCP]\n\n    PubMed --> Aggregate[Aggregate Results]\n    ArXiv --> Aggregate\n    BioRxiv --> Aggregate\n\n    Aggregate --> Filter[Filter & Rank<br/>by Relevance]\n    Filter --> Dedup[Deduplicate<br/>Cross-Reference]\n    Dedup --> Embed[Embed Documents<br/>via MCP]\n    Embed --> Vector[(Vector DB)]\n    Vector --> RAGRetrieval[RAG Retrieval<br/>Top-K per Hypothesis]\n    RAGRetrieval --> Output[Return Contextualized<br/>Search Results]\n\n    style Input fill:#fff4e6\n    style Multi fill:#ffe6e6\n    style Vector fill:#ffe6f0\n    style Output fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#8-analysis-agent-workflow","title":"8. Analysis Agent Workflow","text":"
    flowchart TD\n    Input1[Hypotheses] --> Extract\n    Input2[Search Results] --> Extract[Extract Evidence<br/>per Hypothesis]\n\n    Extract --> Methods[Determine Analysis<br/>Methods Needed]\n\n    Methods --> Branch{Requires<br/>Computation?}\n    Branch -->|Yes| GenCode[Generate Python<br/>Analysis Code]\n    Branch -->|No| Qual[Qualitative<br/>Synthesis]\n\n    GenCode --> Execute[Execute Code<br/>via MCP Sandbox]\n    Execute --> Interpret1[Interpret<br/>Results]\n    Qual --> Interpret2[Interpret<br/>Findings]\n\n    Interpret1 --> Synthesize[Synthesize Evidence<br/>Across Sources]\n    Interpret2 --> Synthesize\n\n    Synthesize --> Verdict[Determine Verdict<br/>per Hypothesis]\n    Verdict --> Support[\u2022 Supported<br/>\u2022 Refuted<br/>\u2022 Inconclusive]\n    Support --> Gaps[Identify Knowledge<br/>Gaps & Limitations]\n    Gaps --> Output[Return Analysis<br/>Report]\n\n    style Input1 fill:#fff4e6\n    style Input2 fill:#e6f3ff\n    style Execute fill:#ffe6e6\n    style Output fill:#e6ffe6
    "},{"location":"architecture/workflow-diagrams/#9-report-agent-workflow","title":"9. Report Agent Workflow","text":"
    flowchart TD\n    Input1[Query] --> Assemble\n    Input2[Hypotheses] --> Assemble\n    Input3[Search Results] --> Assemble\n    Input4[Analysis] --> Assemble[Assemble Report<br/>Sections]\n\n    Assemble --> Exec[Executive Summary]\n    Assemble --> Intro[Introduction]\n    Assemble --> Methods[Methods]\n    Assemble --> Results[Results per<br/>Hypothesis]\n    Assemble --> Discussion[Discussion]\n    Assemble --> Future[Future Directions]\n    Assemble --> Refs[References]\n\n    Results --> VizCheck{Needs<br/>Visualization?}\n    VizCheck -->|Yes| GenViz[Generate Viz Code]\n    GenViz --> ExecViz[Execute via MCP<br/>Create Charts]\n    ExecViz --> Combine\n    VizCheck -->|No| Combine[Combine All<br/>Sections]\n\n    Exec --> Combine\n    Intro --> Combine\n    Methods --> Combine\n    Discussion --> Combine\n    Future --> Combine\n    Refs --> Combine\n\n    Combine --> Format[Format Output]\n    Format --> MD[Markdown]\n    Format --> PDF[PDF]\n    Format --> JSON[JSON]\n\n    MD --> Output[Return Final<br/>Report]\n    PDF --> Output\n    JSON --> Output\n\n    style Input1 fill:#e1f5e1\n    style Input2 fill:#fff4e6\n    style Input3 fill:#e6f3ff\n    style Input4 fill:#e6ffe6\n    style Output fill:#d4edda
    "},{"location":"architecture/workflow-diagrams/#10-data-flow--event-streaming","title":"10. Data Flow & Event Streaming","text":"
    flowchart TD\n    User[\ud83d\udc64 User] -->|Research Query| UI[Gradio UI]\n    UI -->|Submit| Manager[Magentic Manager]\n\n    Manager -->|Event: Planning| UI\n    Manager -->|Select Agent| HypAgent[Hypothesis Agent]\n    HypAgent -->|Event: Delta/Message| UI\n    HypAgent -->|Hypotheses| Context[(Shared Context)]\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| SearchAgent[Search Agent]\n    SearchAgent -->|MCP Request| WebSearch[Web Search Tool]\n    WebSearch -->|Results| SearchAgent\n    SearchAgent -->|Event: Delta/Message| UI\n    SearchAgent -->|Documents| Context\n    SearchAgent -->|Embeddings| VectorDB[(Vector DB)]\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| AnalysisAgent[Analysis Agent]\n    AnalysisAgent -->|MCP Request| CodeExec[Code Execution Tool]\n    CodeExec -->|Results| AnalysisAgent\n    AnalysisAgent -->|Event: Delta/Message| UI\n    AnalysisAgent -->|Analysis| Context\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| ReportAgent[Report Agent]\n    ReportAgent -->|MCP Request| CodeExec\n    ReportAgent -->|Event: Delta/Message| UI\n    ReportAgent -->|Report| Context\n\n    Manager -->|Event: Final Result| UI\n    UI -->|Display| User\n\n    style User fill:#e1f5e1\n    style UI fill:#e6f3ff\n    style Manager fill:#ffe6e6\n    style Context fill:#ffe6f0\n    style VectorDB fill:#ffe6f0\n    style WebSearch fill:#f0f0f0\n    style CodeExec fill:#f0f0f0
    "},{"location":"architecture/workflow-diagrams/#11-mcp-tool-architecture","title":"11. MCP Tool Architecture","text":"
    graph TB\n    subgraph \"Agent Layer\"\n        Manager[Magentic Manager]\n        HypAgent[Hypothesis Agent]\n        SearchAgent[Search Agent]\n        AnalysisAgent[Analysis Agent]\n        ReportAgent[Report Agent]\n    end\n\n    subgraph \"MCP Protocol Layer\"\n        Registry[MCP Tool Registry<br/>\u2022 Discovers tools<br/>\u2022 Routes requests<br/>\u2022 Manages connections]\n    end\n\n    subgraph \"MCP Servers\"\n        Server1[Web Search Server<br/>localhost:8001<br/>\u2022 PubMed<br/>\u2022 arXiv<br/>\u2022 bioRxiv]\n        Server2[Code Execution Server<br/>localhost:8002<br/>\u2022 Sandboxed Python<br/>\u2022 Package management]\n        Server3[RAG Server<br/>localhost:8003<br/>\u2022 Vector embeddings<br/>\u2022 Similarity search]\n        Server4[Visualization Server<br/>localhost:8004<br/>\u2022 Chart generation<br/>\u2022 Plot rendering]\n    end\n\n    subgraph \"External Services\"\n        PubMed[PubMed API]\n        ArXiv[arXiv API]\n        BioRxiv[bioRxiv API]\n        Modal[Modal Sandbox]\n        ChromaDB[(ChromaDB)]\n    end\n\n    SearchAgent -->|Request| Registry\n    AnalysisAgent -->|Request| Registry\n    ReportAgent -->|Request| Registry\n\n    Registry --> Server1\n    Registry --> Server2\n    Registry --> Server3\n    Registry --> Server4\n\n    Server1 --> PubMed\n    Server1 --> ArXiv\n    Server1 --> BioRxiv\n    Server2 --> Modal\n    Server3 --> ChromaDB\n\n    style Manager fill:#ffe6e6\n    style Registry fill:#fff4e6\n    style Server1 fill:#e6f3ff\n    style Server2 fill:#e6f3ff\n    style Server3 fill:#e6f3ff\n    style Server4 fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#12-progress-tracking--stall-detection","title":"12. Progress Tracking & Stall Detection","text":"
    stateDiagram-v2\n    [*] --> Initialization: User Query\n\n    Initialization --> Planning: Manager starts\n\n    Planning --> AgentExecution: Select agent\n\n    AgentExecution --> Assessment: Collect results\n\n    Assessment --> QualityCheck: Evaluate output\n\n    QualityCheck --> AgentExecution: Poor quality<br/>(retry < max_rounds)\n    QualityCheck --> Planning: Poor quality<br/>(try different agent)\n    QualityCheck --> NextAgent: Good quality<br/>(task incomplete)\n    QualityCheck --> Synthesis: Good quality<br/>(task complete)\n\n    NextAgent --> AgentExecution: Select next agent\n\n    state StallDetection <<choice>>\n    Assessment --> StallDetection: Check progress\n    StallDetection --> Planning: No progress<br/>(stall count < max)\n    StallDetection --> ErrorRecovery: No progress<br/>(max stalls reached)\n\n    ErrorRecovery --> PartialReport: Generate partial results\n    PartialReport --> [*]\n\n    Synthesis --> FinalReport: Combine all outputs\n    FinalReport --> [*]\n\n    note right of QualityCheck\n        Manager assesses:\n        \u2022 Output completeness\n        \u2022 Quality metrics\n        \u2022 Progress made\n    end note\n\n    note right of StallDetection\n        Stall = no new progress\n        after agent execution\n        Triggers plan reset\n    end note
    "},{"location":"architecture/workflow-diagrams/#13-gradio-ui-integration","title":"13. Gradio UI Integration","text":"
    graph TD\n    App[Gradio App<br/>DeepCritical Research Agent]\n\n    App --> Input[Input Section]\n    App --> Status[Status Section]\n    App --> Output[Output Section]\n\n    Input --> Query[Research Question<br/>Text Area]\n    Input --> Controls[Controls]\n    Controls --> MaxHyp[Max Hypotheses: 1-10]\n    Controls --> MaxRounds[Max Rounds: 5-20]\n    Controls --> Submit[Start Research Button]\n\n    Status --> Log[Real-time Event Log<br/>\u2022 Manager planning<br/>\u2022 Agent selection<br/>\u2022 Execution updates<br/>\u2022 Quality assessment]\n    Status --> Progress[Progress Tracker<br/>\u2022 Current agent<br/>\u2022 Round count<br/>\u2022 Stall count]\n\n    Output --> Tabs[Tabbed Results]\n    Tabs --> Tab1[Hypotheses Tab<br/>Generated hypotheses with scores]\n    Tabs --> Tab2[Search Results Tab<br/>Papers & sources found]\n    Tabs --> Tab3[Analysis Tab<br/>Evidence & verdicts]\n    Tabs --> Tab4[Report Tab<br/>Final research report]\n    Tab4 --> Download[Download Report<br/>MD / PDF / JSON]\n\n    Submit -.->|Triggers| Workflow[Magentic Workflow]\n    Workflow -.->|MagenticOrchestratorMessageEvent| Log\n    Workflow -.->|MagenticAgentDeltaEvent| Log\n    Workflow -.->|MagenticAgentMessageEvent| Log\n    Workflow -.->|MagenticFinalResultEvent| Tab4\n\n    style App fill:#e1f5e1\n    style Input fill:#fff4e6\n    style Status fill:#e6f3ff\n    style Output fill:#e6ffe6\n    style Workflow fill:#ffe6e6
    "},{"location":"architecture/workflow-diagrams/#14-complete-system-context","title":"14. Complete System Context","text":"
    graph LR\n    User[\ud83d\udc64 Researcher<br/>Asks research questions] -->|Submits query| DC[DeepCritical<br/>Magentic Workflow]\n\n    DC -->|Literature search| PubMed[PubMed API<br/>Medical papers]\n    DC -->|Preprint search| ArXiv[arXiv API<br/>Scientific preprints]\n    DC -->|Biology search| BioRxiv[bioRxiv API<br/>Biology preprints]\n    DC -->|Agent reasoning| Claude[Claude API<br/>Sonnet 4 / Opus]\n    DC -->|Code execution| Modal[Modal Sandbox<br/>Safe Python env]\n    DC -->|Vector storage| Chroma[ChromaDB<br/>Embeddings & RAG]\n\n    DC -->|Deployed on| HF[HuggingFace Spaces<br/>Gradio 6.0]\n\n    PubMed -->|Results| DC\n    ArXiv -->|Results| DC\n    BioRxiv -->|Results| DC\n    Claude -->|Responses| DC\n    Modal -->|Output| DC\n    Chroma -->|Context| DC\n\n    DC -->|Research report| User\n\n    style User fill:#e1f5e1\n    style DC fill:#ffe6e6\n    style PubMed fill:#e6f3ff\n    style ArXiv fill:#e6f3ff\n    style BioRxiv fill:#e6f3ff\n    style Claude fill:#ffd6d6\n    style Modal fill:#f0f0f0\n    style Chroma fill:#ffe6f0\n    style HF fill:#d4edda
    "},{"location":"architecture/workflow-diagrams/#15-workflow-timeline-simplified","title":"15. Workflow Timeline (Simplified)","text":"
    gantt\n    title DeepCritical Magentic Workflow - Typical Execution\n    dateFormat mm:ss\n    axisFormat %M:%S\n\n    section Manager Planning\n    Initial planning         :p1, 00:00, 10s\n\n    section Hypothesis Agent\n    Generate hypotheses      :h1, after p1, 30s\n    Manager assessment       :h2, after h1, 5s\n\n    section Search Agent\n    Search hypothesis 1      :s1, after h2, 20s\n    Search hypothesis 2      :s2, after s1, 20s\n    Search hypothesis 3      :s3, after s2, 20s\n    RAG processing          :s4, after s3, 15s\n    Manager assessment      :s5, after s4, 5s\n\n    section Analysis Agent\n    Evidence extraction     :a1, after s5, 15s\n    Code generation        :a2, after a1, 20s\n    Code execution         :a3, after a2, 25s\n    Synthesis              :a4, after a3, 20s\n    Manager assessment     :a5, after a4, 5s\n\n    section Report Agent\n    Report assembly        :r1, after a5, 30s\n    Visualization          :r2, after r1, 15s\n    Formatting             :r3, after r2, 10s\n\n    section Manager Synthesis\n    Final synthesis        :f1, after r3, 10s
    "},{"location":"architecture/workflow-diagrams/#key-differences-from-original-design","title":"Key Differences from Original Design","text":"Aspect Original (Judge-in-Loop) New (Magentic) Control Flow Fixed sequential phases Dynamic agent selection Quality Control Separate Judge Agent Manager assessment built-in Retry Logic Phase-level with feedback Agent-level with adaptation Flexibility Rigid 4-phase pipeline Adaptive workflow Complexity 5 agents (including Judge) 4 agents (no Judge) Progress Tracking Manual state management Built-in round/stall detection Agent Coordination Sequential handoff Manager-driven dynamic selection Error Recovery Retry same phase Try different agent or replan"},{"location":"architecture/workflow-diagrams/#simplified-design-principles","title":"Simplified Design Principles","text":"
    1. Manager is Intelligent: LLM-powered manager handles planning, selection, and quality assessment
    2. No Separate Judge: Manager's assessment phase replaces dedicated Judge Agent
    3. Dynamic Workflow: Agents can be called multiple times in any order based on need
    4. Built-in Safety: max_round_count (15) and max_stall_count (3) prevent infinite loops
    5. Event-Driven UI: Real-time streaming updates to Gradio interface
    6. MCP-Powered Tools: All external capabilities via Model Context Protocol
    7. Shared Context: Centralized state accessible to all agents
    8. Progress Awareness: Manager tracks what's been done and what's needed
    "},{"location":"architecture/workflow-diagrams/#legend","title":"Legend","text":""},{"location":"architecture/workflow-diagrams/#implementation-highlights","title":"Implementation Highlights","text":"

    Simple 4-Agent Setup:

    Manager handles quality assessment in its instructions: - Checks hypothesis quality (testable, novel, clear) - Validates search results (relevant, authoritative, recent) - Assesses analysis soundness (methodology, evidence, conclusions) - Ensures report completeness (all sections, proper citations)

    No separate Judge Agent needed - manager does it all!

    Document Version: 2.0 (Magentic Simplified) Last Updated: 2025-11-24 Architecture: Microsoft Magentic Orchestration Pattern Agents: 4 (Hypothesis, Search, Analysis, Report) + 1 Manager License: MIT

    "},{"location":"architecture/workflow-diagrams/#see-also","title":"See Also","text":""},{"location":"configuration/","title":"Configuration Guide","text":""},{"location":"configuration/#overview","title":"Overview","text":"

    DeepCritical uses Pydantic Settings for centralized configuration management. All settings are defined in the Settings class in src/utils/config.py and can be configured via environment variables or a .env file.

    The configuration system provides:

    "},{"location":"configuration/#quick-start","title":"Quick Start","text":"
    1. Create a .env file in the project root
    2. Set at least one LLM API key (OPENAI_API_KEY, ANTHROPIC_API_KEY, or HF_TOKEN)
    3. Optionally configure other services as needed
    4. The application will automatically load and validate your configuration
    "},{"location":"configuration/#configuration-system-architecture","title":"Configuration System Architecture","text":""},{"location":"configuration/#settings-class","title":"Settings Class","text":"

    The [Settings][settings-class] class extends BaseSettings from pydantic_settings and defines all application configuration:

    View source

    "},{"location":"configuration/#singleton-instance","title":"Singleton Instance","text":"

    A global settings instance is available for import:

    View source

    "},{"location":"configuration/#usage-pattern","title":"Usage Pattern","text":"

    Access configuration throughout the codebase:

    from src.utils.config import settings\n\n# Check if API keys are available\nif settings.has_openai_key:\n    # Use OpenAI\n    pass\n\n# Access configuration values\nmax_iterations = settings.max_iterations\nweb_search_provider = settings.web_search_provider\n
    "},{"location":"configuration/#required-configuration","title":"Required Configuration","text":""},{"location":"configuration/#llm-provider","title":"LLM Provider","text":"

    You must configure at least one LLM provider. The system supports:

    "},{"location":"configuration/#openai-configuration","title":"OpenAI Configuration","text":"
    LLM_PROVIDER=openai\nOPENAI_API_KEY=your_openai_api_key_here\nOPENAI_MODEL=gpt-5.1\n

    The default model is defined in the Settings class:

    "},{"location":"configuration/#anthropic-configuration","title":"Anthropic Configuration","text":"
    LLM_PROVIDER=anthropic\nANTHROPIC_API_KEY=your_anthropic_api_key_here\nANTHROPIC_MODEL=claude-sonnet-4-5-20250929\n

    The default model is defined in the Settings class:

    "},{"location":"configuration/#huggingface-configuration","title":"HuggingFace Configuration","text":"

    HuggingFace can work without an API key for public models, but an API key provides higher rate limits:

    # Option 1: Using HF_TOKEN (preferred)\nHF_TOKEN=your_huggingface_token_here\n\n# Option 2: Using HUGGINGFACE_API_KEY (alternative)\nHUGGINGFACE_API_KEY=your_huggingface_api_key_here\n\n# Default model\nHUGGINGFACE_MODEL=meta-llama/Llama-3.1-8B-Instruct\n

    The HuggingFace token can be set via either environment variable:

    "},{"location":"configuration/#optional-configuration","title":"Optional Configuration","text":""},{"location":"configuration/#embedding-configuration","title":"Embedding Configuration","text":"

    DeepCritical supports multiple embedding providers for semantic search and RAG:

    # Embedding Provider: \"openai\", \"local\", or \"huggingface\"\nEMBEDDING_PROVIDER=local\n\n# OpenAI Embedding Model (used by LlamaIndex RAG)\nOPENAI_EMBEDDING_MODEL=text-embedding-3-small\n\n# Local Embedding Model (sentence-transformers, used by EmbeddingService)\nLOCAL_EMBEDDING_MODEL=all-MiniLM-L6-v2\n\n# HuggingFace Embedding Model\nHUGGINGFACE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2\n

    The embedding provider configuration:

    Note: OpenAI embeddings require OPENAI_API_KEY. The local provider (default) uses sentence-transformers and requires no API key.

    "},{"location":"configuration/#web-search-configuration","title":"Web Search Configuration","text":"

    DeepCritical supports multiple web search providers:

    # Web Search Provider: \"serper\", \"searchxng\", \"brave\", \"tavily\", or \"duckduckgo\"\n# Default: \"duckduckgo\" (no API key required)\nWEB_SEARCH_PROVIDER=duckduckgo\n\n# Serper API Key (for Google search via Serper)\nSERPER_API_KEY=your_serper_api_key_here\n\n# SearchXNG Host URL (for self-hosted search)\nSEARCHXNG_HOST=http://localhost:8080\n\n# Brave Search API Key\nBRAVE_API_KEY=your_brave_api_key_here\n\n# Tavily API Key\nTAVILY_API_KEY=your_tavily_api_key_here\n

    The web search provider configuration:

    Note: DuckDuckGo is the default and requires no API key, making it ideal for development and testing.

    "},{"location":"configuration/#pubmed-configuration","title":"PubMed Configuration","text":"

    PubMed search supports optional NCBI API key for higher rate limits:

    # NCBI API Key (optional, for higher rate limits: 10 req/sec vs 3 req/sec)\nNCBI_API_KEY=your_ncbi_api_key_here\n

    The PubMed tool uses this configuration:

    "},{"location":"configuration/#agent-configuration","title":"Agent Configuration","text":"

    Control agent behavior and research loop execution:

    # Maximum iterations per research loop (1-50, default: 10)\nMAX_ITERATIONS=10\n\n# Search timeout in seconds\nSEARCH_TIMEOUT=30\n\n# Use graph-based execution for research flows\nUSE_GRAPH_EXECUTION=false\n

    The agent configuration fields:

    "},{"location":"configuration/#budget--rate-limiting-configuration","title":"Budget & Rate Limiting Configuration","text":"

    Control resource limits for research loops:

    # Default token budget per research loop (1000-1000000, default: 100000)\nDEFAULT_TOKEN_LIMIT=100000\n\n# Default time limit per research loop in minutes (1-120, default: 10)\nDEFAULT_TIME_LIMIT_MINUTES=10\n\n# Default iterations limit per research loop (1-50, default: 10)\nDEFAULT_ITERATIONS_LIMIT=10\n

    The budget configuration with validation:

    "},{"location":"configuration/#rag-service-configuration","title":"RAG Service Configuration","text":"

    Configure the Retrieval-Augmented Generation service:

    # ChromaDB collection name for RAG\nRAG_COLLECTION_NAME=deepcritical_evidence\n\n# Number of top results to retrieve from RAG (1-50, default: 5)\nRAG_SIMILARITY_TOP_K=5\n\n# Automatically ingest evidence into RAG\nRAG_AUTO_INGEST=true\n

    The RAG configuration:

    "},{"location":"configuration/#chromadb-configuration","title":"ChromaDB Configuration","text":"

    Configure the vector database for embeddings and RAG:

    # ChromaDB storage path\nCHROMA_DB_PATH=./chroma_db\n\n# Whether to persist ChromaDB to disk\nCHROMA_DB_PERSIST=true\n\n# ChromaDB server host (for remote ChromaDB, optional)\nCHROMA_DB_HOST=localhost\n\n# ChromaDB server port (for remote ChromaDB, optional)\nCHROMA_DB_PORT=8000\n

    The ChromaDB configuration:

    "},{"location":"configuration/#external-services","title":"External Services","text":""},{"location":"configuration/#modal-configuration","title":"Modal Configuration","text":"

    Modal is used for secure sandbox execution of statistical analysis:

    # Modal Token ID (for Modal sandbox execution)\nMODAL_TOKEN_ID=your_modal_token_id_here\n\n# Modal Token Secret\nMODAL_TOKEN_SECRET=your_modal_token_secret_here\n

    The Modal configuration:

    "},{"location":"configuration/#logging-configuration","title":"Logging Configuration","text":"

    Configure structured logging:

    # Log Level: \"DEBUG\", \"INFO\", \"WARNING\", or \"ERROR\"\nLOG_LEVEL=INFO\n

    The logging configuration:

    Logging is configured via the configure_logging() function:

    "},{"location":"configuration/#configuration-properties","title":"Configuration Properties","text":"

    The Settings class provides helpful properties for checking configuration state:

    "},{"location":"configuration/#api-key-availability","title":"API Key Availability","text":"

    Check which API keys are available:

    Usage:

    from src.utils.config import settings\n\n# Check API key availability\nif settings.has_openai_key:\n    # Use OpenAI\n    pass\n\nif settings.has_anthropic_key:\n    # Use Anthropic\n    pass\n\nif settings.has_huggingface_key:\n    # Use HuggingFace\n    pass\n\nif settings.has_any_llm_key:\n    # At least one LLM is available\n    pass\n
    "},{"location":"configuration/#service-availability","title":"Service Availability","text":"

    Check if external services are configured:

    Usage:

    from src.utils.config import settings\n\n# Check service availability\nif settings.modal_available:\n    # Use Modal sandbox\n    pass\n\nif settings.web_search_available:\n    # Web search is configured\n    pass\n
    "},{"location":"configuration/#api-key-retrieval","title":"API Key Retrieval","text":"

    Get the API key for the configured provider:

    For OpenAI-specific operations (e.g., Magentic mode):

    "},{"location":"configuration/#configuration-usage-in-codebase","title":"Configuration Usage in Codebase","text":"

    The configuration system is used throughout the codebase:

    "},{"location":"configuration/#llm-factory","title":"LLM Factory","text":"

    The LLM factory uses settings to create appropriate models:

    "},{"location":"configuration/#embedding-service","title":"Embedding Service","text":"

    The embedding service uses local embedding model configuration:

    "},{"location":"configuration/#orchestrator-factory","title":"Orchestrator Factory","text":"

    The orchestrator factory uses settings to determine mode:

    "},{"location":"configuration/#environment-variables-reference","title":"Environment Variables Reference","text":""},{"location":"configuration/#required-at-least-one-llm","title":"Required (at least one LLM)","text":""},{"location":"configuration/#llm-configuration-variables","title":"LLM Configuration Variables","text":""},{"location":"configuration/#embedding-configuration-variables","title":"Embedding Configuration Variables","text":""},{"location":"configuration/#web-search-configuration-variables","title":"Web Search Configuration Variables","text":""},{"location":"configuration/#pubmed-configuration-variables","title":"PubMed Configuration Variables","text":""},{"location":"configuration/#agent-configuration-variables","title":"Agent Configuration Variables","text":""},{"location":"configuration/#budget-configuration-variables","title":"Budget Configuration Variables","text":""},{"location":"configuration/#rag-configuration-variables","title":"RAG Configuration Variables","text":""},{"location":"configuration/#chromadb-configuration-variables","title":"ChromaDB Configuration Variables","text":""},{"location":"configuration/#external-services-variables","title":"External Services Variables","text":""},{"location":"configuration/#logging-configuration-variables","title":"Logging Configuration Variables","text":""},{"location":"configuration/#validation","title":"Validation","text":"

    Settings are validated on load using Pydantic validation:

    "},{"location":"configuration/#validation-examples","title":"Validation Examples","text":"

    The max_iterations field has range validation:

    The llm_provider field has literal validation:

    "},{"location":"configuration/#error-handling","title":"Error Handling","text":"

    Configuration errors raise ConfigurationError from src/utils/exceptions.py:

    ```22:25:src/utils/exceptions.py class ConfigurationError(DeepCriticalError): \"\"\"Raised when configuration is invalid.\"\"\"

    pass\n

    ```

    "},{"location":"configuration/#error-handling-example","title":"Error Handling Example","text":"

    python from src.utils.config import settings from src.utils.exceptions import ConfigurationError try: api_key = settings.get_api_key() except ConfigurationError as e: print(f\"Configuration error: {e}\")

    "},{"location":"configuration/#common-configuration-errors","title":"Common Configuration Errors","text":"
    1. Missing API Key: When get_api_key() is called but the required API key is not set
    2. Invalid Provider: When llm_provider is set to an unsupported value
    3. Out of Range: When numeric values exceed their min/max constraints
    4. Invalid Literal: When enum fields receive unsupported values
    "},{"location":"configuration/#configuration-best-practices","title":"Configuration Best Practices","text":"
    1. Use .env File: Store sensitive keys in .env file (add to .gitignore)
    2. Check Availability: Use properties like has_openai_key before accessing API keys
    3. Handle Errors: Always catch ConfigurationError when calling get_api_key()
    4. Validate Early: Configuration is validated on import, so errors surface immediately
    5. Use Defaults: Leverage sensible defaults for optional configuration
    "},{"location":"configuration/#future-enhancements","title":"Future Enhancements","text":"

    The following configurations are planned for future phases:

    1. Additional LLM Providers: DeepSeek, OpenRouter, Gemini, Perplexity, Azure OpenAI, Local models
    2. Model Selection: Reasoning/main/fast model configuration
    3. Service Integration: Additional service integrations and configurations
    "},{"location":"contributing/","title":"Contributing to The DETERMINATOR","text":"

    Thank you for your interest in contributing to The DETERMINATOR! This guide will help you get started.

    Note on Project Names: \"The DETERMINATOR\" is the product name, \"DeepCritical\" is the organization/project name, and \"determinator\" is the Python package name.

    "},{"location":"contributing/#git-workflow","title":"Git Workflow","text":""},{"location":"contributing/#repository-information","title":"Repository Information","text":""},{"location":"contributing/#dual-repository-setup","title":"Dual Repository Setup","text":"

    This project uses a dual repository setup:

    "},{"location":"contributing/#remote-configuration","title":"Remote Configuration","text":"

    When cloning, set up remotes as follows:

    # Clone from GitHub\ngit clone https://github.com/DeepCritical/GradioDemo.git\ncd GradioDemo\n\n# Add HuggingFace remote (optional, for deployment)\ngit remote add huggingface-upstream https://huggingface.co/spaces/DataQuests/DeepCritical\n

    Important: Never push directly to main or dev on HuggingFace. Always work through GitHub PRs. GitHub is the source of truth; HuggingFace is for deployment/demo only.

    "},{"location":"contributing/#package-manager","title":"Package Manager","text":"

    This project uses uv as the package manager. All commands should be prefixed with uv run to ensure they run in the correct environment.

    "},{"location":"contributing/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync all dependencies including dev extras\nuv sync --all-extras\n\n# Install pre-commit hooks\nuv run pre-commit install\n
    "},{"location":"contributing/#development-commands","title":"Development Commands","text":"
    # Installation\nuv sync --all-extras              # Install all dependencies including dev\nuv run pre-commit install          # Install pre-commit hooks\n\n# Code Quality Checks (run all before committing)\nuv run ruff check src tests       # Lint with ruff\nuv run ruff format src tests      # Format with ruff\nuv run mypy src                   # Type checking\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire  # Tests with coverage\n\n# Testing Commands\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire              # Run unit tests (excludes OpenAI tests)\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire                 # Run HuggingFace tests\nuv run pytest tests/ -v -p no:logfire                                  # Run all tests\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire  # Tests with terminal coverage\nuv run pytest --cov=src --cov-report=html -p no:logfire                # Generate HTML coverage report (opens htmlcov/index.html)\n\n# Documentation Commands\nuv run mkdocs build                # Build documentation\nuv run mkdocs serve                # Serve documentation locally (http://127.0.0.1:8000)\n
    "},{"location":"contributing/#test-markers","title":"Test Markers","text":"

    The project uses pytest markers to categorize tests. See Testing Guidelines for details:

    Note: The -p no:logfire flag disables the logfire plugin to avoid conflicts during testing.

    "},{"location":"contributing/#getting-started","title":"Getting Started","text":"
    1. Fork the repository on GitHub: DeepCritical/GradioDemo

    2. Clone your fork:

    git clone https://github.com/yourusername/GradioDemo.git\ncd GradioDemo\n
    1. Install dependencies:
    uv sync --all-extras\nuv run pre-commit install\n
    1. Create a feature branch:
    git checkout -b yourname-feature-name\n
    1. Make your changes following the guidelines below

    2. Run checks:

    uv run ruff check src tests\nuv run mypy src\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire\n
    1. Commit and push:
    git commit -m \"Description of changes\"\ngit push origin yourname-feature-name\n
    1. Create a pull request on GitHub
    "},{"location":"contributing/#development-guidelines","title":"Development Guidelines","text":""},{"location":"contributing/#code-style","title":"Code Style","text":""},{"location":"contributing/#error-handling","title":"Error Handling","text":""},{"location":"contributing/#testing","title":"Testing","text":""},{"location":"contributing/#implementation-patterns","title":"Implementation Patterns","text":""},{"location":"contributing/#prompt-engineering","title":"Prompt Engineering","text":""},{"location":"contributing/#code-quality","title":"Code Quality","text":""},{"location":"contributing/#mcp-integration","title":"MCP Integration","text":""},{"location":"contributing/#mcp-tools","title":"MCP Tools","text":""},{"location":"contributing/#gradio-mcp-server","title":"Gradio MCP Server","text":""},{"location":"contributing/#common-pitfalls","title":"Common Pitfalls","text":"
    1. Blocking the event loop: Never use sync I/O in async functions
    2. Missing type hints: All functions must have complete type annotations
    3. Hallucinated citations: Always validate references
    4. Global mutable state: Use ContextVar or pass via parameters
    5. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
    6. Rate limiting: Always implement for external APIs
    7. Error chaining: Always use from e when raising exceptions
    "},{"location":"contributing/#key-principles","title":"Key Principles","text":"
    1. Type Safety First: All code must pass mypy --strict
    2. Async Everything: All I/O must be async
    3. Test-Driven: Write tests before implementation
    4. No Hallucinations: Validate all citations
    5. Graceful Degradation: Support free tier (HF Inference) when no API keys
    6. Lazy Loading: Don't require optional dependencies at import time
    7. Structured Logging: Use structlog, never print()
    8. Error Chaining: Always preserve exception context
    "},{"location":"contributing/#pull-request-process","title":"Pull Request Process","text":"
    1. Ensure all checks pass: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire
    2. Update documentation if needed
    3. Add tests for new features
    4. Update CHANGELOG if applicable
    5. Request review from maintainers
    6. Address review feedback
    7. Wait for approval before merging
    "},{"location":"contributing/#project-structure","title":"Project Structure","text":""},{"location":"contributing/#questions","title":"Questions?","text":"

    Thank you for contributing to The DETERMINATOR!

    "},{"location":"contributing/code-quality/","title":"Code Quality & Documentation","text":"

    This document outlines code quality standards and documentation requirements for The DETERMINATOR.

    "},{"location":"contributing/code-quality/#linting","title":"Linting","text":""},{"location":"contributing/code-quality/#type-checking","title":"Type Checking","text":""},{"location":"contributing/code-quality/#pre-commit","title":"Pre-commit","text":"

    Pre-commit hooks run automatically on commit to ensure code quality. Configuration is in .pre-commit-config.yaml.

    "},{"location":"contributing/code-quality/#installation","title":"Installation","text":"
    # Install dependencies (includes pre-commit package)\nuv sync --all-extras\n\n# Set up git hooks (must be run separately)\nuv run pre-commit install\n

    Note: uv sync --all-extras installs the pre-commit package, but you must run uv run pre-commit install separately to set up the git hooks.

    "},{"location":"contributing/code-quality/#pre-commit-hooks","title":"Pre-commit Hooks","text":"

    The following hooks run automatically on commit:

    1. ruff: Lints code and fixes issues automatically
    2. Runs on: src/ (excludes tests/, reference_repos/)
    3. Auto-fixes: Yes

    4. ruff-format: Formats code with ruff

    5. Runs on: src/ (excludes tests/, reference_repos/)
    6. Auto-fixes: Yes

    7. mypy: Type checking

    8. Runs on: src/ (excludes folder/)
    9. Additional dependencies: pydantic, pydantic-settings, tenacity, pydantic-ai

    10. pytest-unit: Runs unit tests (excludes OpenAI and embedding_provider tests)

    11. Runs: tests/unit/ with -m \"not openai and not embedding_provider\"
    12. Always runs: Yes (not just on changed files)

    13. pytest-local-embeddings: Runs local embedding tests

    14. Runs: tests/ with -m \"local_embeddings\"
    15. Always runs: Yes
    "},{"location":"contributing/code-quality/#manual-pre-commit-run","title":"Manual Pre-commit Run","text":"

    To run pre-commit hooks manually (without committing):

    uv run pre-commit run --all-files\n
    "},{"location":"contributing/code-quality/#troubleshooting","title":"Troubleshooting","text":""},{"location":"contributing/code-quality/#documentation","title":"Documentation","text":""},{"location":"contributing/code-quality/#building-documentation","title":"Building Documentation","text":"

    Documentation is built using MkDocs. Source files are in docs/, and the configuration is in mkdocs.yml.

    # Build documentation\nuv run mkdocs build\n\n# Serve documentation locally (http://127.0.0.1:8000)\nuv run mkdocs serve\n

    The documentation site is published at: https://deepcritical.github.io/GradioDemo/

    "},{"location":"contributing/code-quality/#docstrings","title":"Docstrings","text":"

    Example:

    "},{"location":"contributing/code-quality/#code-comments","title":"Code Comments","text":""},{"location":"contributing/code-quality/#see-also","title":"See Also","text":""},{"location":"contributing/code-style/","title":"Code Style & Conventions","text":"

    This document outlines the code style and conventions for The DETERMINATOR.

    "},{"location":"contributing/code-style/#package-manager","title":"Package Manager","text":"

    This project uses uv as the package manager. All commands should be prefixed with uv run to ensure they run in the correct environment.

    "},{"location":"contributing/code-style/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync all dependencies including dev extras\nuv sync --all-extras\n
    "},{"location":"contributing/code-style/#running-commands","title":"Running Commands","text":"

    All development commands should use uv run prefix:

    # Instead of: pytest tests/\nuv run pytest tests/\n\n# Instead of: ruff check src\nuv run ruff check src\n\n# Instead of: mypy src\nuv run mypy src\n

    This ensures commands run in the correct virtual environment managed by uv.

    "},{"location":"contributing/code-style/#type-safety","title":"Type Safety","text":""},{"location":"contributing/code-style/#pydantic-models","title":"Pydantic Models","text":""},{"location":"contributing/code-style/#async-patterns","title":"Async Patterns","text":"
    loop = asyncio.get_running_loop()\nresult = await loop.run_in_executor(None, cpu_bound_function, args)\n
    "},{"location":"contributing/code-style/#common-pitfalls","title":"Common Pitfalls","text":"
    1. Blocking the event loop: Never use sync I/O in async functions
    2. Missing type hints: All functions must have complete type annotations
    3. Global mutable state: Use ContextVar or pass via parameters
    4. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
    "},{"location":"contributing/code-style/#see-also","title":"See Also","text":""},{"location":"contributing/error-handling/","title":"Error Handling & Logging","text":"

    This document outlines error handling and logging conventions for The DETERMINATOR.

    "},{"location":"contributing/error-handling/#exception-hierarchy","title":"Exception Hierarchy","text":"

    Use custom exception hierarchy (src/utils/exceptions.py):

    "},{"location":"contributing/error-handling/#error-handling-rules","title":"Error Handling Rules","text":"
    logger.error(\"Operation failed\", error=str(e), context=value)\n
    "},{"location":"contributing/error-handling/#logging","title":"Logging","text":""},{"location":"contributing/error-handling/#logging-examples","title":"Logging Examples","text":"
    logger.info(\"Starting search\", query=query, tools=[t.name for t in tools])\nlogger.warning(\"Search tool failed\", tool=tool.name, error=str(result))\nlogger.error(\"Assessment failed\", error=str(e))\n
    "},{"location":"contributing/error-handling/#error-chaining","title":"Error Chaining","text":"

    Always preserve exception context:

    try:\n    result = await api_call()\nexcept httpx.HTTPError as e:\n    raise SearchError(f\"API call failed: {e}\") from e\n
    "},{"location":"contributing/error-handling/#see-also","title":"See Also","text":""},{"location":"contributing/implementation-patterns/","title":"Implementation Patterns","text":"

    This document outlines common implementation patterns used in The DETERMINATOR.

    "},{"location":"contributing/implementation-patterns/#search-tools","title":"Search Tools","text":"

    All tools implement SearchTool protocol (src/tools/base.py):

    Example pattern:

    class MySearchTool:\n    @property\n    def name(self) -> str:\n        return \"mytool\"\n    \n    @retry(stop=stop_after_attempt(3), wait=wait_exponential(...))\n    async def search(self, query: str, max_results: int = 10) -> list[Evidence]:\n        # Implementation\n        return evidence_list\n
    "},{"location":"contributing/implementation-patterns/#judge-handlers","title":"Judge Handlers","text":""},{"location":"contributing/implementation-patterns/#agent-factory-pattern","title":"Agent Factory Pattern","text":""},{"location":"contributing/implementation-patterns/#state-management","title":"State Management","text":""},{"location":"contributing/implementation-patterns/#singleton-pattern","title":"Singleton Pattern","text":"

    Use @lru_cache(maxsize=1) for singletons:

    "},{"location":"contributing/implementation-patterns/#see-also","title":"See Also","text":""},{"location":"contributing/prompt-engineering/","title":"Prompt Engineering & Citation Validation","text":"

    This document outlines prompt engineering guidelines and citation validation rules.

    "},{"location":"contributing/prompt-engineering/#judge-prompts","title":"Judge Prompts","text":""},{"location":"contributing/prompt-engineering/#hypothesis-prompts","title":"Hypothesis Prompts","text":""},{"location":"contributing/prompt-engineering/#report-prompts","title":"Report Prompts","text":""},{"location":"contributing/prompt-engineering/#citation-validation","title":"Citation Validation","text":""},{"location":"contributing/prompt-engineering/#citation-validation-rules","title":"Citation Validation Rules","text":"
    1. Every reference URL must EXACTLY match a provided evidence URL
    2. Do NOT invent, fabricate, or hallucinate any references
    3. Do NOT modify paper titles, authors, dates, or URLs
    4. If unsure about a citation, OMIT it rather than guess
    5. Copy URLs exactly as provided - do not create similar-looking URLs
    "},{"location":"contributing/prompt-engineering/#evidence-selection","title":"Evidence Selection","text":""},{"location":"contributing/prompt-engineering/#see-also","title":"See Also","text":""},{"location":"contributing/testing/","title":"Testing Requirements","text":"

    This document outlines testing requirements and guidelines for The DETERMINATOR.

    "},{"location":"contributing/testing/#test-structure","title":"Test Structure","text":""},{"location":"contributing/testing/#test-markers","title":"Test Markers","text":"

    The project uses pytest markers to categorize tests. These markers are defined in pyproject.toml:

    "},{"location":"contributing/testing/#running-tests-by-marker","title":"Running Tests by Marker","text":"
    # Run only unit tests (excludes OpenAI tests by default)\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire\n\n# Run HuggingFace tests\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire\n\n# Run all tests\nuv run pytest tests/ -v -p no:logfire\n\n# Run only local embedding tests\nuv run pytest tests/ -v -m \"local_embeddings\" -p no:logfire\n\n# Exclude slow tests\nuv run pytest tests/ -v -m \"not slow\" -p no:logfire\n

    Note: The -p no:logfire flag disables the logfire plugin to avoid conflicts during testing.

    "},{"location":"contributing/testing/#mocking","title":"Mocking","text":""},{"location":"contributing/testing/#tdd-workflow","title":"TDD Workflow","text":"
    1. Write failing test in tests/unit/
    2. Implement in src/
    3. Ensure test passes
    4. Run checks: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire
    "},{"location":"contributing/testing/#test-command-examples","title":"Test Command Examples","text":"
    # Run unit tests (default, excludes OpenAI tests)\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire\n\n# Run HuggingFace tests\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire\n\n# Run all tests\nuv run pytest tests/ -v -p no:logfire\n
    "},{"location":"contributing/testing/#test-examples","title":"Test Examples","text":"
    @pytest.mark.unit\nasync def test_pubmed_search(mock_httpx_client):\n    tool = PubMedTool()\n    results = await tool.search(\"metformin\", max_results=5)\n    assert len(results) > 0\n    assert all(isinstance(r, Evidence) for r in results)\n\n@pytest.mark.integration\nasync def test_real_pubmed_search():\n    tool = PubMedTool()\n    results = await tool.search(\"metformin\", max_results=3)\n    assert len(results) <= 3\n
    "},{"location":"contributing/testing/#test-coverage","title":"Test Coverage","text":""},{"location":"contributing/testing/#terminal-coverage-report","title":"Terminal Coverage Report","text":"
    uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire\n

    This shows coverage with missing lines highlighted in the terminal output.

    "},{"location":"contributing/testing/#html-coverage-report","title":"HTML Coverage Report","text":"
    uv run pytest --cov=src --cov-report=html -p no:logfire\n

    This generates an HTML coverage report in htmlcov/index.html. Open this file in your browser to see detailed coverage information.

    "},{"location":"contributing/testing/#coverage-goals","title":"Coverage Goals","text":""},{"location":"contributing/testing/#see-also","title":"See Also","text":""},{"location":"getting-started/examples/","title":"Examples","text":"

    This page provides examples of using The DETERMINATOR for various research tasks.

    "},{"location":"getting-started/examples/#basic-research-query","title":"Basic Research Query","text":""},{"location":"getting-started/examples/#example-1-drug-information","title":"Example 1: Drug Information","text":"

    Query:

    What are the latest treatments for Alzheimer's disease?\n

    What The DETERMINATOR Does: 1. Searches PubMed for recent papers 2. Searches ClinicalTrials.gov for active trials 3. Evaluates evidence quality 4. Synthesizes findings into a comprehensive report

    "},{"location":"getting-started/examples/#example-2-clinical-trial-search","title":"Example 2: Clinical Trial Search","text":"

    Query:

    What clinical trials are investigating metformin for cancer prevention?\n

    What The DETERMINATOR Does:

    1. Searches ClinicalTrials.gov for relevant trials
    2. Searches PubMed for supporting literature
    3. Provides trial details and status
    4. Summarizes findings
    "},{"location":"getting-started/examples/#advanced-research-queries","title":"Advanced Research Queries","text":""},{"location":"getting-started/examples/#example-3-comprehensive-review","title":"Example 3: Comprehensive Review","text":"

    Query:

    Review the evidence for using metformin as an anti-aging intervention, \nincluding clinical trials, mechanisms of action, and safety profile.\n

    What The DETERMINATOR Does: 1. Uses deep research mode (multi-section) 2. Searches multiple sources in parallel 3. Generates sections on: - Clinical trials - Mechanisms of action - Safety profile 4. Synthesizes comprehensive report

    "},{"location":"getting-started/examples/#example-4-hypothesis-testing","title":"Example 4: Hypothesis Testing","text":"

    Query:

    Test the hypothesis that regular exercise reduces Alzheimer's disease risk.\n

    What The DETERMINATOR Does: 1. Generates testable hypotheses 2. Searches for supporting/contradicting evidence 3. Performs statistical analysis (if Modal configured) 4. Provides verdict: SUPPORTED, REFUTED, or INCONCLUSIVE

    "},{"location":"getting-started/examples/#mcp-tool-examples","title":"MCP Tool Examples","text":""},{"location":"getting-started/examples/#using-search_pubmed","title":"Using search_pubmed","text":"
    Search PubMed for \"CRISPR gene editing cancer therapy\"\n
    "},{"location":"getting-started/examples/#using-search_clinical_trials","title":"Using search_clinical_trials","text":"
    Find active clinical trials for \"diabetes type 2 treatment\"\n
    "},{"location":"getting-started/examples/#using-search_all","title":"Using search_all","text":"
    Search all sources for \"COVID-19 vaccine side effects\"\n
    "},{"location":"getting-started/examples/#using-analyze_hypothesis","title":"Using analyze_hypothesis","text":"
    Analyze whether vitamin D supplementation reduces COVID-19 severity\n
    "},{"location":"getting-started/examples/#code-examples","title":"Code Examples","text":""},{"location":"getting-started/examples/#python-api-usage","title":"Python API Usage","text":"
    from src.orchestrator_factory import create_orchestrator\nfrom src.tools.search_handler import SearchHandler\nfrom src.agent_factory.judges import create_judge_handler\n\n# Create orchestrator\nsearch_handler = SearchHandler()\njudge_handler = create_judge_handler()\n
    # Run research query\nquery = \"What are the latest treatments for Alzheimer's disease?\"\nasync for event in orchestrator.run(query):\n    print(f\"Event: {event.type} - {event.data}\")\n
    "},{"location":"getting-started/examples/#gradio-ui-integration","title":"Gradio UI Integration","text":"
    import gradio as gr\nfrom src.app import create_research_interface\n\n# Create interface\ninterface = create_research_interface()\n\n# Launch\ninterface.launch(server_name=\"0.0.0.0\", server_port=7860)\n
    "},{"location":"getting-started/examples/#research-patterns","title":"Research Patterns","text":""},{"location":"getting-started/examples/#iterative-research","title":"Iterative Research","text":"

    Single-loop research with search-judge-synthesize cycles:

    from src.orchestrator.research_flow import IterativeResearchFlow\n
    async for event in flow.run(query):\n    # Handle events\n    pass\n
    "},{"location":"getting-started/examples/#deep-research","title":"Deep Research","text":"

    Multi-section parallel research:

    from src.orchestrator.research_flow import DeepResearchFlow\n
    async for event in flow.run(query):\n    # Handle events\n    pass\n
    "},{"location":"getting-started/examples/#configuration-examples","title":"Configuration Examples","text":""},{"location":"getting-started/examples/#basic-configuration","title":"Basic Configuration","text":"
    # .env file\nLLM_PROVIDER=openai\nOPENAI_API_KEY=your_key_here\nMAX_ITERATIONS=10\n
    "},{"location":"getting-started/examples/#advanced-configuration","title":"Advanced Configuration","text":"
    # .env file\nLLM_PROVIDER=anthropic\nANTHROPIC_API_KEY=your_key_here\nEMBEDDING_PROVIDER=local\nWEB_SEARCH_PROVIDER=duckduckgo\nMAX_ITERATIONS=20\nDEFAULT_TOKEN_LIMIT=200000\nUSE_GRAPH_EXECUTION=true\n
    "},{"location":"getting-started/examples/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/installation/","title":"Installation","text":"

    This guide will help you install and set up DeepCritical on your system.

    "},{"location":"getting-started/installation/#prerequisites","title":"Prerequisites","text":""},{"location":"getting-started/installation/#installation-steps","title":"Installation Steps","text":""},{"location":"getting-started/installation/#1-install-uv-recommended","title":"1. Install uv (Recommended)","text":"

    uv is a fast Python package installer and resolver. Install it using the standalone installer (recommended):

    Unix/macOS/Linux:

    curl -LsSf https://astral.sh/uv/install.sh | sh\n

    Windows (PowerShell):

    powershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n

    Alternative methods:

    # Using pipx (recommended if you have pipx installed)\npipx install uv\n\n# Or using pip\npip install uv\n

    After installation, restart your terminal or add ~/.cargo/bin to your PATH.

    "},{"location":"getting-started/installation/#2-clone-the-repository","title":"2. Clone the Repository","text":"
    git clone https://github.com/DeepCritical/GradioDemo.git\ncd GradioDemo\n
    "},{"location":"getting-started/installation/#3-install-dependencies","title":"3. Install Dependencies","text":"

    Using uv (recommended):

    uv sync\n

    Using pip:

    pip install -e .\n
    "},{"location":"getting-started/installation/#4-install-optional-dependencies","title":"4. Install Optional Dependencies","text":"

    For embeddings support (local sentence-transformers):

    uv sync --extra embeddings\n

    For Modal sandbox execution:

    uv sync --extra modal\n

    For Magentic orchestration:

    uv sync --extra magentic\n

    Install all extras:

    uv sync --all-extras\n
    "},{"location":"getting-started/installation/#5-configure-environment-variables","title":"5. Configure Environment Variables","text":"

    Create a .env file in the project root:

    # Required: At least one LLM provider\nLLM_PROVIDER=openai  # or \"anthropic\" or \"huggingface\"\nOPENAI_API_KEY=your_openai_api_key_here\n\n# Optional: Other services\nNCBI_API_KEY=your_ncbi_api_key_here  # For higher PubMed rate limits\nMODAL_TOKEN_ID=your_modal_token_id\nMODAL_TOKEN_SECRET=your_modal_token_secret\n

    See the Configuration Guide for all available options.

    "},{"location":"getting-started/installation/#6-verify-installation","title":"6. Verify Installation","text":"

    Run the application:

    uv run gradio run src/app.py\n

    Open your browser to http://localhost:7860 to verify the installation.

    "},{"location":"getting-started/installation/#development-setup","title":"Development Setup","text":"

    For development, install dev dependencies:

    uv sync --all-extras --dev\n

    Install pre-commit hooks:

    uv run pre-commit install\n
    "},{"location":"getting-started/installation/#troubleshooting","title":"Troubleshooting","text":""},{"location":"getting-started/installation/#common-issues","title":"Common Issues","text":"

    Import Errors: - Ensure you've installed all required dependencies - Check that Python 3.11+ is being used

    API Key Errors: - Verify your .env file is in the project root - Check that API keys are correctly formatted - Ensure at least one LLM provider is configured

    Module Not Found: - Run uv sync or pip install -e . again - Check that you're in the correct virtual environment

    Port Already in Use: - Change the port in src/app.py or use environment variable - Kill the process using port 7860

    "},{"location":"getting-started/installation/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/mcp-integration/","title":"MCP Integration","text":"

    The DETERMINATOR exposes a Model Context Protocol (MCP) server, allowing you to use its search tools directly from Claude Desktop or other MCP clients.

    "},{"location":"getting-started/mcp-integration/#what-is-mcp","title":"What is MCP?","text":"

    The Model Context Protocol (MCP) is a standard for connecting AI assistants to external tools and data sources. The DETERMINATOR implements an MCP server that exposes its search capabilities as MCP tools.

    "},{"location":"getting-started/mcp-integration/#mcp-server-url","title":"MCP Server URL","text":"

    When running locally:

    http://localhost:7860/gradio_api/mcp/\n
    "},{"location":"getting-started/mcp-integration/#claude-desktop-configuration","title":"Claude Desktop Configuration","text":""},{"location":"getting-started/mcp-integration/#1-locate-configuration-file","title":"1. Locate Configuration File","text":"

    macOS:

    ~/Library/Application Support/Claude/claude_desktop_config.json\n

    Windows:

    %APPDATA%\\Claude\\claude_desktop_config.json\n

    Linux:

    ~/.config/Claude/claude_desktop_config.json\n

    "},{"location":"getting-started/mcp-integration/#2-add-the-determinator-server","title":"2. Add The DETERMINATOR Server","text":"

    Edit claude_desktop_config.json and add:

    {\n  \"mcpServers\": {\n    \"determinator\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#3-restart-claude-desktop","title":"3. Restart Claude Desktop","text":"

    Close and restart Claude Desktop for changes to take effect.

    "},{"location":"getting-started/mcp-integration/#4-verify-connection","title":"4. Verify Connection","text":"

    In Claude Desktop, you should see The DETERMINATOR tools available: - search_pubmed - search_clinical_trials - search_biorxiv - search_all - analyze_hypothesis

    "},{"location":"getting-started/mcp-integration/#available-tools","title":"Available Tools","text":""},{"location":"getting-started/mcp-integration/#search_pubmed","title":"search_pubmed","text":"

    Search peer-reviewed biomedical literature from PubMed.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search PubMed for \"metformin diabetes\"\n

    "},{"location":"getting-started/mcp-integration/#search_clinical_trials","title":"search_clinical_trials","text":"

    Search ClinicalTrials.gov for interventional studies.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search clinical trials for \"Alzheimer's disease treatment\"\n

    "},{"location":"getting-started/mcp-integration/#search_biorxiv","title":"search_biorxiv","text":"

    Search bioRxiv/medRxiv preprints via Europe PMC.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search bioRxiv for \"CRISPR gene editing\"\n

    "},{"location":"getting-started/mcp-integration/#search_all","title":"search_all","text":"

    Search all sources simultaneously (PubMed, ClinicalTrials.gov, Europe PMC).

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results per source (default: 10)

    Example:

    Search all sources for \"COVID-19 vaccine efficacy\"\n

    "},{"location":"getting-started/mcp-integration/#analyze_hypothesis","title":"analyze_hypothesis","text":"

    Perform secure statistical analysis using Modal sandboxes.

    Parameters: - hypothesis (string): Hypothesis to analyze - data (string, optional): Data description or code

    Example:

    Analyze the hypothesis that metformin reduces cancer risk\n

    "},{"location":"getting-started/mcp-integration/#using-tools-in-claude-desktop","title":"Using Tools in Claude Desktop","text":"

    Once configured, you can ask Claude to use DeepCritical tools:

    Use DeepCritical to search PubMed for recent papers on Alzheimer's disease treatments.\n

    Claude will automatically: 1. Call the appropriate DeepCritical tool 2. Retrieve results 3. Use the results in its response

    "},{"location":"getting-started/mcp-integration/#troubleshooting","title":"Troubleshooting","text":""},{"location":"getting-started/mcp-integration/#connection-issues","title":"Connection Issues","text":"

    Server Not Found: - Ensure DeepCritical is running (uv run gradio run src/app.py) - Verify the URL in claude_desktop_config.json is correct - Check that port 7860 is not blocked by firewall

    Tools Not Appearing: - Restart Claude Desktop after configuration changes - Check Claude Desktop logs for errors - Verify MCP server is accessible at the configured URL

    "},{"location":"getting-started/mcp-integration/#authentication","title":"Authentication","text":"

    If DeepCritical requires authentication: - Configure API keys in DeepCritical settings - Use HuggingFace OAuth login - Ensure API keys are valid

    "},{"location":"getting-started/mcp-integration/#advanced-configuration","title":"Advanced Configuration","text":""},{"location":"getting-started/mcp-integration/#custom-port","title":"Custom Port","text":"

    If running on a different port, update the URL:

    {\n  \"mcpServers\": {\n    \"deepcritical\": {\n      \"url\": \"http://localhost:8080/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#multiple-instances","title":"Multiple Instances","text":"

    You can configure multiple DeepCritical instances:

    {\n  \"mcpServers\": {\n    \"deepcritical-local\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    },\n    \"deepcritical-remote\": {\n      \"url\": \"https://your-server.com/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/quick-start/","title":"Single Command Deploy","text":"

    Deploy with docker instandly with a single command :

    docker run -it -p 7860:7860 --platform=linux/amd64 \\\n    -e DB_KEY=\"YOUR_VALUE_HERE\" \\\n    -e SERP_API=\"YOUR_VALUE_HERE\" \\\n    -e INFERENCE_API=\"YOUR_VALUE_HERE\" \\\n    -e MODAL_TOKEN_ID=\"YOUR_VALUE_HERE\" \\\n    -e MODAL_TOKEN_SECRET=\"YOUR_VALUE_HERE\" \\\n    -e NCBI_API_KEY=\"YOUR_VALUE_HERE\" \\\n    -e SERPER_API_KEY=\"YOUR_VALUE_HERE\" \\\n    -e CHROMA_DB_PATH=\"./chroma_db\" \\\n    -e CHROMA_DB_HOST=\"localhost\" \\\n    -e CHROMA_DB_PORT=\"8000\" \\\n    -e RAG_COLLECTION_NAME=\"deepcritical_evidence\" \\\n    -e RAG_SIMILARITY_TOP_K=\"5\" \\\n    -e RAG_AUTO_INGEST=\"true\" \\\n    -e USE_GRAPH_EXECUTION=\"false\" \\\n    -e DEFAULT_TOKEN_LIMIT=\"100000\" \\\n    -e DEFAULT_TIME_LIMIT_MINUTES=\"10\" \\\n    -e DEFAULT_ITERATIONS_LIMIT=\"10\" \\\n    -e WEB_SEARCH_PROVIDER=\"duckduckgo\" \\\n    -e MAX_ITERATIONS=\"10\" \\\n    -e SEARCH_TIMEOUT=\"30\" \\\n    -e LOG_LEVEL=\"DEBUG\" \\\n    -e EMBEDDING_PROVIDER=\"local\" \\\n    -e OPENAI_EMBEDDING_MODEL=\"text-embedding-3-small\" \\\n    -e LOCAL_EMBEDDING_MODEL=\"BAAI/bge-small-en-v1.5\" \\\n    -e HUGGINGFACE_EMBEDDING_MODEL=\"sentence-transformers/all-MiniLM-L6-v2\" \\\n    -e HF_FALLBACK_MODELS=\"Qwen/Qwen3-Next-80B-A3B-Thinking,Qwen/Qwen3-Next-80B-A3B-Instruct,meta-llama/Llama-3.3-70B-Instruct,meta-llama/Llama-3.1-8B-Instruct,HuggingFaceH4/zephyr-7b-beta,Qwen/Qwen2-7B-Instruct\" \\\n    -e HUGGINGFACE_MODEL=\"Qwen/Qwen3-Next-80B-A3B-Thinking\" \\\n    registry.hf.space/dataquests-deepcritical:latest python src/app.py\n   ```\n\n## Quick start guide\n\nGet up and running with The DETERMINATOR in minutes.\n\n## Start the Application\n\n```bash\ngradio src/app.py\n

    Open your browser to http://localhost:7860.

    "},{"location":"getting-started/quick-start/#first-research-query","title":"First Research Query","text":"
    1. Enter a Research Question

    Type your research question in the chat interface, for example: - \"What are the latest treatments for Alzheimer's disease?\" - \"Review the evidence for metformin in cancer prevention\" - \"What clinical trials are investigating COVID-19 vaccines?\"

    1. Submit the Query

    Click \"Submit\" or press Enter. The system will: - Generate observations about your query - Identify knowledge gaps - Search multiple sources (PubMed, ClinicalTrials.gov, Europe PMC) - Evaluate evidence quality - Synthesize findings into a report

    1. Review Results

    Watch the real-time progress in the chat interface: - Search operations and results - Evidence evaluation - Report generation - Final research report with citations

    "},{"location":"getting-started/quick-start/#authentication","title":"Authentication","text":""},{"location":"getting-started/quick-start/#huggingface-oauth-recommended","title":"HuggingFace OAuth (Recommended)","text":"
    1. Click \"Sign in with HuggingFace\" at the top of the app
    2. Authorize the application
    3. Your HuggingFace API token will be automatically used
    4. No need to manually enter API keys
    "},{"location":"getting-started/quick-start/#manual-api-key","title":"Manual API Key","text":"
    1. Open the Settings accordion
    2. Enter your API key:
    3. OpenAI API key
    4. Anthropic API key
    5. HuggingFace API key
    6. Click \"Save Settings\"
    7. Manual keys take priority over OAuth tokens
    "},{"location":"getting-started/quick-start/#understanding-the-interface","title":"Understanding the Interface","text":""},{"location":"getting-started/quick-start/#chat-interface","title":"Chat Interface","text":""},{"location":"getting-started/quick-start/#status-indicators","title":"Status Indicators","text":""},{"location":"getting-started/quick-start/#settings","title":"Settings","text":""},{"location":"getting-started/quick-start/#example-queries","title":"Example Queries","text":""},{"location":"getting-started/quick-start/#simple-query","title":"Simple Query","text":"
    What are the side effects of metformin?\n
    "},{"location":"getting-started/quick-start/#complex-query","title":"Complex Query","text":"
    Review the evidence for using metformin as an anti-aging intervention, \nincluding clinical trials, mechanisms of action, and safety profile.\n
    "},{"location":"getting-started/quick-start/#clinical-trial-query","title":"Clinical Trial Query","text":"
    What are the active clinical trials investigating Alzheimer's disease treatments?\n
    "},{"location":"getting-started/quick-start/#next-steps","title":"Next Steps","text":""},{"location":"overview/architecture/","title":"Architecture Overview","text":"

    The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations). The system automatically determines if medical knowledge sources are needed and adapts its search strategy accordingly. It supports multiple orchestration patterns, graph-based execution, parallel research workflows, and long-running task management with real-time streaming.

    "},{"location":"overview/architecture/#core-architecture","title":"Core Architecture","text":""},{"location":"overview/architecture/#orchestration-patterns","title":"Orchestration Patterns","text":"
    1. Graph Orchestrator (src/orchestrator/graph_orchestrator.py):
    2. Graph-based execution using Pydantic AI agents as nodes
    3. Supports both iterative and deep research patterns
    4. Node types: Agent, State, Decision, Parallel
    5. Edge types: Sequential, Conditional, Parallel
    6. Conditional routing based on knowledge gaps, budget, and iterations
    7. Parallel execution for concurrent research loops
    8. Event streaming via AsyncGenerator[AgentEvent] for real-time UI updates
    9. Fallback to agent chains when graph execution is disabled

    10. Deep Research Flow (src/orchestrator/research_flow.py):

    11. Pattern: Planner \u2192 Parallel Iterative Loops (one per section) \u2192 Synthesis
    12. Uses PlannerAgent to break query into report sections
    13. Runs IterativeResearchFlow instances in parallel per section via WorkflowManager
    14. Synthesizes results using LongWriterAgent or ProofreaderAgent
    15. Supports both graph execution (use_graph=True) and agent chains (use_graph=False)
    16. Budget tracking per section and globally
    17. State synchronization across parallel loops

    18. Iterative Research Flow (src/orchestrator/research_flow.py):

    19. Pattern: Generate observations \u2192 Evaluate gaps \u2192 Select tools \u2192 Execute \u2192 Judge \u2192 Continue/Complete
    20. Uses KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent, WriterAgent
    21. JudgeHandler assesses evidence sufficiency
    22. Iterates until research complete or constraints met (iterations, time, tokens)
    23. Supports graph execution and agent chains

    24. Magentic Orchestrator (src/orchestrator_magentic.py):

    25. Multi-agent coordination using agent-framework-core
    26. ChatAgent pattern with internal LLMs per agent
    27. Uses MagenticBuilder with participants: searcher, hypothesizer, judge, reporter
    28. Manager orchestrates agents via OpenAIChatClient
    29. Requires OpenAI API key (function calling support)
    30. Event-driven: converts Magentic events to AgentEvent for UI streaming
    31. Supports long-running workflows with max rounds and stall/reset handling

    32. Hierarchical Orchestrator (src/orchestrator_hierarchical.py):

    33. Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge
    34. Adapts Magentic ChatAgent to SubIterationTeam protocol
    35. Event-driven via asyncio.Queue for coordination
    36. Supports sub-iteration patterns for complex research tasks

    37. Legacy Simple Mode (src/legacy_orchestrator.py):

    38. Linear search-judge-synthesize loop
    39. Uses SearchHandlerProtocol and JudgeHandlerProtocol
    40. Generator-based design yielding AgentEvent objects
    41. Backward compatibility for simple use cases
    "},{"location":"overview/architecture/#long-running-task-support","title":"Long-Running Task Support","text":"

    The system is designed for long-running research tasks with comprehensive state management and streaming:

    1. Event Streaming:
    2. All orchestrators yield AgentEvent objects via AsyncGenerator
    3. Real-time UI updates through Gradio chat interface
    4. Event types: started, searching, search_complete, judging, judge_complete, looping, synthesizing, hypothesizing, complete, error
    5. Metadata includes iteration numbers, tool names, result counts, durations

    6. Budget Tracking (src/middleware/budget_tracker.py):

    7. Per-loop and global budget management
    8. Tracks: tokens, time (seconds), iterations
    9. Budget enforcement at decision nodes
    10. Token estimation (~4 chars per token)
    11. Early termination when budgets exceeded
    12. Budget summaries for monitoring

    13. Workflow Manager (src/middleware/workflow_manager.py):

    14. Coordinates parallel research loops
    15. Tracks loop status: pending, running, completed, failed, cancelled
    16. Synchronizes evidence between loops and global state
    17. Handles errors per loop (doesn't fail all if one fails)
    18. Supports loop cancellation and timeout handling
    19. Evidence deduplication across parallel loops

    20. State Management (src/middleware/state_machine.py):

    21. Thread-safe isolation using ContextVar for concurrent requests
    22. WorkflowState tracks: evidence, conversation history, embedding service
    23. Evidence deduplication by URL
    24. Semantic search via embedding service
    25. State persistence across long-running workflows
    26. Supports both iterative and deep research patterns

    27. Gradio UI (src/app.py):

    28. Real-time streaming of research progress
    29. Accordion-based UI for pending/done operations
    30. OAuth integration (HuggingFace)
    31. Multiple backend support (API keys, free tier)
    32. Handles long-running tasks with progress indicators
    33. Event accumulation for pending operations
    "},{"location":"overview/architecture/#graph-architecture","title":"Graph Architecture","text":"

    The graph orchestrator (src/orchestrator/graph_orchestrator.py) implements a flexible graph-based execution model:

    Node Types:

    Edge Types:

    Graph Patterns:

    Execution Flow:

    1. Graph construction from nodes and edges
    2. Graph validation (no cycles, all nodes reachable)
    3. Graph execution from entry node
    4. Node execution based on type
    5. Edge evaluation for next node(s)
    6. Parallel execution via asyncio.gather()
    7. State updates at state nodes
    8. Event streaming for UI
    "},{"location":"overview/architecture/#key-components","title":"Key Components","text":""},{"location":"overview/architecture/#research-team--parallel-execution","title":"Research Team & Parallel Execution","text":"

    The system supports complex research workflows through:

    1. WorkflowManager: Coordinates multiple parallel research loops
    2. Creates and tracks ResearchLoop instances
    3. Runs loops in parallel via asyncio.gather()
    4. Synchronizes evidence to global state
    5. Handles loop failures gracefully

    6. Deep Research Pattern: Breaks complex queries into sections

    7. Planner creates report outline with sections
    8. Each section runs as independent iterative research loop
    9. Loops execute in parallel
    10. Evidence shared across loops via global state
    11. Final synthesis combines all section results

    12. State Synchronization: Thread-safe evidence sharing

    13. Evidence deduplication by URL
    14. Global state accessible to all loops
    15. Semantic search across all collected evidence
    16. Conversation history tracking per iteration
    "},{"location":"overview/architecture/#configuration--modes","title":"Configuration & Modes","text":"

    Note: The UI provides separate controls for orchestrator mode and graph research mode. When using graph-based orchestrators (iterative/deep/auto), the graph research mode determines the specific pattern used within the graph execution.

    "},{"location":"overview/features/","title":"Features","text":"

    The DETERMINATOR provides a comprehensive set of features for AI-assisted research:

    "},{"location":"overview/features/#core-features","title":"Core Features","text":""},{"location":"overview/features/#multi-source-search","title":"Multi-Source Search","text":""},{"location":"overview/features/#mcp-integration","title":"MCP Integration","text":""},{"location":"overview/features/#authentication","title":"Authentication","text":""},{"location":"overview/features/#secure-code-execution","title":"Secure Code Execution","text":""},{"location":"overview/features/#semantic-search--rag","title":"Semantic Search & RAG","text":""},{"location":"overview/features/#orchestration-patterns","title":"Orchestration Patterns","text":"

    Orchestrator Modes: - simple: Legacy linear search-judge loop - advanced (or magentic): Multi-agent coordination (requires OpenAI API key) - iterative: Knowledge-gap-driven research with single loop - deep: Parallel section-based research with planning - auto: Intelligent mode detection based on query complexity

    Graph Research Modes (used within graph orchestrator): - iterative: Single research loop pattern - deep: Multi-section parallel research pattern - auto: Auto-detect pattern based on query complexity

    Execution Modes: - use_graph=True: Graph-based execution with parallel and conditional routing - use_graph=False: Agent chains with sequential execution (backward compatible)

    "},{"location":"overview/features/#real-time-streaming","title":"Real-Time Streaming","text":""},{"location":"overview/features/#budget-management","title":"Budget Management","text":""},{"location":"overview/features/#state-management","title":"State Management","text":""},{"location":"overview/features/#multimodal-input--output","title":"Multimodal Input & Output","text":""},{"location":"overview/features/#advanced-features","title":"Advanced Features","text":""},{"location":"overview/features/#agent-system","title":"Agent System","text":""},{"location":"overview/features/#search-tools","title":"Search Tools","text":""},{"location":"overview/features/#error-handling","title":"Error Handling","text":""},{"location":"overview/features/#configuration","title":"Configuration","text":""},{"location":"overview/features/#testing","title":"Testing","text":""},{"location":"overview/features/#ui-features","title":"UI Features","text":""},{"location":"overview/features/#gradio-interface","title":"Gradio Interface","text":""},{"location":"overview/features/#mcp-server","title":"MCP Server","text":""},{"location":"overview/features/#development-features","title":"Development Features","text":""},{"location":"overview/features/#code-quality","title":"Code Quality","text":""},{"location":"overview/features/#documentation","title":"Documentation","text":""},{"location":"overview/quick-start/","title":"Quick Start","text":"

    Get started with DeepCritical in minutes.

    "},{"location":"overview/quick-start/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync dependencies\nuv sync\n
    "},{"location":"overview/quick-start/#run-the-ui","title":"Run the UI","text":"
    # Start the Gradio app\nuv run gradio run src/app.py\n

    Open your browser to http://localhost:7860.

    "},{"location":"overview/quick-start/#basic-usage","title":"Basic Usage","text":""},{"location":"overview/quick-start/#1-authentication-required","title":"1. Authentication (REQUIRED)","text":"

    Authentication is mandatory - you must authenticate before using the application. The app will display an error message if you try to use it without authentication.

    HuggingFace OAuth Login (Recommended): - Click the \"Sign in with HuggingFace\" button at the top of the app - Your HuggingFace API token will be automatically used for AI inference - No need to manually enter API keys when logged in

    Manual API Key (Alternative): - Set environment variable HF_TOKEN or HUGGINGFACE_API_KEY before starting the app - The app will automatically use these tokens if OAuth login is not available - Supports HuggingFace API keys only (OpenAI/Anthropic keys are not used in the current implementation)

    "},{"location":"overview/quick-start/#2-start-a-research-query","title":"2. Start a Research Query","text":"
    1. Enter your research question in the chat interface
    2. Text Input: Type your question directly
    3. Image Input: Click the \ud83d\udcf7 icon to upload images (OCR will extract text)
    4. Audio Input: Click the \ud83c\udfa4 icon to record or upload audio (STT will transcribe to text)
    5. Click \"Submit\" or press Enter
    6. Watch the real-time progress as the system:
    7. Generates observations
    8. Identifies knowledge gaps
    9. Searches multiple sources
    10. Evaluates evidence
    11. Synthesizes findings
    12. Review the final research report
    13. Audio Output: If enabled, the final response will include audio synthesis (TTS)

    Multimodal Features: - Configure image/audio input and output in the sidebar settings - Image OCR and audio STT/TTS can be enabled/disabled independently - TTS voice and speed can be customized in the Audio Output settings

    "},{"location":"overview/quick-start/#3-mcp-integration-optional","title":"3. MCP Integration (Optional)","text":"

    Connect DeepCritical to Claude Desktop:

    1. Add to your claude_desktop_config.json:

      {\n  \"mcpServers\": {\n    \"deepcritical\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    }\n  }\n}\n

    2. Restart Claude Desktop

    3. Use DeepCritical tools directly from Claude Desktop
    "},{"location":"overview/quick-start/#available-tools","title":"Available Tools","text":"

    Note: The application automatically uses all available search tools (Neo4j, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG) based on query analysis. Neo4j knowledge graph search is included by default for biomedical queries.

    "},{"location":"overview/quick-start/#next-steps","title":"Next Steps","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"The DETERMINATOR","text":"

    Generalist Deep Research Agent - Stops at Nothing Until Finding Precise Answers

    The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations).

    Key Features: - Generalist: Handles queries from any domain (medical, technical, business, scientific, etc.) - Automatic Source Selection: Automatically determines if medical knowledge sources (PubMed, ClinicalTrials.gov) are needed - Multi-Source Search: Web search, PubMed, ClinicalTrials.gov, Europe PMC, RAG - Iterative Refinement: Continues searching and refining until precise answers are found - Evidence Synthesis: Comprehensive reports with proper citations

    Important: The DETERMINATOR is a research tool that synthesizes evidence. It cannot provide medical advice or answer medical questions directly.

    "},{"location":"#features","title":"Features","text":""},{"location":"#quick-start","title":"Quick Start","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync dependencies\nuv sync\n\n# Start the Gradio app\nuv run gradio run src/app.py\n

    Open your browser to http://localhost:7860.

    For detailed installation and setup instructions, see the Getting Started Guide.

    "},{"location":"#architecture","title":"Architecture","text":"

    The DETERMINATOR uses a Vertical Slice Architecture:

    1. Search Slice: Retrieving evidence from multiple sources (web, PubMed, ClinicalTrials.gov, Europe PMC, RAG) based on query analysis
    2. Judge Slice: Evaluating evidence quality using LLMs
    3. Orchestrator Slice: Managing the research loop and UI

    The system supports three main research patterns:

    Learn more about the Architecture.

    "},{"location":"#documentation","title":"Documentation","text":""},{"location":"#links","title":"Links","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/","title":"MkDocs & Material UI Improvement Assessment","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#current-configuration-analysis","title":"Current Configuration Analysis","text":"

    Your current mkdocs.yml already includes many excellent features: - \u2705 Material theme with light/dark mode toggle - \u2705 Navigation tabs, sections, expand, and top navigation - \u2705 Search with suggestions and highlighting - \u2705 Code annotation and copy buttons - \u2705 Mermaid diagram support - \u2705 Code include plugin - \u2705 Minification for performance - \u2705 Comprehensive markdown extensions

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#recommended-improvements","title":"Recommended Improvements","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#1-versioning--multi-version-documentation--high-priority","title":"1. Versioning & Multi-Version Documentation \u2b50 High Priority","text":"

    If you plan to maintain multiple versions or branches:

    plugins:\n  - search\n  - mermaid2\n  - codeinclude\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n  # Optional: For versioning\n  # - versioning:\n  #     version: ['dev', 'main']\n

    Benefits: Shows when pages were last updated, helps users understand document freshness.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#2-git-integration--revision-information--high-priority","title":"2. Git Integration & Revision Information \u2b50 High Priority","text":"

    Add revision dates and authors to pages:

    plugins:\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n      fallback_to_build_date: true\n  - git-committers:\n      repository: DeepCritical/GradioDemo\n      branch: dev\n

    Benefits: Users see when content was last updated, builds trust in documentation freshness.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#3-enhanced-navigation-features--high-priority","title":"3. Enhanced Navigation Features \u2b50 High Priority","text":"

    Add breadcrumbs and improve navigation:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes  # Add index pages\n    - navigation.instant  # Instant page loads\n    - navigation.tracking  # Track scroll position\n    - navigation.smooth  # Smooth scrolling\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link  # Link to specific tabs\n    - content.tooltips  # Tooltips for abbreviations\n

    Benefits: Better UX, easier navigation, professional feel.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#4-content-tabs-for-code-examples--high-priority","title":"4. Content Tabs for Code Examples \u2b50 High Priority","text":"

    Perfect for showing multiple code examples (Python, TypeScript, etc.):

    markdown_extensions:\n  - pymdownx.tabbed:\n      alternate_style: true\n      combine_header_slug: true  # Add this\n

    Usage in docs:

    === \"Python\"\n    ```python\n    def example():\n        pass\n    ```\n\n=== \"TypeScript\"\n    ```typescript\n    function example() {}\n    ```\n

    Benefits: Clean way to show multiple implementations without cluttering pages.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#5-enhanced-admonitions--medium-priority","title":"5. Enhanced Admonitions \u2b50 Medium Priority","text":"

    Add more admonition types and better styling:

    markdown_extensions:\n  - admonition\n  - pymdownx.details\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n        # Add custom admonition fences\n        - name: danger\n          class: danger\n          format: !!python/name:pymdownx.superfences.fence_code_format\n

    Usage:

    !!! danger \"Important\"\n    This is a critical warning.\n

    Benefits: Better visual hierarchy for warnings, tips, and important information.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#6-math-formula-support--medium-priority-if-needed","title":"6. Math Formula Support \u2b50 Medium Priority (if needed)","text":"

    If your documentation includes mathematical formulas:

    markdown_extensions:\n  - pymdownx.arithmatex:\n      generic: true\n  - pymdownx.superfences:\n      custom_fences:\n        - name: math\n          class: arithmetic\n          format: !!python/name:pymdownx.superfences.fence_code_format\n\nextra_javascript:\n  - javascripts/mathjax.js\n  - https://polyfill.io/v3/polyfill.min.js?features=es6\n  - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js\n

    Benefits: Essential for scientific/technical documentation with formulas.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#7-better-code-highlighting--medium-priority","title":"7. Better Code Highlighting \u2b50 Medium Priority","text":"

    Add more language support and better themes:

    markdown_extensions:\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n      use_pygments: true\n      noclasses: false  # Use CSS classes instead of inline styles\n

    Benefits: Better syntax highlighting, more language support.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#8-social-links-enhancement--low-priority","title":"8. Social Links Enhancement \u2b50 Low Priority","text":"

    Add more social platforms and better icons:

    extra:\n  social:\n    - icon: fontawesome/brands/github\n      link: https://github.com/DeepCritical/GradioDemo\n      name: GitHub\n    - icon: fontawesome/brands/twitter\n      link: https://twitter.com/yourhandle\n      name: Twitter\n    - icon: material/web\n      link: https://huggingface.co/spaces/DataQuests/DeepCritical\n      name: HuggingFace Space\n    - icon: fontawesome/brands/discord\n      link: https://discord.gg/yourserver\n      name: Discord\n

    Benefits: Better community engagement, more ways to connect.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#9-analytics-integration--medium-priority","title":"9. Analytics Integration \u2b50 Medium Priority","text":"

    Add privacy-respecting analytics:

    extra:\n  analytics:\n    provider: google\n    property: G-XXXXXXXXXX\n  # Or use privacy-focused alternative:\n  # analytics:\n  #   provider: plausible\n  #   domain: yourdomain.com\n

    Benefits: Understand how users interact with your documentation.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#10-custom-cssjs-for-branding--low-priority","title":"10. Custom CSS/JS for Branding \u2b50 Low Priority","text":"

    Add custom styling:

    extra_css:\n  - stylesheets/extra.css\n\nextra_javascript:\n  - javascripts/extra.js\n

    Benefits: Customize appearance, add interactive features.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#11-better-table-of-contents--medium-priority","title":"11. Better Table of Contents \u2b50 Medium Priority","text":"

    Enhance TOC with more options:

    markdown_extensions:\n  - toc:\n      permalink: true\n      permalink_title: \"Anchor link to this section\"\n      baselevel: 1\n      toc_depth: 3\n      slugify: !!python/object/apply:pymdownx.slugs.slugify\n        kwds:\n          case: lower\n

    Benefits: Better navigation within long pages, SEO-friendly anchor links.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#12-image-optimization--medium-priority","title":"12. Image Optimization \u2b50 Medium Priority","text":"

    Add image handling plugin:

    plugins:\n  - search\n  - mermaid2\n  - codeinclude\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n  # Optional: Image optimization\n  # - awesome-pages  # For better page organization\n

    Benefits: Faster page loads, better mobile experience.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#13-keyboard-shortcuts--low-priority","title":"13. Keyboard Shortcuts \u2b50 Low Priority","text":"

    Enable keyboard navigation:

    theme:\n  keyboard_shortcuts:\n    search: true\n    previous: true\n    next: true\n

    Benefits: Power users can navigate faster.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#14-print-styles--low-priority","title":"14. Print Styles \u2b50 Low Priority","text":"

    Better printing experience:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes\n    - navigation.instant\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - content.action.edit  # Edit button\n    - content.action.view  # View source\n

    Benefits: Users can print documentation cleanly.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#15-better-search-configuration--medium-priority","title":"15. Better Search Configuration \u2b50 Medium Priority","text":"

    Enhance search capabilities:

    plugins:\n  - search:\n      lang:\n        - en\n      separator: '[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&amp;'\n      prebuild_index: true  # For faster search\n      indexing: full  # Full-text indexing\n

    Benefits: Faster, more accurate search results.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#16-api-documentation-enhancements--high-priority-for-your-api-docs","title":"16. API Documentation Enhancements \u2b50 High Priority (for your API docs)","text":"

    Since you have extensive API documentation, consider:

    markdown_extensions:\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n      preserve_tabs: true\n  # Add API-specific features\n  - attr_list\n  - md_in_html\n  - pymdownx.caret\n  - pymdownx.tilde\n

    Benefits: Better formatting for API endpoints, parameters, responses.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#17-blognews-section--low-priority-if-needed","title":"17. Blog/News Section \u2b50 Low Priority (if needed)","text":"

    If you want to add a blog:

    plugins:\n  - blog:\n      blog_dir: blog\n      blog_description: \"News and updates\"\n      post_date_format: full\n      post_url_format: '{slug}'\n      archive: true\n

    Benefits: Keep users updated with changelog, announcements.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#18-tags-and-categories--low-priority","title":"18. Tags and Categories \u2b50 Low Priority","text":"

    Organize content with tags:

    markdown_extensions:\n  - meta\n

    Then in frontmatter:

    ---\ntags:\n  - api\n  - agents\n  - getting-started\n---\n

    Benefits: Better content organization, related content discovery.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#19-better-mobile-experience--high-priority","title":"19. Better Mobile Experience \u2b50 High Priority","text":"

    Ensure mobile optimization:

    theme:\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.instant  # Helps on mobile\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - toc.integrate  # Better mobile TOC\n

    Benefits: Better experience for mobile users (growing segment).

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#20-feedback-mechanism--medium-priority","title":"20. Feedback Mechanism \u2b50 Medium Priority","text":"

    Add feedback buttons:

    extra:\n  feedback:\n    title: \"Was this page helpful?\"\n    ratings:\n      - icon: material/thumb-up-outline\n        name: \"This page was helpful\"\n      - icon: material/thumb-down-outline\n        name: \"This page could be improved\"\n

    Benefits: Understand what content needs improvement.

    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#priority-recommendations","title":"Priority Recommendations","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#immediate-high-impact-easy-implementation","title":"Immediate (High Impact, Easy Implementation)","text":"
    1. \u2705 Git revision dates - Shows content freshness
    2. \u2705 Enhanced navigation features - Better UX
    3. \u2705 Content tabs - Perfect for code examples
    4. \u2705 Better search configuration - Faster search
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#short-term-high-impact-medium-effort","title":"Short-term (High Impact, Medium Effort)","text":"
    1. \u2705 API documentation enhancements - Better API docs
    2. \u2705 Enhanced admonitions - Better visual hierarchy
    3. \u2705 Mobile optimization - Better mobile experience
    4. \u2705 Analytics - Understand user behavior
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#long-term-nice-to-have","title":"Long-term (Nice to Have)","text":"
    1. \u26a0\ufe0f Versioning - If you need multiple versions
    2. \u26a0\ufe0f Math formulas - If you have mathematical content
    3. \u26a0\ufe0f Blog section - If you want to publish updates
    4. \u26a0\ufe0f Custom CSS/JS - For advanced customization
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#implementation-example","title":"Implementation Example","text":"

    Here's an enhanced mkdocs.yml with the high-priority improvements:

    site_name: The DETERMINATOR\nsite_description: Generalist Deep Research Agent that Stops at Nothing\nsite_author: The DETERMINATOR Team\nsite_url: https://deepcritical.github.io/GradioDemo/\n\nrepo_name: DeepCritical/GradioDemo\nrepo_url: https://github.com/DeepCritical/GradioDemo\nedit_uri: edit/dev/docs/\n\nstrict: false\n\ntheme:\n  name: material\n  palette:\n    - scheme: default\n      primary: orange\n      accent: red\n      toggle:\n        icon: material/brightness-7\n        name: Switch to dark mode\n    - scheme: slate\n      primary: orange\n      accent: red\n      toggle:\n        icon: material/brightness-4\n        name: Switch to light mode\n  features:\n    - navigation.tabs\n    - navigation.sections\n    - navigation.expand\n    - navigation.top\n    - navigation.indexes\n    - navigation.instant\n    - navigation.tracking\n    - navigation.smooth\n    - search.suggest\n    - search.highlight\n    - content.code.annotate\n    - content.code.copy\n    - content.tabs.link\n    - content.tooltips\n    - toc.integrate\n  icon:\n    repo: fontawesome/brands/github\n  language: en\n\nplugins:\n  - search:\n      lang:\n        - en\n      separator: '[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|&amp;'\n      prebuild_index: true\n      indexing: full\n  - mermaid2\n  - codeinclude\n  - git-revision-date-localized:\n      enable_creation_date: true\n      type: timeago\n      fallback_to_build_date: true\n  - minify:\n      minify_html: true\n      minify_js: true\n      minify_css: true\n\nmarkdown_extensions:\n  - dev.docs_plugins:\n      base_path: \".\"\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n      use_pygments: true\n      noclasses: false\n  - pymdownx.inlinehilite\n  - pymdownx.superfences:\n      custom_fences:\n        - name: mermaid\n          class: mermaid\n          format: !!python/name:pymdownx.superfences.fence_code_format\n      preserve_tabs: true\n  - pymdownx.tabbed:\n      alternate_style: true\n      combine_header_slug: true\n  - pymdownx.tasklist:\n      custom_checkbox: true\n  - pymdownx.emoji:\n      emoji_generator: !!python/name:pymdownx.emoji.to_svg\n      emoji_index: !!python/name:pymdownx.emoji.twemoji\n  - pymdownx.snippets\n  - admonition\n  - pymdownx.details\n  - attr_list\n  - md_in_html\n  - tables\n  - meta\n  - toc:\n      permalink: true\n      permalink_title: \"Anchor link to this section\"\n      baselevel: 1\n      toc_depth: 3\n      slugify: !!python/object/apply:pymdownx.slugs.slugify\n        kwds:\n          case: lower\n\nnav:\n  - Home: index.md\n  - Overview:\n    - overview/architecture.md\n    - overview/features.md\n  - Getting Started:\n    - getting-started/installation.md\n    - getting-started/quick-start.md\n    - getting-started/mcp-integration.md\n    - getting-started/examples.md\n  - Configuration:\n    - configuration/index.md\n  - Architecture:\n    - \"Graph Orchestration\": architecture/graph_orchestration.md\n    - \"Workflow Diagrams\": architecture/workflow-diagrams.md\n    - \"Agents\": architecture/agents.md\n    - \"Orchestrators\": architecture/orchestrators.md\n    - \"Tools\": architecture/tools.md\n    - \"Middleware\": architecture/middleware.md\n    - \"Services\": architecture/services.md\n  - API Reference:\n    - api/agents.md\n    - api/tools.md\n    - api/orchestrators.md\n    - api/services.md\n    - api/models.md\n  - Contributing:\n    - contributing/index.md\n    - contributing/code-quality.md\n    - contributing/code-style.md\n    - contributing/error-handling.md\n    - contributing/implementation-patterns.md\n    - contributing/prompt-engineering.md\n    - contributing/testing.md\n  - License: LICENSE.md\n  - Team: team.md\n\nextra:\n  social:\n    - icon: fontawesome/brands/github\n      link: https://github.com/DeepCritical/GradioDemo\n      name: GitHub\n    - icon: material/web\n      link: https://huggingface.co/spaces/DataQuests/DeepCritical\n      name: HuggingFace Space\n  version:\n    provider: mike\n  generator:\n    enabled: false\n\ncopyright: Copyright &copy; 2024 DeepCritical Team\n
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#additional-documentation-improvements","title":"Additional Documentation Improvements","text":""},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#content-structure","title":"Content Structure","text":"
    1. Add a changelog page - Keep users informed of updates
    2. Add a FAQ section - Address common questions
    3. Add a glossary - Define technical terms
    4. Add a troubleshooting guide - Help users solve common issues
    5. Add video tutorials - Embed videos for complex topics
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#visual-enhancements","title":"Visual Enhancements","text":"
    1. Add diagrams - Use more Mermaid diagrams for complex flows
    2. Add screenshots - Visual guides for UI features
    3. Add code examples - More practical examples
    4. Add comparison tables - Compare different approaches/options
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#seo--discoverability","title":"SEO & Discoverability","text":"
    1. Add meta descriptions - Better search engine results
    2. Add Open Graph tags - Better social media sharing
    3. Add sitemap - Help search engines index your docs
    4. Add robots.txt - Control search engine crawling
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#next-steps","title":"Next Steps","text":"
    1. Review this assessment
    2. Prioritize features based on your needs
    3. Test changes in a branch
    4. Gather user feedback
    5. Iterate and improve
    "},{"location":"MKDOCS_IMPROVEMENTS_ASSESSMENT/#resources","title":"Resources","text":""},{"location":"team/","title":"Team","text":"

    DeepCritical is developed by a team of researchers and developers working on AI-assisted research.

    "},{"location":"team/#team-members","title":"Team Members","text":""},{"location":"team/#zj","title":"ZJ","text":""},{"location":"team/#mario-aderman","title":"Mario Aderman","text":""},{"location":"team/#joseph-pollack","title":"Joseph Pollack","text":""},{"location":"team/#virat-chauran","title":"Virat Chauran","text":""},{"location":"team/#anna-bossler","title":"Anna Bossler","text":""},{"location":"team/#about","title":"About","text":"

    The DeepCritical team met online in the Alzheimer's Critical Literature Review Group in the Hugging Science initiative. We're building the agent framework we want to use for AI-assisted research to turn the vast amounts of clinical data into cures.

    "},{"location":"team/#contributing","title":"Contributing","text":"

    We welcome contributions! See the Contributing Guide for details.

    "},{"location":"team/#links","title":"Links","text":""},{"location":"api/agents/","title":"Agents API Reference","text":"

    This page documents the API for DeepCritical agents.

    "},{"location":"api/agents/#knowledgegapagent","title":"KnowledgeGapAgent","text":"

    Module: src.agents.knowledge_gap

    Purpose: Evaluates research state and identifies knowledge gaps.

    "},{"location":"api/agents/#methods","title":"Methods","text":""},{"location":"api/agents/#evaluate","title":"evaluate","text":"

    Evaluates research completeness and identifies outstanding knowledge gaps.

    Parameters: - query: Research query string - background_context: Background context for the query (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\") - iteration: Current iteration number (default: 0) - time_elapsed_minutes: Elapsed time in minutes (default: 0.0) - max_time_minutes: Maximum time limit in minutes (default: 10)

    Returns: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    "},{"location":"api/agents/#toolselectoragent","title":"ToolSelectorAgent","text":"

    Module: src.agents.tool_selector

    Purpose: Selects appropriate tools for addressing knowledge gaps.

    "},{"location":"api/agents/#methods_1","title":"Methods","text":""},{"location":"api/agents/#select_tools","title":"select_tools","text":"

    Selects tools for addressing a knowledge gap.

    Parameters: - gap: The knowledge gap to address - query: Research query string - background_context: Optional background context (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\")

    Returns: AgentSelectionPlan with list of AgentTask objects.

    "},{"location":"api/agents/#writeragent","title":"WriterAgent","text":"

    Module: src.agents.writer

    Purpose: Generates final reports from research findings.

    "},{"location":"api/agents/#methods_2","title":"Methods","text":""},{"location":"api/agents/#write_report","title":"write_report","text":"

    Generates a markdown report from research findings.

    Parameters: - query: Research query string - findings: Research findings to include in report - output_length: Optional description of desired output length (default: \"\") - output_instructions: Optional additional instructions for report generation (default: \"\")

    Returns: Markdown string with numbered citations.

    "},{"location":"api/agents/#longwriteragent","title":"LongWriterAgent","text":"

    Module: src.agents.long_writer

    Purpose: Long-form report generation with section-by-section writing.

    "},{"location":"api/agents/#methods_3","title":"Methods","text":""},{"location":"api/agents/#write_next_section","title":"write_next_section","text":"

    Writes the next section of a long-form report.

    Parameters: - original_query: The original research query - report_draft: Current report draft as string (all sections written so far) - next_section_title: Title of the section to write - next_section_draft: Draft content for the next section

    Returns: LongWriterOutput with formatted section and references.

    "},{"location":"api/agents/#write_report_1","title":"write_report","text":"

    Generates final report from draft.

    Parameters: - query: Research query string - report_title: Title of the report - report_draft: Complete report draft

    Returns: Final markdown report string.

    "},{"location":"api/agents/#proofreaderagent","title":"ProofreaderAgent","text":"

    Module: src.agents.proofreader

    Purpose: Proofreads and polishes report drafts.

    "},{"location":"api/agents/#methods_4","title":"Methods","text":""},{"location":"api/agents/#proofread","title":"proofread","text":"

    Proofreads and polishes a report draft.

    Parameters: - query: Research query string - report_title: Title of the report - report_draft: Report draft to proofread

    Returns: Polished markdown string.

    "},{"location":"api/agents/#thinkingagent","title":"ThinkingAgent","text":"

    Module: src.agents.thinking

    Purpose: Generates observations from conversation history.

    "},{"location":"api/agents/#methods_5","title":"Methods","text":""},{"location":"api/agents/#generate_observations","title":"generate_observations","text":"

    Generates observations from conversation history.

    Parameters: - query: Research query string - background_context: Optional background context (default: \"\") - conversation_history: History of actions, findings, and thoughts as string (default: \"\") - iteration: Current iteration number (default: 1)

    Returns: Observation string.

    "},{"location":"api/agents/#inputparseragent","title":"InputParserAgent","text":"

    Module: src.agents.input_parser

    Purpose: Parses and improves user queries, detects research mode.

    "},{"location":"api/agents/#methods_6","title":"Methods","text":""},{"location":"api/agents/#parse","title":"parse","text":"

    Parses and improves a user query.

    Parameters: - query: Original query string

    Returns: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: \"iterative\" or \"deep\" - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"api/agents/#factory-functions","title":"Factory Functions","text":"

    All agents have factory functions in src.agent_factory.agents:

    Parameters: - model: Optional Pydantic AI model. If None, uses get_model() from settings. - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Returns: Agent instance.

    "},{"location":"api/agents/#see-also","title":"See Also","text":""},{"location":"api/models/","title":"Models API Reference","text":"

    This page documents the Pydantic models used throughout DeepCritical.

    "},{"location":"api/models/#evidence","title":"Evidence","text":"

    Module: src.utils.models

    Purpose: Represents evidence from search results.

    Fields: - citation: Citation information (title, URL, date, authors) - content: Evidence text content - relevance: Relevance score (0.0-1.0) - metadata: Additional metadata dictionary

    "},{"location":"api/models/#citation","title":"Citation","text":"

    Module: src.utils.models

    Purpose: Citation information for evidence.

    Fields: - source: Source name (e.g., \"pubmed\", \"clinicaltrials\", \"europepmc\", \"web\", \"rag\") - title: Article/trial title - url: Source URL - date: Publication date (YYYY-MM-DD or \"Unknown\") - authors: List of authors (optional)

    "},{"location":"api/models/#knowledgegapoutput","title":"KnowledgeGapOutput","text":"

    Module: src.utils.models

    Purpose: Output from knowledge gap evaluation.

    Fields: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    "},{"location":"api/models/#agentselectionplan","title":"AgentSelectionPlan","text":"

    Module: src.utils.models

    Purpose: Plan for tool/agent selection.

    Fields: - tasks: List of agent tasks to execute

    "},{"location":"api/models/#agenttask","title":"AgentTask","text":"

    Module: src.utils.models

    Purpose: Individual agent task.

    Fields: - gap: The knowledge gap being addressed (optional) - agent: Name of agent to use - query: The specific query for the agent - entity_website: The website of the entity being researched, if known (optional)

    "},{"location":"api/models/#reportdraft","title":"ReportDraft","text":"

    Module: src.utils.models

    Purpose: Draft structure for long-form reports.

    Fields: - sections: List of report sections

    "},{"location":"api/models/#reportsection","title":"ReportSection","text":"

    Module: src.utils.models

    Purpose: Individual section in a report draft.

    Fields: - section_title: The title of the section - section_content: The content of the section

    "},{"location":"api/models/#parsedquery","title":"ParsedQuery","text":"

    Module: src.utils.models

    Purpose: Parsed and improved query.

    Fields: - original_query: Original query string - improved_query: Refined query string - research_mode: Research mode (\"iterative\" or \"deep\") - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"api/models/#conversation","title":"Conversation","text":"

    Module: src.utils.models

    Purpose: Conversation history with iterations.

    Fields: - history: List of iteration data

    "},{"location":"api/models/#iterationdata","title":"IterationData","text":"

    Module: src.utils.models

    Purpose: Data for a single iteration.

    Fields: - gap: The gap addressed in the iteration - tool_calls: The tool calls made - findings: The findings collected from tool calls - thought: The thinking done to reflect on the success of the iteration and next steps

    "},{"location":"api/models/#agentevent","title":"AgentEvent","text":"

    Module: src.utils.models

    Purpose: Event emitted during research execution.

    Fields: - type: Event type (e.g., \"started\", \"search_complete\", \"complete\") - iteration: Iteration number (optional) - data: Event data dictionary

    "},{"location":"api/models/#budgetstatus","title":"BudgetStatus","text":"

    Module: src.utils.models

    Purpose: Current budget status.

    Fields: - tokens_used: Total tokens used - tokens_limit: Token budget limit - time_elapsed_seconds: Time elapsed in seconds - time_limit_seconds: Time budget limit (default: 600.0 seconds / 10 minutes) - iterations: Number of iterations completed - iterations_limit: Maximum iterations (default: 10) - iteration_tokens: Tokens used per iteration (iteration number -> token count)

    "},{"location":"api/models/#see-also","title":"See Also","text":""},{"location":"api/orchestrators/","title":"Orchestrators API Reference","text":"

    This page documents the API for DeepCritical orchestrators.

    "},{"location":"api/orchestrators/#iterativeresearchflow","title":"IterativeResearchFlow","text":"

    Module: src.orchestrator.research_flow

    Purpose: Single-loop research with search-judge-synthesize cycles.

    "},{"location":"api/orchestrators/#methods","title":"Methods","text":""},{"location":"api/orchestrators/#run","title":"run","text":"

    Runs iterative research flow.

    Parameters: - query: Research query string - background_context: Background context (default: \"\") - output_length: Optional description of desired output length (default: \"\") - output_instructions: Optional additional instructions for report generation (default: \"\")

    Returns: Final report string.

    Note: max_iterations, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#deepresearchflow","title":"DeepResearchFlow","text":"

    Module: src.orchestrator.research_flow

    Purpose: Multi-section parallel research with planning and synthesis.

    "},{"location":"api/orchestrators/#methods_1","title":"Methods","text":""},{"location":"api/orchestrators/#run_1","title":"run","text":"

    Runs deep research flow.

    Parameters: - query: Research query string

    Returns: Final report string.

    Note: max_iterations_per_section, max_time_minutes, and token_budget are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#graphorchestrator","title":"GraphOrchestrator","text":"

    Module: src.orchestrator.graph_orchestrator

    Purpose: Graph-based execution using Pydantic AI agents as nodes.

    "},{"location":"api/orchestrators/#methods_2","title":"Methods","text":""},{"location":"api/orchestrators/#run_2","title":"run","text":"

    Runs graph-based research orchestration.

    Parameters: - query: Research query string

    Yields: AgentEvent objects during graph execution.

    Note: research_mode and use_graph are constructor parameters, not run() parameters.

    "},{"location":"api/orchestrators/#orchestrator-factory","title":"Orchestrator Factory","text":"

    Module: src.orchestrator_factory

    Purpose: Factory for creating orchestrators.

    "},{"location":"api/orchestrators/#functions","title":"Functions","text":""},{"location":"api/orchestrators/#create_orchestrator","title":"create_orchestrator","text":"

    Creates an orchestrator instance.

    Parameters: - search_handler: Search handler protocol implementation (optional, required for simple mode) - judge_handler: Judge handler protocol implementation (optional, required for simple mode) - config: Configuration object (optional) - mode: Orchestrator mode (\"simple\", \"advanced\", \"magentic\", \"iterative\", \"deep\", \"auto\", or None for auto-detect) - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Returns: Orchestrator instance.

    Raises: - ValueError: If requirements not met

    Modes: - \"simple\": Legacy orchestrator - \"advanced\" or \"magentic\": Magentic orchestrator (requires OpenAI API key) - None: Auto-detect based on API key availability

    "},{"location":"api/orchestrators/#magenticorchestrator","title":"MagenticOrchestrator","text":"

    Module: src.orchestrator_magentic

    Purpose: Multi-agent coordination using Microsoft Agent Framework.

    "},{"location":"api/orchestrators/#methods_3","title":"Methods","text":""},{"location":"api/orchestrators/#run_3","title":"run","text":"

    Runs Magentic orchestration.

    Parameters: - query: Research query string

    Yields: AgentEvent objects converted from Magentic events.

    Note: max_rounds and max_stalls are constructor parameters, not run() parameters.

    Requirements: - agent-framework-core package - OpenAI API key

    "},{"location":"api/orchestrators/#see-also","title":"See Also","text":""},{"location":"api/services/","title":"Services API Reference","text":"

    This page documents the API for DeepCritical services.

    "},{"location":"api/services/#embeddingservice","title":"EmbeddingService","text":"

    Module: src.services.embeddings

    Purpose: Local sentence-transformers for semantic search and deduplication.

    "},{"location":"api/services/#methods","title":"Methods","text":""},{"location":"api/services/#embed","title":"embed","text":"

    Generates embedding for a text string.

    Parameters: - text: Text to embed

    Returns: Embedding vector as list of floats.

    "},{"location":"api/services/#embed_batch","title":"embed_batch","text":"
    async def embed_batch(self, texts: list[str]) -> list[list[float]]\n

    Generates embeddings for multiple texts.

    Parameters: - texts: List of texts to embed

    Returns: List of embedding vectors.

    "},{"location":"api/services/#similarity","title":"similarity","text":"
    async def similarity(self, text1: str, text2: str) -> float\n

    Calculates similarity between two texts.

    Parameters: - text1: First text - text2: Second text

    Returns: Similarity score (0.0-1.0).

    "},{"location":"api/services/#find_duplicates","title":"find_duplicates","text":"
    async def find_duplicates(\n    self,\n    texts: list[str],\n    threshold: float = 0.85\n) -> list[tuple[int, int]]\n

    Finds duplicate texts based on similarity threshold.

    Parameters: - texts: List of texts to check - threshold: Similarity threshold (default: 0.85)

    Returns: List of (index1, index2) tuples for duplicate pairs.

    "},{"location":"api/services/#add_evidence","title":"add_evidence","text":"
    async def add_evidence(\n    self,\n    evidence_id: str,\n    content: str,\n    metadata: dict[str, Any]\n) -> None\n

    Adds evidence to vector store for semantic search.

    Parameters: - evidence_id: Unique identifier for the evidence - content: Evidence text content - metadata: Additional metadata dictionary

    "},{"location":"api/services/#search_similar","title":"search_similar","text":"
    async def search_similar(\n    self,\n    query: str,\n    n_results: int = 5\n) -> list[dict[str, Any]]\n

    Finds semantically similar evidence.

    Parameters: - query: Search query string - n_results: Number of results to return (default: 5)

    Returns: List of dictionaries with id, content, metadata, and distance keys.

    "},{"location":"api/services/#deduplicate","title":"deduplicate","text":"
    async def deduplicate(\n    self,\n    new_evidence: list[Evidence],\n    threshold: float = 0.9\n) -> list[Evidence]\n

    Removes semantically duplicate evidence.

    Parameters: - new_evidence: List of evidence items to deduplicate - threshold: Similarity threshold (default: 0.9, where 0.9 = 90% similar is duplicate)

    Returns: List of unique evidence items (not already in vector store).

    "},{"location":"api/services/#factory-function","title":"Factory Function","text":""},{"location":"api/services/#get_embedding_service","title":"get_embedding_service","text":"
    @lru_cache(maxsize=1)\ndef get_embedding_service() -> EmbeddingService\n

    Returns singleton EmbeddingService instance.

    "},{"location":"api/services/#llamaindexragservice","title":"LlamaIndexRAGService","text":"

    Module: src.services.rag

    Purpose: Retrieval-Augmented Generation using LlamaIndex.

    "},{"location":"api/services/#methods_1","title":"Methods","text":""},{"location":"api/services/#ingest_evidence","title":"ingest_evidence","text":"

    Ingests evidence into RAG service.

    Parameters: - evidence_list: List of Evidence objects to ingest

    Note: Supports multiple embedding providers (OpenAI, local sentence-transformers, Hugging Face).

    "},{"location":"api/services/#retrieve","title":"retrieve","text":"
    def retrieve(\n    self,\n    query: str,\n    top_k: int | None = None\n) -> list[dict[str, Any]]\n

    Retrieves relevant documents for a query.

    Parameters: - query: Search query string - top_k: Number of top results to return (defaults to similarity_top_k from constructor)

    Returns: List of dictionaries with text, score, and metadata keys.

    "},{"location":"api/services/#query","title":"query","text":"
    def query(\n    self,\n    query_str: str,\n    top_k: int | None = None\n) -> str\n

    Queries RAG service and returns synthesized response.

    Parameters: - query_str: Query string - top_k: Number of results to use (defaults to similarity_top_k from constructor)

    Returns: Synthesized response string.

    Raises: - ConfigurationError: If no LLM API key is available for query synthesis

    "},{"location":"api/services/#ingest_documents","title":"ingest_documents","text":"
    def ingest_documents(self, documents: list[Any]) -> None\n

    Ingests raw LlamaIndex Documents.

    Parameters: - documents: List of LlamaIndex Document objects

    "},{"location":"api/services/#clear_collection","title":"clear_collection","text":"
    def clear_collection(self) -> None\n

    Clears all documents from the collection.

    "},{"location":"api/services/#factory-function_1","title":"Factory Function","text":""},{"location":"api/services/#get_rag_service","title":"get_rag_service","text":"
    def get_rag_service(\n    collection_name: str = \"deepcritical_evidence\",\n    oauth_token: str | None = None,\n    **kwargs: Any\n) -> LlamaIndexRAGService\n

    Get or create a RAG service instance.

    Parameters: - collection_name: Name of the ChromaDB collection (default: \"deepcritical_evidence\") - oauth_token: Optional OAuth token from HuggingFace login (takes priority over env vars) - **kwargs: Additional arguments for LlamaIndexRAGService (e.g., use_openai_embeddings=False)

    Returns: Configured LlamaIndexRAGService instance.

    Note: By default, uses local embeddings (sentence-transformers) which require no API keys.

    "},{"location":"api/services/#statisticalanalyzer","title":"StatisticalAnalyzer","text":"

    Module: src.services.statistical_analyzer

    Purpose: Secure execution of AI-generated statistical code.

    "},{"location":"api/services/#methods_2","title":"Methods","text":""},{"location":"api/services/#analyze","title":"analyze","text":"
    async def analyze(\n    self,\n    query: str,\n    evidence: list[Evidence],\n    hypothesis: dict[str, Any] | None = None\n) -> AnalysisResult\n

    Analyzes a research question using statistical methods.

    Parameters: - query: The research question - evidence: List of Evidence objects to analyze - hypothesis: Optional hypothesis dict with drug, target, pathway, effect, confidence keys

    Returns: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - confidence: Confidence in verdict (0.0-1.0) - statistical_evidence: Summary of statistical findings - code_generated: Python code that was executed - execution_output: Output from code execution - key_takeaways: Key takeaways from analysis - limitations: List of limitations

    Note: Requires Modal credentials for sandbox execution.

    "},{"location":"api/services/#see-also","title":"See Also","text":""},{"location":"api/tools/","title":"Tools API Reference","text":"

    This page documents the API for DeepCritical search tools.

    "},{"location":"api/tools/#searchtool-protocol","title":"SearchTool Protocol","text":"

    All tools implement the SearchTool protocol:

    class SearchTool(Protocol):\n    @property\n    def name(self) -> str: ...\n    \n    async def search(\n        self, \n        query: str, \n        max_results: int = 10\n    ) -> list[Evidence]: ...\n
    "},{"location":"api/tools/#pubmedtool","title":"PubMedTool","text":"

    Module: src.tools.pubmed

    Purpose: Search peer-reviewed biomedical literature from PubMed.

    "},{"location":"api/tools/#properties","title":"Properties","text":""},{"location":"api/tools/#name","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"pubmed\"

    "},{"location":"api/tools/#methods","title":"Methods","text":""},{"location":"api/tools/#search","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches PubMed for articles.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with PubMed articles.

    Raises: - SearchError: If search fails (timeout, HTTP error, XML parsing error) - RateLimitError: If rate limit is exceeded (429 status code)

    Note: Uses NCBI E-utilities (ESearch \u2192 EFetch). Rate limit: 0.34s between requests. Handles single vs. multiple articles.

    "},{"location":"api/tools/#clinicaltrialstool","title":"ClinicalTrialsTool","text":"

    Module: src.tools.clinicaltrials

    Purpose: Search ClinicalTrials.gov for interventional studies.

    "},{"location":"api/tools/#properties_1","title":"Properties","text":""},{"location":"api/tools/#name_1","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"clinicaltrials\"

    "},{"location":"api/tools/#methods_1","title":"Methods","text":""},{"location":"api/tools/#search_1","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches ClinicalTrials.gov for trials.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with clinical trials.

    Note: Only returns interventional studies with status: COMPLETED, ACTIVE_NOT_RECRUITING, RECRUITING, ENROLLING_BY_INVITATION. Uses requests library (NOT httpx - WAF blocks httpx). Runs in thread pool for async compatibility.

    Raises: - SearchError: If search fails (HTTP error, request exception)

    "},{"location":"api/tools/#europepmctool","title":"EuropePMCTool","text":"

    Module: src.tools.europepmc

    Purpose: Search Europe PMC for preprints and peer-reviewed articles.

    "},{"location":"api/tools/#properties_2","title":"Properties","text":""},{"location":"api/tools/#name_2","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"europepmc\"

    "},{"location":"api/tools/#methods_2","title":"Methods","text":""},{"location":"api/tools/#search_2","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches Europe PMC for articles and preprints.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects with articles/preprints.

    Note: Includes both preprints (marked with [PREPRINT - Not peer-reviewed]) and peer-reviewed articles. Handles preprint markers. Builds URLs from DOI or PMID.

    Raises: - SearchError: If search fails (HTTP error, connection error)

    "},{"location":"api/tools/#ragtool","title":"RAGTool","text":"

    Module: src.tools.rag_tool

    Purpose: Semantic search within collected evidence.

    "},{"location":"api/tools/#initialization","title":"Initialization","text":"
    def __init__(\n    self,\n    rag_service: LlamaIndexRAGService | None = None,\n    oauth_token: str | None = None\n) -> None\n

    Parameters: - rag_service: Optional RAG service instance. If None, will be lazy-initialized. - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

    "},{"location":"api/tools/#properties_3","title":"Properties","text":""},{"location":"api/tools/#name_3","title":"name","text":"
    @property\ndef name(self) -> str\n

    Returns tool name: \"rag\"

    "},{"location":"api/tools/#methods_3","title":"Methods","text":""},{"location":"api/tools/#search_3","title":"search","text":"
    async def search(\n    self,\n    query: str,\n    max_results: int = 10\n) -> list[Evidence]\n

    Searches collected evidence using semantic similarity.

    Parameters: - query: Search query string - max_results: Maximum number of results to return (default: 10)

    Returns: List of Evidence objects from collected evidence.

    Raises: - ConfigurationError: If RAG service is unavailable

    Note: Requires evidence to be ingested into RAG service first. Wraps LlamaIndexRAGService. Returns Evidence from RAG results.

    "},{"location":"api/tools/#searchhandler","title":"SearchHandler","text":"

    Module: src.tools.search_handler

    Purpose: Orchestrates parallel searches across multiple tools.

    "},{"location":"api/tools/#initialization_1","title":"Initialization","text":"
    def __init__(\n    self,\n    tools: list[SearchTool],\n    timeout: float = 30.0,\n    include_rag: bool = False,\n    auto_ingest_to_rag: bool = True,\n    oauth_token: str | None = None\n) -> None\n

    Parameters: - tools: List of search tools to use - timeout: Timeout for each search in seconds (default: 30.0) - include_rag: Whether to include RAG tool in searches (default: False) - auto_ingest_to_rag: Whether to automatically ingest results into RAG (default: True) - oauth_token: Optional OAuth token from HuggingFace login (for RAG LLM)

    "},{"location":"api/tools/#methods_4","title":"Methods","text":""},{"location":"api/tools/#execute","title":"execute","text":"

    Searches multiple tools in parallel.

    Parameters: - query: Search query string - max_results_per_tool: Maximum results per tool (default: 10)

    Returns: SearchResult with: - query: The search query - evidence: Aggregated list of evidence - sources_searched: List of source names searched - total_found: Total number of results - errors: List of error messages from failed tools

    Raises: - SearchError: If search times out

    Note: Uses asyncio.gather() for parallel execution. Handles tool failures gracefully (returns errors in SearchResult.errors). Automatically ingests evidence into RAG if enabled.

    "},{"location":"api/tools/#see-also","title":"See Also","text":""},{"location":"architecture/agents/","title":"Agents Architecture","text":"

    DeepCritical uses Pydantic AI agents for all AI-powered operations. All agents follow a consistent pattern and use structured output types.

    "},{"location":"architecture/agents/#agent-pattern","title":"Agent Pattern","text":""},{"location":"architecture/agents/#pydantic-ai-agents","title":"Pydantic AI Agents","text":"

    Pydantic AI agents use the Agent class with the following structure:

    Note: Factory functions accept an optional oauth_token parameter for HuggingFace authentication, which takes priority over environment variables.

    "},{"location":"architecture/agents/#model-initialization","title":"Model Initialization","text":"

    Agents use get_model() from src/agent_factory/judges.py if no model is provided. This supports:

    The model selection is based on the configured LLM_PROVIDER in settings.

    "},{"location":"architecture/agents/#error-handling","title":"Error Handling","text":"

    Agents return fallback values on failure rather than raising exceptions:

    All errors are logged with context using structlog.

    "},{"location":"architecture/agents/#input-validation","title":"Input Validation","text":"

    All agents validate inputs:

    "},{"location":"architecture/agents/#output-types","title":"Output Types","text":"

    Agents use structured output types from src/utils/models.py:

    For text output (writer agents), agents return str directly.

    "},{"location":"architecture/agents/#agent-types","title":"Agent Types","text":""},{"location":"architecture/agents/#knowledge-gap-agent","title":"Knowledge Gap Agent","text":"

    File: src/agents/knowledge_gap.py

    Purpose: Evaluates research state and identifies knowledge gaps.

    Output: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps

    Methods: - async def evaluate(query, background_context, conversation_history, iteration, time_elapsed_minutes, max_time_minutes) -> KnowledgeGapOutput

    "},{"location":"architecture/agents/#tool-selector-agent","title":"Tool Selector Agent","text":"

    File: src/agents/tool_selector.py

    Purpose: Selects appropriate tools for addressing knowledge gaps.

    Output: AgentSelectionPlan with list of AgentTask objects.

    Available Agents: - WebSearchAgent: General web search for fresh information - SiteCrawlerAgent: Research specific entities/companies - RAGAgent: Semantic search within collected evidence

    "},{"location":"architecture/agents/#writer-agent","title":"Writer Agent","text":"

    File: src/agents/writer.py

    Purpose: Generates final reports from research findings.

    Output: Markdown string with numbered citations.

    Methods: - async def write_report(query, findings, output_length, output_instructions) -> str

    Features: - Validates inputs - Truncates very long findings (max 50000 chars) with warning - Retry logic for transient failures (3 retries) - Citation validation before returning

    "},{"location":"architecture/agents/#long-writer-agent","title":"Long Writer Agent","text":"

    File: src/agents/long_writer.py

    Purpose: Long-form report generation with section-by-section writing.

    Input/Output: Uses ReportDraft models.

    Methods: - async def write_next_section(query, draft, section_title, section_content) -> LongWriterOutput - async def write_report(query, report_title, report_draft) -> str

    Features: - Writes sections iteratively - Aggregates references across sections - Reformats section headings and references - Deduplicates and renumbers references

    "},{"location":"architecture/agents/#proofreader-agent","title":"Proofreader Agent","text":"

    File: src/agents/proofreader.py

    Purpose: Proofreads and polishes report drafts.

    Input: ReportDraft Output: Polished markdown string

    Methods: - async def proofread(query, report_title, report_draft) -> str

    Features: - Removes duplicate content across sections - Adds executive summary if multiple sections - Preserves all references and citations - Improves flow and readability

    "},{"location":"architecture/agents/#thinking-agent","title":"Thinking Agent","text":"

    File: src/agents/thinking.py

    Purpose: Generates observations from conversation history.

    Output: Observation string

    Methods: - async def generate_observations(query, background_context, conversation_history) -> str

    "},{"location":"architecture/agents/#input-parser-agent","title":"Input Parser Agent","text":"

    File: src/agents/input_parser.py

    Purpose: Parses and improves user queries, detects research mode.

    Output: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: \"iterative\" or \"deep\" - key_entities: List of key entities - research_questions: List of research questions

    "},{"location":"architecture/agents/#magentic-agents","title":"Magentic Agents","text":"

    The following agents use the BaseAgent pattern from agent-framework and are used exclusively with MagenticOrchestrator:

    "},{"location":"architecture/agents/#hypothesis-agent","title":"Hypothesis Agent","text":"

    File: src/agents/hypothesis_agent.py

    Purpose: Generates mechanistic hypotheses based on evidence.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Uses internal Pydantic AI Agent with HypothesisAssessment output type - Accesses shared evidence_store for evidence - Uses embedding service for diverse evidence selection (MMR algorithm) - Stores hypotheses in shared context

    "},{"location":"architecture/agents/#search-agent","title":"Search Agent","text":"

    File: src/agents/search_agent.py

    Purpose: Wraps SearchHandler as an agent for Magentic orchestrator.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Executes searches via SearchHandlerProtocol - Deduplicates evidence using embedding service - Searches for semantically related evidence - Updates shared evidence store

    "},{"location":"architecture/agents/#analysis-agent","title":"Analysis Agent","text":"

    File: src/agents/analysis_agent.py

    Purpose: Performs statistical analysis using Modal sandbox.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Wraps StatisticalAnalyzer service - Analyzes evidence and hypotheses - Returns verdict (SUPPORTED/REFUTED/INCONCLUSIVE) - Stores analysis results in shared context

    "},{"location":"architecture/agents/#report-agent-magentic","title":"Report Agent (Magentic)","text":"

    File: src/agents/report_agent.py

    Purpose: Generates structured scientific reports from evidence and hypotheses.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse

    Features: - Uses internal Pydantic AI Agent with ResearchReport output type - Accesses shared evidence store and hypotheses - Validates citations before returning - Formats report as markdown

    "},{"location":"architecture/agents/#judge-agent","title":"Judge Agent","text":"

    File: src/agents/judge_agent.py

    Purpose: Evaluates evidence quality and determines if sufficient for synthesis.

    Pattern: BaseAgent from agent-framework

    Methods: - async def run(messages, thread, **kwargs) -> AgentRunResponse - async def run_stream(messages, thread, **kwargs) -> AsyncIterable[AgentRunResponseUpdate]

    Features: - Wraps JudgeHandlerProtocol - Accesses shared evidence store - Returns JudgeAssessment with sufficient flag, confidence, and recommendation

    "},{"location":"architecture/agents/#agent-patterns","title":"Agent Patterns","text":"

    DeepCritical uses two distinct agent patterns:

    "},{"location":"architecture/agents/#1-pydantic-ai-agents-traditional-pattern","title":"1. Pydantic AI Agents (Traditional Pattern)","text":"

    These agents use the Pydantic AI Agent class directly and are used in iterative and deep research flows:

    "},{"location":"architecture/agents/#2-magentic-agents-agent-framework-pattern","title":"2. Magentic Agents (Agent-Framework Pattern)","text":"

    These agents use the BaseAgent class from agent-framework and are used in Magentic orchestrator:

    Note: Magentic agents are used exclusively with the MagenticOrchestrator and follow the agent-framework protocol for multi-agent coordination.

    "},{"location":"architecture/agents/#factory-functions","title":"Factory Functions","text":"

    All agents have factory functions in src/agent_factory/agents.py:

    Factory functions: - Use get_model() if no model provided - Accept oauth_token parameter for HuggingFace authentication - Raise ConfigurationError if creation fails - Log agent creation

    "},{"location":"architecture/agents/#see-also","title":"See Also","text":""},{"location":"architecture/graph_orchestration/","title":"Graph Orchestration Architecture","text":""},{"location":"architecture/graph_orchestration/#overview","title":"Overview","text":"

    DeepCritical implements a graph-based orchestration system for research workflows using Pydantic AI agents as nodes. This enables better parallel execution, conditional routing, and state management compared to simple agent chains.

    "},{"location":"architecture/graph_orchestration/#graph-patterns","title":"Graph Patterns","text":""},{"location":"architecture/graph_orchestration/#iterative-research-graph","title":"Iterative Research Graph","text":"

    The iterative research graph follows this pattern:

    [Input] \u2192 [Thinking] \u2192 [Knowledge Gap] \u2192 [Decision: Complete?]\n                                              \u2193 No          \u2193 Yes\n                                    [Tool Selector]    [Writer]\n                                              \u2193\n                                    [Execute Tools] \u2192 [Loop Back]\n

    Node IDs: thinking \u2192 knowledge_gap \u2192 continue_decision \u2192 tool_selector/writer \u2192 execute_tools \u2192 (loop back to thinking)

    Special Node Handling: - execute_tools: State node that uses search_handler to execute searches and add evidence to workflow state - continue_decision: Decision node that routes based on research_complete flag from KnowledgeGapOutput

    "},{"location":"architecture/graph_orchestration/#deep-research-graph","title":"Deep Research Graph","text":"

    The deep research graph follows this pattern:

    [Input] \u2192 [Planner] \u2192 [Store Plan] \u2192 [Parallel Loops] \u2192 [Collect Drafts] \u2192 [Synthesizer]\n                                        \u2193         \u2193         \u2193\n                                     [Loop1]  [Loop2]  [Loop3]\n

    Node IDs: planner \u2192 store_plan \u2192 parallel_loops \u2192 collect_drafts \u2192 synthesizer

    Special Node Handling: - planner: Agent node that creates ReportPlan with report outline - store_plan: State node that stores ReportPlan in context for parallel loops - parallel_loops: Parallel node that executes IterativeResearchFlow instances for each section - collect_drafts: State node that collects section drafts from parallel loops - synthesizer: Agent node that calls LongWriterAgent.write_report() directly with ReportDraft

    "},{"location":"architecture/graph_orchestration/#deep-research","title":"Deep Research","text":"
    \nsequenceDiagram\n    actor User\n    participant GraphOrchestrator\n    participant InputParser\n    participant GraphBuilder\n    participant GraphExecutor\n    participant Agent\n    participant BudgetTracker\n    participant WorkflowState\n\n    User->>GraphOrchestrator: run(query)\n    GraphOrchestrator->>InputParser: detect_research_mode(query)\n    InputParser-->>GraphOrchestrator: mode (iterative/deep)\n    GraphOrchestrator->>GraphBuilder: build_graph(mode)\n    GraphBuilder-->>GraphOrchestrator: ResearchGraph\n    GraphOrchestrator->>WorkflowState: init_workflow_state()\n    GraphOrchestrator->>BudgetTracker: create_budget()\n    GraphOrchestrator->>GraphExecutor: _execute_graph(graph)\n    \n    loop For each node in graph\n        GraphExecutor->>Agent: execute_node(agent_node)\n        Agent->>Agent: process_input\n        Agent-->>GraphExecutor: result\n        GraphExecutor->>WorkflowState: update_state(result)\n        GraphExecutor->>BudgetTracker: add_tokens(used)\n        GraphExecutor->>BudgetTracker: check_budget()\n        alt Budget exceeded\n            GraphExecutor->>GraphOrchestrator: emit(error_event)\n        else Continue\n            GraphExecutor->>GraphOrchestrator: emit(progress_event)\n        end\n    end\n    \n    GraphOrchestrator->>User: AsyncGenerator[AgentEvent]\n
    "},{"location":"architecture/graph_orchestration/#iterative-research","title":"Iterative Research","text":"
    sequenceDiagram\n    participant IterativeFlow\n    participant ThinkingAgent\n    participant KnowledgeGapAgent\n    participant ToolSelector\n    participant ToolExecutor\n    participant JudgeHandler\n    participant WriterAgent\n\n    IterativeFlow->>IterativeFlow: run(query)\n    \n    loop Until complete or max_iterations\n        IterativeFlow->>ThinkingAgent: generate_observations()\n        ThinkingAgent-->>IterativeFlow: observations\n        \n        IterativeFlow->>KnowledgeGapAgent: evaluate_gaps()\n        KnowledgeGapAgent-->>IterativeFlow: KnowledgeGapOutput\n        \n        alt Research complete\n            IterativeFlow->>WriterAgent: create_final_report()\n            WriterAgent-->>IterativeFlow: final_report\n        else Gaps remain\n            IterativeFlow->>ToolSelector: select_agents(gap)\n            ToolSelector-->>IterativeFlow: AgentSelectionPlan\n            \n            IterativeFlow->>ToolExecutor: execute_tool_tasks()\n            ToolExecutor-->>IterativeFlow: ToolAgentOutput[]\n            \n            IterativeFlow->>JudgeHandler: assess_evidence()\n            JudgeHandler-->>IterativeFlow: should_continue\n        end\n    end
    "},{"location":"architecture/graph_orchestration/#graph-structure","title":"Graph Structure","text":""},{"location":"architecture/graph_orchestration/#nodes","title":"Nodes","text":"

    Graph nodes represent different stages in the research workflow:

    1. Agent Nodes: Execute Pydantic AI agents
    2. Input: Prompt/query
    3. Output: Structured or unstructured response
    4. Examples: KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent

    5. State Nodes: Update or read workflow state

    6. Input: Current state
    7. Output: Updated state
    8. Examples: Update evidence, update conversation history

    9. Decision Nodes: Make routing decisions based on conditions

    10. Input: Current state/results
    11. Output: Next node ID
    12. Examples: Continue research vs. complete research

    13. Parallel Nodes: Execute multiple nodes concurrently

    14. Input: List of node IDs
    15. Output: Aggregated results
    16. Examples: Parallel iterative research loops
    "},{"location":"architecture/graph_orchestration/#edges","title":"Edges","text":"

    Edges define transitions between nodes:

    1. Sequential Edges: Always traversed (no condition)
    2. From: Source node
    3. To: Target node
    4. Condition: None (always True)

    5. Conditional Edges: Traversed based on condition

    6. From: Source node
    7. To: Target node
    8. Condition: Callable that returns bool
    9. Example: If research complete \u2192 go to writer, else \u2192 continue loop

    10. Parallel Edges: Used for parallel execution branches

    11. From: Parallel node
    12. To: Multiple target nodes
    13. Execution: All targets run concurrently
    "},{"location":"architecture/graph_orchestration/#state-management","title":"State Management","text":"

    State is managed via WorkflowState using ContextVar for thread-safe isolation:

    State transitions occur at state nodes, which update the global workflow state.

    "},{"location":"architecture/graph_orchestration/#execution-flow","title":"Execution Flow","text":"
    1. Graph Construction: Build graph from nodes and edges using create_iterative_graph() or create_deep_graph()
    2. Graph Validation: Ensure graph is valid (no cycles, all nodes reachable) via ResearchGraph.validate_structure()
    3. Graph Execution: Traverse graph from entry node using GraphOrchestrator._execute_graph()
    4. Node Execution: Execute each node based on type:
    5. Agent Nodes: Call agent.run() with transformed input
    6. State Nodes: Update workflow state via state_updater function
    7. Decision Nodes: Evaluate decision_function to get next node ID
    8. Parallel Nodes: Execute all parallel nodes concurrently via asyncio.gather()
    9. Edge Evaluation: Determine next node(s) based on edges and conditions
    10. Parallel Execution: Use asyncio.gather() for parallel nodes
    11. State Updates: Update state at state nodes via GraphExecutionContext.update_state()
    12. Event Streaming: Yield AgentEvent objects during execution for UI
    "},{"location":"architecture/graph_orchestration/#graphexecutioncontext","title":"GraphExecutionContext","text":"

    The GraphExecutionContext class manages execution state during graph traversal:

    Methods: - set_node_result(node_id, result): Store result from node execution - get_node_result(node_id): Retrieve stored result - has_visited(node_id): Check if node was visited - mark_visited(node_id): Mark node as visited - update_state(updater, data): Update workflow state

    "},{"location":"architecture/graph_orchestration/#conditional-routing","title":"Conditional Routing","text":"

    Decision nodes evaluate conditions and return next node IDs:

    "},{"location":"architecture/graph_orchestration/#parallel-execution","title":"Parallel Execution","text":"

    Parallel nodes execute multiple nodes concurrently:

    "},{"location":"architecture/graph_orchestration/#budget-enforcement","title":"Budget Enforcement","text":"

    Budget constraints are enforced at decision nodes:

    If any budget is exceeded, execution routes to exit node.

    "},{"location":"architecture/graph_orchestration/#error-handling","title":"Error Handling","text":"

    Errors are handled at multiple levels:

    1. Node Level: Catch errors in individual node execution
    2. Graph Level: Handle errors during graph traversal
    3. State Level: Rollback state changes on error

    Errors are logged and yield error events for UI.

    "},{"location":"architecture/graph_orchestration/#backward-compatibility","title":"Backward Compatibility","text":"

    Graph execution is optional via feature flag:

    This allows gradual migration and fallback if needed.

    "},{"location":"architecture/graph_orchestration/#see-also","title":"See Also","text":""},{"location":"architecture/middleware/","title":"Middleware Architecture","text":"

    DeepCritical uses middleware for state management, budget tracking, and workflow coordination.

    "},{"location":"architecture/middleware/#state-management","title":"State Management","text":""},{"location":"architecture/middleware/#workflowstate","title":"WorkflowState","text":"

    File: src/middleware/state_machine.py

    Purpose: Thread-safe state management for research workflows

    Implementation: Uses ContextVar for thread-safe isolation

    State Components: - evidence: list[Evidence]: Collected evidence from searches - conversation: Conversation: Iteration history (gaps, tool calls, findings, thoughts) - embedding_service: Any: Embedding service for semantic search

    Methods: - add_evidence(new_evidence: list[Evidence]) -> int: Adds evidence with URL-based deduplication. Returns the number of new items added (excluding duplicates). - async search_related(query: str, n_results: int = 5) -> list[Evidence]: Semantic search for related evidence using embedding service

    Initialization:

    Access:

    "},{"location":"architecture/middleware/#workflow-manager","title":"Workflow Manager","text":"

    File: src/middleware/workflow_manager.py

    Purpose: Coordinates parallel research loops

    Methods: - async add_loop(loop_id: str, query: str) -> ResearchLoop: Add a new research loop to manage - async run_loops_parallel(loop_configs: list[dict], loop_func: Callable, judge_handler: Any | None = None, budget_tracker: Any | None = None) -> list[Any]: Run multiple research loops in parallel. Takes configuration dicts and a loop function. - async update_loop_status(loop_id: str, status: LoopStatus, error: str | None = None): Update loop status - async sync_loop_evidence_to_state(loop_id: str): Synchronize evidence from a specific loop to global state

    Features: - Uses asyncio.gather() for parallel execution - Handles errors per loop (doesn't fail all if one fails) - Tracks loop status: pending, running, completed, failed, cancelled - Evidence deduplication across parallel loops

    Usage:

    from src.middleware.workflow_manager import WorkflowManager\n\nmanager = WorkflowManager()\nawait manager.add_loop(\"loop1\", \"Research query 1\")\nawait manager.add_loop(\"loop2\", \"Research query 2\")\n\nasync def run_research(config: dict) -> str:\n    loop_id = config[\"loop_id\"]\n    query = config[\"query\"]\n    # ... research logic ...\n    return \"report\"\n\nresults = await manager.run_loops_parallel(\n    loop_configs=[\n        {\"loop_id\": \"loop1\", \"query\": \"Research query 1\"},\n        {\"loop_id\": \"loop2\", \"query\": \"Research query 2\"},\n    ],\n    loop_func=run_research,\n)\n

    "},{"location":"architecture/middleware/#budget-tracker","title":"Budget Tracker","text":"

    File: src/middleware/budget_tracker.py

    Purpose: Tracks and enforces resource limits

    Budget Components: - Tokens: LLM token usage - Time: Elapsed time in seconds - Iterations: Number of iterations

    Methods: - create_budget(loop_id: str, tokens_limit: int = 100000, time_limit_seconds: float = 600.0, iterations_limit: int = 10) -> BudgetStatus: Create a budget for a specific loop - add_tokens(loop_id: str, tokens: int): Add token usage to a loop's budget - start_timer(loop_id: str): Start time tracking for a loop - update_timer(loop_id: str): Update elapsed time for a loop - increment_iteration(loop_id: str): Increment iteration count for a loop - check_budget(loop_id: str) -> tuple[bool, str]: Check if a loop's budget has been exceeded. Returns (exceeded: bool, reason: str) - can_continue(loop_id: str) -> bool: Check if a loop can continue based on budget

    Token Estimation: - estimate_tokens(text: str) -> int: ~4 chars per token - estimate_llm_call_tokens(prompt: str, response: str) -> int: Estimate LLM call tokens

    Usage:

    from src.middleware.budget_tracker import BudgetTracker\n\ntracker = BudgetTracker()\nbudget = tracker.create_budget(\n    loop_id=\"research_loop\",\n    tokens_limit=100000,\n    time_limit_seconds=600,\n    iterations_limit=10\n)\ntracker.start_timer(\"research_loop\")\n# ... research operations ...\ntracker.add_tokens(\"research_loop\", 5000)\ntracker.update_timer(\"research_loop\")\nexceeded, reason = tracker.check_budget(\"research_loop\")\nif exceeded:\n    # Budget exceeded, stop research\n    pass\nif not tracker.can_continue(\"research_loop\"):\n    # Budget exceeded, stop research\n    pass\n

    "},{"location":"architecture/middleware/#models","title":"Models","text":"

    All middleware models are defined in src/utils/models.py:

    "},{"location":"architecture/middleware/#thread-safety","title":"Thread Safety","text":"

    All middleware components use ContextVar for thread-safe isolation:

    "},{"location":"architecture/middleware/#see-also","title":"See Also","text":""},{"location":"architecture/orchestrators/","title":"Orchestrators Architecture","text":"

    DeepCritical supports multiple orchestration patterns for research workflows.

    "},{"location":"architecture/orchestrators/#research-flows","title":"Research Flows","text":""},{"location":"architecture/orchestrators/#iterativeresearchflow","title":"IterativeResearchFlow","text":"

    File: src/orchestrator/research_flow.py

    Pattern: Generate observations \u2192 Evaluate gaps \u2192 Select tools \u2192 Execute \u2192 Judge \u2192 Continue/Complete

    Agents Used: - KnowledgeGapAgent: Evaluates research completeness - ToolSelectorAgent: Selects tools for addressing gaps - ThinkingAgent: Generates observations - WriterAgent: Creates final report - JudgeHandler: Assesses evidence sufficiency

    Features: - Tracks iterations, time, budget - Supports graph execution (use_graph=True) and agent chains (use_graph=False) - Iterates until research complete or constraints met

    Usage:

    "},{"location":"architecture/orchestrators/#deepresearchflow","title":"DeepResearchFlow","text":"

    File: src/orchestrator/research_flow.py

    Pattern: Planner \u2192 Parallel iterative loops per section \u2192 Synthesizer

    Agents Used: - PlannerAgent: Breaks query into report sections - IterativeResearchFlow: Per-section research (parallel) - LongWriterAgent or ProofreaderAgent: Final synthesis

    Features: - Uses WorkflowManager for parallel execution - Budget tracking per section and globally - State synchronization across parallel loops - Supports graph execution and agent chains

    Usage:

    "},{"location":"architecture/orchestrators/#graph-orchestrator","title":"Graph Orchestrator","text":"

    File: src/orchestrator/graph_orchestrator.py

    Purpose: Graph-based execution using Pydantic AI agents as nodes

    Features: - Uses graph execution (use_graph=True) or agent chains (use_graph=False) as fallback - Routes based on research mode (iterative/deep/auto) - Streams AgentEvent objects for UI - Uses GraphExecutionContext to manage execution state

    Node Types: - Agent Nodes: Execute Pydantic AI agents - State Nodes: Update or read workflow state - Decision Nodes: Make routing decisions - Parallel Nodes: Execute multiple nodes concurrently

    Edge Types: - Sequential Edges: Always traversed - Conditional Edges: Traversed based on condition - Parallel Edges: Used for parallel execution branches

    Special Node Handling:

    The GraphOrchestrator has special handling for certain nodes:

    GraphExecutionContext:

    The orchestrator uses GraphExecutionContext to manage execution state: - Tracks current node, visited nodes, and node results - Manages workflow state and budget tracker - Provides methods to store and retrieve node execution results

    "},{"location":"architecture/orchestrators/#orchestrator-factory","title":"Orchestrator Factory","text":"

    File: src/orchestrator_factory.py

    Purpose: Factory for creating orchestrators

    Modes: - Simple: Legacy orchestrator (backward compatible) - Advanced: Magentic orchestrator (requires OpenAI API key) - Auto-detect: Chooses based on API key availability

    Usage:

    "},{"location":"architecture/orchestrators/#magentic-orchestrator","title":"Magentic Orchestrator","text":"

    File: src/orchestrator_magentic.py

    Purpose: Multi-agent coordination using Microsoft Agent Framework

    Features: - Uses agent-framework-core - ChatAgent pattern with internal LLMs per agent - MagenticBuilder with participants: - searcher: SearchAgent (wraps SearchHandler) - hypothesizer: HypothesisAgent (generates hypotheses) - judge: JudgeAgent (evaluates evidence) - reporter: ReportAgent (generates final report) - Manager orchestrates agents via chat client (OpenAI or HuggingFace) - Event-driven: converts Magentic events to AgentEvent for UI streaming via _process_event() method - Supports max rounds, stall detection, and reset handling

    Event Processing:

    The orchestrator processes Magentic events and converts them to AgentEvent: - MagenticOrchestratorMessageEvent \u2192 AgentEvent with type based on message content - MagenticAgentMessageEvent \u2192 AgentEvent with type based on agent name - MagenticAgentDeltaEvent \u2192 AgentEvent for streaming updates - MagenticFinalResultEvent \u2192 AgentEvent with type \"complete\"

    Requirements: - agent-framework-core package - OpenAI API key or HuggingFace authentication

    "},{"location":"architecture/orchestrators/#hierarchical-orchestrator","title":"Hierarchical Orchestrator","text":"

    File: src/orchestrator_hierarchical.py

    Purpose: Hierarchical orchestrator using middleware and sub-teams

    Features: - Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge - Adapts Magentic ChatAgent to SubIterationTeam protocol - Event-driven via asyncio.Queue for coordination - Supports sub-iteration patterns for complex research tasks

    "},{"location":"architecture/orchestrators/#legacy-simple-mode","title":"Legacy Simple Mode","text":"

    File: src/legacy_orchestrator.py

    Purpose: Linear search-judge-synthesize loop

    Features: - Uses SearchHandlerProtocol and JudgeHandlerProtocol - Generator-based design yielding AgentEvent objects - Backward compatibility for simple use cases

    "},{"location":"architecture/orchestrators/#state-initialization","title":"State Initialization","text":"

    All orchestrators must initialize workflow state:

    "},{"location":"architecture/orchestrators/#event-streaming","title":"Event Streaming","text":"

    All orchestrators yield AgentEvent objects:

    Event Types: - started: Research started - searching: Search in progress - search_complete: Search completed - judging: Evidence evaluation in progress - judge_complete: Evidence evaluation completed - looping: Iteration in progress - hypothesizing: Generating hypotheses - analyzing: Statistical analysis in progress - analysis_complete: Statistical analysis completed - synthesizing: Synthesizing results - complete: Research completed - error: Error occurred - streaming: Streaming update (delta events)

    Event Structure:

    "},{"location":"architecture/orchestrators/#see-also","title":"See Also","text":""},{"location":"architecture/services/","title":"Services Architecture","text":"

    DeepCritical provides several services for embeddings, RAG, and statistical analysis.

    "},{"location":"architecture/services/#embedding-service","title":"Embedding Service","text":"

    File: src/services/embeddings.py

    Purpose: Local sentence-transformers for semantic search and deduplication

    Features: - No API Key Required: Uses local sentence-transformers models - Async-Safe: All operations use run_in_executor() to avoid blocking the event loop - ChromaDB Storage: In-memory vector storage for embeddings - Deduplication: 0.9 similarity threshold by default (90% similarity = duplicate, configurable)

    Model: Configurable via settings.local_embedding_model (default: all-MiniLM-L6-v2)

    Methods: - async def embed(text: str) -> list[float]: Generate embeddings (async-safe via run_in_executor()) - async def embed_batch(texts: list[str]) -> list[list[float]]: Batch embedding (more efficient) - async def add_evidence(evidence_id: str, content: str, metadata: dict[str, Any]) -> None: Add evidence to vector store - async def search_similar(query: str, n_results: int = 5) -> list[dict[str, Any]]: Find semantically similar evidence - async def deduplicate(new_evidence: list[Evidence], threshold: float = 0.9) -> list[Evidence]: Remove semantically duplicate evidence

    Usage:

    from src.services.embeddings import get_embedding_service\n\nservice = get_embedding_service()\nembedding = await service.embed(\"text to embed\")\n

    "},{"location":"architecture/services/#llamaindex-rag-service","title":"LlamaIndex RAG Service","text":"

    File: src/services/llamaindex_rag.py

    Purpose: Retrieval-Augmented Generation using LlamaIndex

    Features: - Multiple Embedding Providers: OpenAI embeddings (requires OPENAI_API_KEY) or local sentence-transformers (no API key) - Multiple LLM Providers: HuggingFace LLM (preferred) or OpenAI LLM (fallback) for query synthesis - ChromaDB Storage: Vector database for document storage (supports in-memory mode) - Metadata Preservation: Preserves source, title, URL, date, authors - Lazy Initialization: Graceful fallback if dependencies not available

    Initialization Parameters: - use_openai_embeddings: bool | None: Force OpenAI embeddings (None = auto-detect) - use_in_memory: bool: Use in-memory ChromaDB client (useful for tests) - oauth_token: str | None: Optional OAuth token from HuggingFace login (takes priority over env vars)

    Methods: - async def ingest_evidence(evidence: list[Evidence]) -> None: Ingest evidence into RAG - async def retrieve(query: str, top_k: int = 5) -> list[Document]: Retrieve relevant documents - async def query(query: str, top_k: int = 5) -> str: Query with RAG

    Usage:

    from src.services.llamaindex_rag import get_rag_service\n\nservice = get_rag_service(\n    use_openai_embeddings=False,  # Use local embeddings\n    use_in_memory=True,  # Use in-memory ChromaDB\n    oauth_token=token  # Optional HuggingFace token\n)\nif service:\n    documents = await service.retrieve(\"query\", top_k=5)\n

    "},{"location":"architecture/services/#statistical-analyzer","title":"Statistical Analyzer","text":"

    File: src/services/statistical_analyzer.py

    Purpose: Secure execution of AI-generated statistical code

    Features: - Modal Sandbox: Secure, isolated execution environment - Code Generation: Generates Python code via LLM - Library Pinning: Version-pinned libraries in SANDBOX_LIBRARIES - Network Isolation: block_network=True by default

    Libraries Available: - pandas, numpy, scipy - matplotlib, scikit-learn - statsmodels

    Output: AnalysisResult with: - verdict: SUPPORTED, REFUTED, or INCONCLUSIVE - code: Generated analysis code - output: Execution output - error: Error message if execution failed

    Usage:

    from src.services.statistical_analyzer import StatisticalAnalyzer\n\nanalyzer = StatisticalAnalyzer()\nresult = await analyzer.analyze(\n    hypothesis=\"Metformin reduces cancer risk\",\n    evidence=evidence_list\n)\n

    "},{"location":"architecture/services/#singleton-pattern","title":"Singleton Pattern","text":"

    Services use singleton patterns for lazy initialization:

    EmbeddingService: Uses a global variable pattern:

    LlamaIndexRAGService: Direct instantiation (no caching):

    This ensures: - Single instance per process - Lazy initialization - No dependencies required at import time

    "},{"location":"architecture/services/#service-availability","title":"Service Availability","text":"

    Services check availability before use:

    from src.utils.config import settings\n\nif settings.modal_available:\n    # Use Modal sandbox\n    pass\n\nif settings.has_openai_key:\n    # Use OpenAI embeddings for RAG\n    pass\n
    "},{"location":"architecture/services/#see-also","title":"See Also","text":""},{"location":"architecture/tools/","title":"Tools Architecture","text":"

    DeepCritical implements a protocol-based search tool system for retrieving evidence from multiple sources.

    "},{"location":"architecture/tools/#searchtool-protocol","title":"SearchTool Protocol","text":"

    All tools implement the SearchTool protocol from src/tools/base.py:

    "},{"location":"architecture/tools/#rate-limiting","title":"Rate Limiting","text":"

    All tools use the @retry decorator from tenacity:

    Tools with API rate limits implement _rate_limit() method and use shared rate limiters from src/tools/rate_limiter.py.

    "},{"location":"architecture/tools/#error-handling","title":"Error Handling","text":"

    Tools raise custom exceptions:

    Tools handle HTTP errors (429, 500, timeout) and return empty lists on non-critical errors (with warning logs).

    "},{"location":"architecture/tools/#query-preprocessing","title":"Query Preprocessing","text":"

    Tools use preprocess_query() from src/tools/query_utils.py to:

    "},{"location":"architecture/tools/#evidence-conversion","title":"Evidence Conversion","text":"

    All tools convert API responses to Evidence objects with:

    Missing fields are handled gracefully with defaults.

    "},{"location":"architecture/tools/#tool-implementations","title":"Tool Implementations","text":""},{"location":"architecture/tools/#pubmed-tool","title":"PubMed Tool","text":"

    File: src/tools/pubmed.py

    API: NCBI E-utilities (ESearch \u2192 EFetch)

    Rate Limiting: - 0.34s between requests (3 req/sec without API key) - 0.1s between requests (10 req/sec with NCBI API key)

    Features: - XML parsing with xmltodict - Handles single vs. multiple articles - Query preprocessing - Evidence conversion with metadata extraction

    "},{"location":"architecture/tools/#clinicaltrials-tool","title":"ClinicalTrials Tool","text":"

    File: src/tools/clinicaltrials.py

    API: ClinicalTrials.gov API v2

    Important: Uses requests library (NOT httpx) because WAF blocks httpx TLS fingerprint.

    Execution: Runs in thread pool: await asyncio.to_thread(requests.get, ...)

    Filtering: - Only interventional studies - Status: COMPLETED, ACTIVE_NOT_RECRUITING, RECRUITING, ENROLLING_BY_INVITATION

    Features: - Parses nested JSON structure - Extracts trial metadata - Evidence conversion

    "},{"location":"architecture/tools/#europe-pmc-tool","title":"Europe PMC Tool","text":"

    File: src/tools/europepmc.py

    API: Europe PMC REST API

    Features: - Handles preprint markers: [PREPRINT - Not peer-reviewed] - Builds URLs from DOI or PMID - Checks pubTypeList for preprint detection - Includes both preprints and peer-reviewed articles

    "},{"location":"architecture/tools/#rag-tool","title":"RAG Tool","text":"

    File: src/tools/rag_tool.py

    Purpose: Semantic search within collected evidence

    Implementation: Wraps LlamaIndexRAGService

    Features: - Returns Evidence from RAG results - Handles evidence ingestion - Semantic similarity search - Metadata preservation

    "},{"location":"architecture/tools/#search-handler","title":"Search Handler","text":"

    File: src/tools/search_handler.py

    Purpose: Orchestrates parallel searches across multiple tools

    Initialization Parameters: - tools: list[SearchTool]: List of search tools to use - timeout: float = 30.0: Timeout for each search in seconds - include_rag: bool = False: Whether to include RAG tool in searches - auto_ingest_to_rag: bool = True: Whether to automatically ingest results into RAG - oauth_token: str | None = None: Optional OAuth token from HuggingFace login (for RAG LLM)

    Methods: - async def execute(query: str, max_results_per_tool: int = 10) -> SearchResult: Execute search across all tools in parallel

    Features: - Uses asyncio.gather() with return_exceptions=True for parallel execution - Aggregates results into SearchResult with evidence and metadata - Handles tool failures gracefully (continues with other tools) - Deduplicates results by URL - Automatically ingests results into RAG if auto_ingest_to_rag=True - Can add RAG tool dynamically via add_rag_tool() method

    "},{"location":"architecture/tools/#tool-registration","title":"Tool Registration","text":"

    Tools are registered in the search handler:

    from src.tools.pubmed import PubMedTool\nfrom src.tools.clinicaltrials import ClinicalTrialsTool\nfrom src.tools.europepmc import EuropePMCTool\nfrom src.tools.search_handler import SearchHandler\n\nsearch_handler = SearchHandler(\n    tools=[\n        PubMedTool(),\n        ClinicalTrialsTool(),\n        EuropePMCTool(),\n    ],\n    include_rag=True,  # Include RAG tool for semantic search\n    auto_ingest_to_rag=True,  # Automatically ingest results into RAG\n    oauth_token=token  # Optional HuggingFace token for RAG LLM\n)\n\n# Execute search\nresult = await search_handler.execute(\"query\", max_results_per_tool=10)\n
    "},{"location":"architecture/tools/#see-also","title":"See Also","text":""},{"location":"architecture/workflow-diagrams/","title":"DeepCritical Workflow - Simplified Magentic Architecture","text":"

    Architecture Pattern: Microsoft Magentic Orchestration Design Philosophy: Simple, dynamic, manager-driven coordination Key Innovation: Intelligent manager replaces rigid sequential phases

    "},{"location":"architecture/workflow-diagrams/#1-high-level-magentic-workflow","title":"1. High-Level Magentic Workflow","text":"
    flowchart TD\n    Start([User Query]) --> Manager[Magentic Manager<br/>Plan \u2022 Select \u2022 Assess \u2022 Adapt]\n\n    Manager -->|Plans| Task1[Task Decomposition]\n    Task1 --> Manager\n\n    Manager -->|Selects & Executes| HypAgent[Hypothesis Agent]\n    Manager -->|Selects & Executes| SearchAgent[Search Agent]\n    Manager -->|Selects & Executes| AnalysisAgent[Analysis Agent]\n    Manager -->|Selects & Executes| ReportAgent[Report Agent]\n\n    HypAgent -->|Results| Manager\n    SearchAgent -->|Results| Manager\n    AnalysisAgent -->|Results| Manager\n    ReportAgent -->|Results| Manager\n\n    Manager -->|Assesses Quality| Decision{Good Enough?}\n    Decision -->|No - Refine| Manager\n    Decision -->|No - Different Agent| Manager\n    Decision -->|No - Stalled| Replan[Reset Plan]\n    Replan --> Manager\n\n    Decision -->|Yes| Synthesis[Synthesize Final Result]\n    Synthesis --> Output([Research Report])\n\n    style Start fill:#e1f5e1\n    style Manager fill:#ffe6e6\n    style HypAgent fill:#fff4e6\n    style SearchAgent fill:#fff4e6\n    style AnalysisAgent fill:#fff4e6\n    style ReportAgent fill:#fff4e6\n    style Decision fill:#ffd6d6\n    style Synthesis fill:#d4edda\n    style Output fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#2-magentic-manager-the-6-phase-cycle","title":"2. Magentic Manager: The 6-Phase Cycle","text":"
    flowchart LR\n    P1[1. Planning<br/>Analyze task<br/>Create strategy] --> P2[2. Agent Selection<br/>Pick best agent<br/>for subtask]\n    P2 --> P3[3. Execution<br/>Run selected<br/>agent with tools]\n    P3 --> P4[4. Assessment<br/>Evaluate quality<br/>Check progress]\n    P4 --> Decision{Quality OK?<br/>Progress made?}\n    Decision -->|Yes| P6[6. Synthesis<br/>Combine results<br/>Generate report]\n    Decision -->|No| P5[5. Iteration<br/>Adjust plan<br/>Try again]\n    P5 --> P2\n    P6 --> Done([Complete])\n\n    style P1 fill:#fff4e6\n    style P2 fill:#ffe6e6\n    style P3 fill:#e6f3ff\n    style P4 fill:#ffd6d6\n    style P5 fill:#fff3cd\n    style P6 fill:#d4edda\n    style Done fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#3-simplified-agent-architecture","title":"3. Simplified Agent Architecture","text":"
    graph TB\n    subgraph \"Orchestration Layer\"\n        Manager[Magentic Manager<br/>\u2022 Plans workflow<br/>\u2022 Selects agents<br/>\u2022 Assesses quality<br/>\u2022 Adapts strategy]\n        SharedContext[(Shared Context<br/>\u2022 Hypotheses<br/>\u2022 Search Results<br/>\u2022 Analysis<br/>\u2022 Progress)]\n        Manager <--> SharedContext\n    end\n\n    subgraph \"Specialist Agents\"\n        HypAgent[Hypothesis Agent<br/>\u2022 Domain understanding<br/>\u2022 Hypothesis generation<br/>\u2022 Testability refinement]\n        SearchAgent[Search Agent<br/>\u2022 Multi-source search<br/>\u2022 RAG retrieval<br/>\u2022 Result ranking]\n        AnalysisAgent[Analysis Agent<br/>\u2022 Evidence extraction<br/>\u2022 Statistical analysis<br/>\u2022 Code execution]\n        ReportAgent[Report Agent<br/>\u2022 Report assembly<br/>\u2022 Visualization<br/>\u2022 Citation formatting]\n    end\n\n    subgraph \"MCP Tools\"\n        WebSearch[Web Search<br/>PubMed \u2022 arXiv \u2022 bioRxiv]\n        CodeExec[Code Execution<br/>Sandboxed Python]\n        RAG[RAG Retrieval<br/>Vector DB \u2022 Embeddings]\n        Viz[Visualization<br/>Charts \u2022 Graphs]\n    end\n\n    Manager -->|Selects & Directs| HypAgent\n    Manager -->|Selects & Directs| SearchAgent\n    Manager -->|Selects & Directs| AnalysisAgent\n    Manager -->|Selects & Directs| ReportAgent\n\n    HypAgent --> SharedContext\n    SearchAgent --> SharedContext\n    AnalysisAgent --> SharedContext\n    ReportAgent --> SharedContext\n\n    SearchAgent --> WebSearch\n    SearchAgent --> RAG\n    AnalysisAgent --> CodeExec\n    ReportAgent --> CodeExec\n    ReportAgent --> Viz\n\n    style Manager fill:#ffe6e6\n    style SharedContext fill:#ffe6f0\n    style HypAgent fill:#fff4e6\n    style SearchAgent fill:#fff4e6\n    style AnalysisAgent fill:#fff4e6\n    style ReportAgent fill:#fff4e6\n    style WebSearch fill:#e6f3ff\n    style CodeExec fill:#e6f3ff\n    style RAG fill:#e6f3ff\n    style Viz fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#4-dynamic-workflow-example","title":"4. Dynamic Workflow Example","text":"
    sequenceDiagram\n    participant User\n    participant Manager\n    participant HypAgent\n    participant SearchAgent\n    participant AnalysisAgent\n    participant ReportAgent\n\n    User->>Manager: \"Research protein folding in Alzheimer's\"\n\n    Note over Manager: PLAN: Generate hypotheses \u2192 Search \u2192 Analyze \u2192 Report\n\n    Manager->>HypAgent: Generate 3 hypotheses\n    HypAgent-->>Manager: Returns 3 hypotheses\n    Note over Manager: ASSESS: Good quality, proceed\n\n    Manager->>SearchAgent: Search literature for hypothesis 1\n    SearchAgent-->>Manager: Returns 15 papers\n    Note over Manager: ASSESS: Good results, continue\n\n    Manager->>SearchAgent: Search for hypothesis 2\n    SearchAgent-->>Manager: Only 2 papers found\n    Note over Manager: ASSESS: Insufficient, refine search\n\n    Manager->>SearchAgent: Refined query for hypothesis 2\n    SearchAgent-->>Manager: Returns 12 papers\n    Note over Manager: ASSESS: Better, proceed\n\n    Manager->>AnalysisAgent: Analyze evidence for all hypotheses\n    AnalysisAgent-->>Manager: Returns analysis with code\n    Note over Manager: ASSESS: Complete, generate report\n\n    Manager->>ReportAgent: Create comprehensive report\n    ReportAgent-->>Manager: Returns formatted report\n    Note over Manager: SYNTHESIZE: Combine all results\n\n    Manager->>User: Final Research Report
    "},{"location":"architecture/workflow-diagrams/#5-manager-decision-logic","title":"5. Manager Decision Logic","text":"
    flowchart TD\n    Start([Manager Receives Task]) --> Plan[Create Initial Plan]\n\n    Plan --> Select[Select Agent for Next Subtask]\n    Select --> Execute[Execute Agent]\n    Execute --> Collect[Collect Results]\n\n    Collect --> Assess[Assess Quality & Progress]\n\n    Assess --> Q1{Quality Sufficient?}\n    Q1 -->|No| Q2{Same Agent Can Fix?}\n    Q2 -->|Yes| Feedback[Provide Specific Feedback]\n    Feedback --> Execute\n    Q2 -->|No| Different[Try Different Agent]\n    Different --> Select\n\n    Q1 -->|Yes| Q3{Task Complete?}\n    Q3 -->|No| Q4{Making Progress?}\n    Q4 -->|Yes| Select\n    Q4 -->|No - Stalled| Replan[Reset Plan & Approach]\n    Replan --> Plan\n\n    Q3 -->|Yes| Synth[Synthesize Final Result]\n    Synth --> Done([Return Report])\n\n    style Start fill:#e1f5e1\n    style Plan fill:#fff4e6\n    style Select fill:#ffe6e6\n    style Execute fill:#e6f3ff\n    style Assess fill:#ffd6d6\n    style Q1 fill:#ffe6e6\n    style Q2 fill:#ffe6e6\n    style Q3 fill:#ffe6e6\n    style Q4 fill:#ffe6e6\n    style Synth fill:#d4edda\n    style Done fill:#e1f5e1
    "},{"location":"architecture/workflow-diagrams/#6-hypothesis-agent-workflow","title":"6. Hypothesis Agent Workflow","text":"
    flowchart LR\n    Input[Research Query] --> Domain[Identify Domain<br/>& Key Concepts]\n    Domain --> Context[Retrieve Background<br/>Knowledge]\n    Context --> Generate[Generate 3-5<br/>Initial Hypotheses]\n    Generate --> Refine[Refine for<br/>Testability]\n    Refine --> Rank[Rank by<br/>Quality Score]\n    Rank --> Output[Return Top<br/>Hypotheses]\n\n    Output --> Struct[Hypothesis Structure:<br/>\u2022 Statement<br/>\u2022 Rationale<br/>\u2022 Testability Score<br/>\u2022 Data Requirements<br/>\u2022 Expected Outcomes]\n\n    style Input fill:#e1f5e1\n    style Output fill:#fff4e6\n    style Struct fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#7-search-agent-workflow","title":"7. Search Agent Workflow","text":"
    flowchart TD\n    Input[Hypotheses] --> Strategy[Formulate Search<br/>Strategy per Hypothesis]\n\n    Strategy --> Multi[Multi-Source Search]\n\n    Multi --> PubMed[PubMed Search<br/>via MCP]\n    Multi --> ArXiv[arXiv Search<br/>via MCP]\n    Multi --> BioRxiv[bioRxiv Search<br/>via MCP]\n\n    PubMed --> Aggregate[Aggregate Results]\n    ArXiv --> Aggregate\n    BioRxiv --> Aggregate\n\n    Aggregate --> Filter[Filter & Rank<br/>by Relevance]\n    Filter --> Dedup[Deduplicate<br/>Cross-Reference]\n    Dedup --> Embed[Embed Documents<br/>via MCP]\n    Embed --> Vector[(Vector DB)]\n    Vector --> RAGRetrieval[RAG Retrieval<br/>Top-K per Hypothesis]\n    RAGRetrieval --> Output[Return Contextualized<br/>Search Results]\n\n    style Input fill:#fff4e6\n    style Multi fill:#ffe6e6\n    style Vector fill:#ffe6f0\n    style Output fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#8-analysis-agent-workflow","title":"8. Analysis Agent Workflow","text":"
    flowchart TD\n    Input1[Hypotheses] --> Extract\n    Input2[Search Results] --> Extract[Extract Evidence<br/>per Hypothesis]\n\n    Extract --> Methods[Determine Analysis<br/>Methods Needed]\n\n    Methods --> Branch{Requires<br/>Computation?}\n    Branch -->|Yes| GenCode[Generate Python<br/>Analysis Code]\n    Branch -->|No| Qual[Qualitative<br/>Synthesis]\n\n    GenCode --> Execute[Execute Code<br/>via MCP Sandbox]\n    Execute --> Interpret1[Interpret<br/>Results]\n    Qual --> Interpret2[Interpret<br/>Findings]\n\n    Interpret1 --> Synthesize[Synthesize Evidence<br/>Across Sources]\n    Interpret2 --> Synthesize\n\n    Synthesize --> Verdict[Determine Verdict<br/>per Hypothesis]\n    Verdict --> Support[\u2022 Supported<br/>\u2022 Refuted<br/>\u2022 Inconclusive]\n    Support --> Gaps[Identify Knowledge<br/>Gaps & Limitations]\n    Gaps --> Output[Return Analysis<br/>Report]\n\n    style Input1 fill:#fff4e6\n    style Input2 fill:#e6f3ff\n    style Execute fill:#ffe6e6\n    style Output fill:#e6ffe6
    "},{"location":"architecture/workflow-diagrams/#9-report-agent-workflow","title":"9. Report Agent Workflow","text":"
    flowchart TD\n    Input1[Query] --> Assemble\n    Input2[Hypotheses] --> Assemble\n    Input3[Search Results] --> Assemble\n    Input4[Analysis] --> Assemble[Assemble Report<br/>Sections]\n\n    Assemble --> Exec[Executive Summary]\n    Assemble --> Intro[Introduction]\n    Assemble --> Methods[Methods]\n    Assemble --> Results[Results per<br/>Hypothesis]\n    Assemble --> Discussion[Discussion]\n    Assemble --> Future[Future Directions]\n    Assemble --> Refs[References]\n\n    Results --> VizCheck{Needs<br/>Visualization?}\n    VizCheck -->|Yes| GenViz[Generate Viz Code]\n    GenViz --> ExecViz[Execute via MCP<br/>Create Charts]\n    ExecViz --> Combine\n    VizCheck -->|No| Combine[Combine All<br/>Sections]\n\n    Exec --> Combine\n    Intro --> Combine\n    Methods --> Combine\n    Discussion --> Combine\n    Future --> Combine\n    Refs --> Combine\n\n    Combine --> Format[Format Output]\n    Format --> MD[Markdown]\n    Format --> PDF[PDF]\n    Format --> JSON[JSON]\n\n    MD --> Output[Return Final<br/>Report]\n    PDF --> Output\n    JSON --> Output\n\n    style Input1 fill:#e1f5e1\n    style Input2 fill:#fff4e6\n    style Input3 fill:#e6f3ff\n    style Input4 fill:#e6ffe6\n    style Output fill:#d4edda
    "},{"location":"architecture/workflow-diagrams/#10-data-flow--event-streaming","title":"10. Data Flow & Event Streaming","text":"
    flowchart TD\n    User[\ud83d\udc64 User] -->|Research Query| UI[Gradio UI]\n    UI -->|Submit| Manager[Magentic Manager]\n\n    Manager -->|Event: Planning| UI\n    Manager -->|Select Agent| HypAgent[Hypothesis Agent]\n    HypAgent -->|Event: Delta/Message| UI\n    HypAgent -->|Hypotheses| Context[(Shared Context)]\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| SearchAgent[Search Agent]\n    SearchAgent -->|MCP Request| WebSearch[Web Search Tool]\n    WebSearch -->|Results| SearchAgent\n    SearchAgent -->|Event: Delta/Message| UI\n    SearchAgent -->|Documents| Context\n    SearchAgent -->|Embeddings| VectorDB[(Vector DB)]\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| AnalysisAgent[Analysis Agent]\n    AnalysisAgent -->|MCP Request| CodeExec[Code Execution Tool]\n    CodeExec -->|Results| AnalysisAgent\n    AnalysisAgent -->|Event: Delta/Message| UI\n    AnalysisAgent -->|Analysis| Context\n\n    Context -->|Retrieved by| Manager\n    Manager -->|Select Agent| ReportAgent[Report Agent]\n    ReportAgent -->|MCP Request| CodeExec\n    ReportAgent -->|Event: Delta/Message| UI\n    ReportAgent -->|Report| Context\n\n    Manager -->|Event: Final Result| UI\n    UI -->|Display| User\n\n    style User fill:#e1f5e1\n    style UI fill:#e6f3ff\n    style Manager fill:#ffe6e6\n    style Context fill:#ffe6f0\n    style VectorDB fill:#ffe6f0\n    style WebSearch fill:#f0f0f0\n    style CodeExec fill:#f0f0f0
    "},{"location":"architecture/workflow-diagrams/#11-mcp-tool-architecture","title":"11. MCP Tool Architecture","text":"
    graph TB\n    subgraph \"Agent Layer\"\n        Manager[Magentic Manager]\n        HypAgent[Hypothesis Agent]\n        SearchAgent[Search Agent]\n        AnalysisAgent[Analysis Agent]\n        ReportAgent[Report Agent]\n    end\n\n    subgraph \"MCP Protocol Layer\"\n        Registry[MCP Tool Registry<br/>\u2022 Discovers tools<br/>\u2022 Routes requests<br/>\u2022 Manages connections]\n    end\n\n    subgraph \"MCP Servers\"\n        Server1[Web Search Server<br/>localhost:8001<br/>\u2022 PubMed<br/>\u2022 arXiv<br/>\u2022 bioRxiv]\n        Server2[Code Execution Server<br/>localhost:8002<br/>\u2022 Sandboxed Python<br/>\u2022 Package management]\n        Server3[RAG Server<br/>localhost:8003<br/>\u2022 Vector embeddings<br/>\u2022 Similarity search]\n        Server4[Visualization Server<br/>localhost:8004<br/>\u2022 Chart generation<br/>\u2022 Plot rendering]\n    end\n\n    subgraph \"External Services\"\n        PubMed[PubMed API]\n        ArXiv[arXiv API]\n        BioRxiv[bioRxiv API]\n        Modal[Modal Sandbox]\n        ChromaDB[(ChromaDB)]\n    end\n\n    SearchAgent -->|Request| Registry\n    AnalysisAgent -->|Request| Registry\n    ReportAgent -->|Request| Registry\n\n    Registry --> Server1\n    Registry --> Server2\n    Registry --> Server3\n    Registry --> Server4\n\n    Server1 --> PubMed\n    Server1 --> ArXiv\n    Server1 --> BioRxiv\n    Server2 --> Modal\n    Server3 --> ChromaDB\n\n    style Manager fill:#ffe6e6\n    style Registry fill:#fff4e6\n    style Server1 fill:#e6f3ff\n    style Server2 fill:#e6f3ff\n    style Server3 fill:#e6f3ff\n    style Server4 fill:#e6f3ff
    "},{"location":"architecture/workflow-diagrams/#12-progress-tracking--stall-detection","title":"12. Progress Tracking & Stall Detection","text":"
    stateDiagram-v2\n    [*] --> Initialization: User Query\n\n    Initialization --> Planning: Manager starts\n\n    Planning --> AgentExecution: Select agent\n\n    AgentExecution --> Assessment: Collect results\n\n    Assessment --> QualityCheck: Evaluate output\n\n    QualityCheck --> AgentExecution: Poor quality<br/>(retry < max_rounds)\n    QualityCheck --> Planning: Poor quality<br/>(try different agent)\n    QualityCheck --> NextAgent: Good quality<br/>(task incomplete)\n    QualityCheck --> Synthesis: Good quality<br/>(task complete)\n\n    NextAgent --> AgentExecution: Select next agent\n\n    state StallDetection <<choice>>\n    Assessment --> StallDetection: Check progress\n    StallDetection --> Planning: No progress<br/>(stall count < max)\n    StallDetection --> ErrorRecovery: No progress<br/>(max stalls reached)\n\n    ErrorRecovery --> PartialReport: Generate partial results\n    PartialReport --> [*]\n\n    Synthesis --> FinalReport: Combine all outputs\n    FinalReport --> [*]\n\n    note right of QualityCheck\n        Manager assesses:\n        \u2022 Output completeness\n        \u2022 Quality metrics\n        \u2022 Progress made\n    end note\n\n    note right of StallDetection\n        Stall = no new progress\n        after agent execution\n        Triggers plan reset\n    end note
    "},{"location":"architecture/workflow-diagrams/#13-gradio-ui-integration","title":"13. Gradio UI Integration","text":"
    graph TD\n    App[Gradio App<br/>DeepCritical Research Agent]\n\n    App --> Input[Input Section]\n    App --> Status[Status Section]\n    App --> Output[Output Section]\n\n    Input --> Query[Research Question<br/>Text Area]\n    Input --> Controls[Controls]\n    Controls --> MaxHyp[Max Hypotheses: 1-10]\n    Controls --> MaxRounds[Max Rounds: 5-20]\n    Controls --> Submit[Start Research Button]\n\n    Status --> Log[Real-time Event Log<br/>\u2022 Manager planning<br/>\u2022 Agent selection<br/>\u2022 Execution updates<br/>\u2022 Quality assessment]\n    Status --> Progress[Progress Tracker<br/>\u2022 Current agent<br/>\u2022 Round count<br/>\u2022 Stall count]\n\n    Output --> Tabs[Tabbed Results]\n    Tabs --> Tab1[Hypotheses Tab<br/>Generated hypotheses with scores]\n    Tabs --> Tab2[Search Results Tab<br/>Papers & sources found]\n    Tabs --> Tab3[Analysis Tab<br/>Evidence & verdicts]\n    Tabs --> Tab4[Report Tab<br/>Final research report]\n    Tab4 --> Download[Download Report<br/>MD / PDF / JSON]\n\n    Submit -.->|Triggers| Workflow[Magentic Workflow]\n    Workflow -.->|MagenticOrchestratorMessageEvent| Log\n    Workflow -.->|MagenticAgentDeltaEvent| Log\n    Workflow -.->|MagenticAgentMessageEvent| Log\n    Workflow -.->|MagenticFinalResultEvent| Tab4\n\n    style App fill:#e1f5e1\n    style Input fill:#fff4e6\n    style Status fill:#e6f3ff\n    style Output fill:#e6ffe6\n    style Workflow fill:#ffe6e6
    "},{"location":"architecture/workflow-diagrams/#14-complete-system-context","title":"14. Complete System Context","text":"
    graph LR\n    User[\ud83d\udc64 Researcher<br/>Asks research questions] -->|Submits query| DC[DeepCritical<br/>Magentic Workflow]\n\n    DC -->|Literature search| PubMed[PubMed API<br/>Medical papers]\n    DC -->|Preprint search| ArXiv[arXiv API<br/>Scientific preprints]\n    DC -->|Biology search| BioRxiv[bioRxiv API<br/>Biology preprints]\n    DC -->|Agent reasoning| Claude[Claude API<br/>Sonnet 4 / Opus]\n    DC -->|Code execution| Modal[Modal Sandbox<br/>Safe Python env]\n    DC -->|Vector storage| Chroma[ChromaDB<br/>Embeddings & RAG]\n\n    DC -->|Deployed on| HF[HuggingFace Spaces<br/>Gradio 6.0]\n\n    PubMed -->|Results| DC\n    ArXiv -->|Results| DC\n    BioRxiv -->|Results| DC\n    Claude -->|Responses| DC\n    Modal -->|Output| DC\n    Chroma -->|Context| DC\n\n    DC -->|Research report| User\n\n    style User fill:#e1f5e1\n    style DC fill:#ffe6e6\n    style PubMed fill:#e6f3ff\n    style ArXiv fill:#e6f3ff\n    style BioRxiv fill:#e6f3ff\n    style Claude fill:#ffd6d6\n    style Modal fill:#f0f0f0\n    style Chroma fill:#ffe6f0\n    style HF fill:#d4edda
    "},{"location":"architecture/workflow-diagrams/#15-workflow-timeline-simplified","title":"15. Workflow Timeline (Simplified)","text":"
    gantt\n    title DeepCritical Magentic Workflow - Typical Execution\n    dateFormat mm:ss\n    axisFormat %M:%S\n\n    section Manager Planning\n    Initial planning         :p1, 00:00, 10s\n\n    section Hypothesis Agent\n    Generate hypotheses      :h1, after p1, 30s\n    Manager assessment       :h2, after h1, 5s\n\n    section Search Agent\n    Search hypothesis 1      :s1, after h2, 20s\n    Search hypothesis 2      :s2, after s1, 20s\n    Search hypothesis 3      :s3, after s2, 20s\n    RAG processing          :s4, after s3, 15s\n    Manager assessment      :s5, after s4, 5s\n\n    section Analysis Agent\n    Evidence extraction     :a1, after s5, 15s\n    Code generation        :a2, after a1, 20s\n    Code execution         :a3, after a2, 25s\n    Synthesis              :a4, after a3, 20s\n    Manager assessment     :a5, after a4, 5s\n\n    section Report Agent\n    Report assembly        :r1, after a5, 30s\n    Visualization          :r2, after r1, 15s\n    Formatting             :r3, after r2, 10s\n\n    section Manager Synthesis\n    Final synthesis        :f1, after r3, 10s
    "},{"location":"architecture/workflow-diagrams/#key-differences-from-original-design","title":"Key Differences from Original Design","text":"Aspect Original (Judge-in-Loop) New (Magentic) Control Flow Fixed sequential phases Dynamic agent selection Quality Control Separate Judge Agent Manager assessment built-in Retry Logic Phase-level with feedback Agent-level with adaptation Flexibility Rigid 4-phase pipeline Adaptive workflow Complexity 5 agents (including Judge) 4 agents (no Judge) Progress Tracking Manual state management Built-in round/stall detection Agent Coordination Sequential handoff Manager-driven dynamic selection Error Recovery Retry same phase Try different agent or replan"},{"location":"architecture/workflow-diagrams/#simplified-design-principles","title":"Simplified Design Principles","text":"
    1. Manager is Intelligent: LLM-powered manager handles planning, selection, and quality assessment
    2. No Separate Judge: Manager's assessment phase replaces dedicated Judge Agent
    3. Dynamic Workflow: Agents can be called multiple times in any order based on need
    4. Built-in Safety: max_round_count (15) and max_stall_count (3) prevent infinite loops
    5. Event-Driven UI: Real-time streaming updates to Gradio interface
    6. MCP-Powered Tools: All external capabilities via Model Context Protocol
    7. Shared Context: Centralized state accessible to all agents
    8. Progress Awareness: Manager tracks what's been done and what's needed
    "},{"location":"architecture/workflow-diagrams/#legend","title":"Legend","text":""},{"location":"architecture/workflow-diagrams/#implementation-highlights","title":"Implementation Highlights","text":"

    Simple 4-Agent Setup:

    Manager handles quality assessment in its instructions: - Checks hypothesis quality (testable, novel, clear) - Validates search results (relevant, authoritative, recent) - Assesses analysis soundness (methodology, evidence, conclusions) - Ensures report completeness (all sections, proper citations)

    No separate Judge Agent needed - manager does it all!

    Document Version: 2.0 (Magentic Simplified) Last Updated: 2025-11-24 Architecture: Microsoft Magentic Orchestration Pattern Agents: 4 (Hypothesis, Search, Analysis, Report) + 1 Manager License: MIT

    "},{"location":"architecture/workflow-diagrams/#see-also","title":"See Also","text":""},{"location":"configuration/","title":"Configuration Guide","text":""},{"location":"configuration/#overview","title":"Overview","text":"

    DeepCritical uses Pydantic Settings for centralized configuration management. All settings are defined in the Settings class in src/utils/config.py and can be configured via environment variables or a .env file.

    The configuration system provides:

    "},{"location":"configuration/#quick-start","title":"Quick Start","text":"
    1. Create a .env file in the project root
    2. Set at least one LLM API key (OPENAI_API_KEY, ANTHROPIC_API_KEY, or HF_TOKEN)
    3. Optionally configure other services as needed
    4. The application will automatically load and validate your configuration
    "},{"location":"configuration/#configuration-system-architecture","title":"Configuration System Architecture","text":""},{"location":"configuration/#settings-class","title":"Settings Class","text":"

    The [Settings][settings-class] class extends BaseSettings from pydantic_settings and defines all application configuration:

    View source

    "},{"location":"configuration/#singleton-instance","title":"Singleton Instance","text":"

    A global settings instance is available for import:

    View source

    "},{"location":"configuration/#usage-pattern","title":"Usage Pattern","text":"

    Access configuration throughout the codebase:

    from src.utils.config import settings\n\n# Check if API keys are available\nif settings.has_openai_key:\n    # Use OpenAI\n    pass\n\n# Access configuration values\nmax_iterations = settings.max_iterations\nweb_search_provider = settings.web_search_provider\n
    "},{"location":"configuration/#required-configuration","title":"Required Configuration","text":""},{"location":"configuration/#llm-provider","title":"LLM Provider","text":"

    You must configure at least one LLM provider. The system supports:

    "},{"location":"configuration/#openai-configuration","title":"OpenAI Configuration","text":"
    LLM_PROVIDER=openai\nOPENAI_API_KEY=your_openai_api_key_here\nOPENAI_MODEL=gpt-5.1\n

    The default model is defined in the Settings class:

    "},{"location":"configuration/#anthropic-configuration","title":"Anthropic Configuration","text":"
    LLM_PROVIDER=anthropic\nANTHROPIC_API_KEY=your_anthropic_api_key_here\nANTHROPIC_MODEL=claude-sonnet-4-5-20250929\n

    The default model is defined in the Settings class:

    "},{"location":"configuration/#huggingface-configuration","title":"HuggingFace Configuration","text":"

    HuggingFace can work without an API key for public models, but an API key provides higher rate limits:

    # Option 1: Using HF_TOKEN (preferred)\nHF_TOKEN=your_huggingface_token_here\n\n# Option 2: Using HUGGINGFACE_API_KEY (alternative)\nHUGGINGFACE_API_KEY=your_huggingface_api_key_here\n\n# Default model\nHUGGINGFACE_MODEL=meta-llama/Llama-3.1-8B-Instruct\n

    The HuggingFace token can be set via either environment variable:

    "},{"location":"configuration/#optional-configuration","title":"Optional Configuration","text":""},{"location":"configuration/#embedding-configuration","title":"Embedding Configuration","text":"

    DeepCritical supports multiple embedding providers for semantic search and RAG:

    # Embedding Provider: \"openai\", \"local\", or \"huggingface\"\nEMBEDDING_PROVIDER=local\n\n# OpenAI Embedding Model (used by LlamaIndex RAG)\nOPENAI_EMBEDDING_MODEL=text-embedding-3-small\n\n# Local Embedding Model (sentence-transformers, used by EmbeddingService)\nLOCAL_EMBEDDING_MODEL=all-MiniLM-L6-v2\n\n# HuggingFace Embedding Model\nHUGGINGFACE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2\n

    The embedding provider configuration:

    Note: OpenAI embeddings require OPENAI_API_KEY. The local provider (default) uses sentence-transformers and requires no API key.

    "},{"location":"configuration/#web-search-configuration","title":"Web Search Configuration","text":"

    DeepCritical supports multiple web search providers:

    # Web Search Provider: \"serper\", \"searchxng\", \"brave\", \"tavily\", or \"duckduckgo\"\n# Default: \"duckduckgo\" (no API key required)\nWEB_SEARCH_PROVIDER=duckduckgo\n\n# Serper API Key (for Google search via Serper)\nSERPER_API_KEY=your_serper_api_key_here\n\n# SearchXNG Host URL (for self-hosted search)\nSEARCHXNG_HOST=http://localhost:8080\n\n# Brave Search API Key\nBRAVE_API_KEY=your_brave_api_key_here\n\n# Tavily API Key\nTAVILY_API_KEY=your_tavily_api_key_here\n

    The web search provider configuration:

    Note: DuckDuckGo is the default and requires no API key, making it ideal for development and testing.

    "},{"location":"configuration/#pubmed-configuration","title":"PubMed Configuration","text":"

    PubMed search supports optional NCBI API key for higher rate limits:

    # NCBI API Key (optional, for higher rate limits: 10 req/sec vs 3 req/sec)\nNCBI_API_KEY=your_ncbi_api_key_here\n

    The PubMed tool uses this configuration:

    "},{"location":"configuration/#agent-configuration","title":"Agent Configuration","text":"

    Control agent behavior and research loop execution:

    # Maximum iterations per research loop (1-50, default: 10)\nMAX_ITERATIONS=10\n\n# Search timeout in seconds\nSEARCH_TIMEOUT=30\n\n# Use graph-based execution for research flows\nUSE_GRAPH_EXECUTION=false\n

    The agent configuration fields:

    "},{"location":"configuration/#budget--rate-limiting-configuration","title":"Budget & Rate Limiting Configuration","text":"

    Control resource limits for research loops:

    # Default token budget per research loop (1000-1000000, default: 100000)\nDEFAULT_TOKEN_LIMIT=100000\n\n# Default time limit per research loop in minutes (1-120, default: 10)\nDEFAULT_TIME_LIMIT_MINUTES=10\n\n# Default iterations limit per research loop (1-50, default: 10)\nDEFAULT_ITERATIONS_LIMIT=10\n

    The budget configuration with validation:

    "},{"location":"configuration/#rag-service-configuration","title":"RAG Service Configuration","text":"

    Configure the Retrieval-Augmented Generation service:

    # ChromaDB collection name for RAG\nRAG_COLLECTION_NAME=deepcritical_evidence\n\n# Number of top results to retrieve from RAG (1-50, default: 5)\nRAG_SIMILARITY_TOP_K=5\n\n# Automatically ingest evidence into RAG\nRAG_AUTO_INGEST=true\n

    The RAG configuration:

    "},{"location":"configuration/#chromadb-configuration","title":"ChromaDB Configuration","text":"

    Configure the vector database for embeddings and RAG:

    # ChromaDB storage path\nCHROMA_DB_PATH=./chroma_db\n\n# Whether to persist ChromaDB to disk\nCHROMA_DB_PERSIST=true\n\n# ChromaDB server host (for remote ChromaDB, optional)\nCHROMA_DB_HOST=localhost\n\n# ChromaDB server port (for remote ChromaDB, optional)\nCHROMA_DB_PORT=8000\n

    The ChromaDB configuration:

    "},{"location":"configuration/#external-services","title":"External Services","text":""},{"location":"configuration/#modal-configuration","title":"Modal Configuration","text":"

    Modal is used for secure sandbox execution of statistical analysis:

    # Modal Token ID (for Modal sandbox execution)\nMODAL_TOKEN_ID=your_modal_token_id_here\n\n# Modal Token Secret\nMODAL_TOKEN_SECRET=your_modal_token_secret_here\n

    The Modal configuration:

    "},{"location":"configuration/#logging-configuration","title":"Logging Configuration","text":"

    Configure structured logging:

    # Log Level: \"DEBUG\", \"INFO\", \"WARNING\", or \"ERROR\"\nLOG_LEVEL=INFO\n

    The logging configuration:

    Logging is configured via the configure_logging() function:

    "},{"location":"configuration/#configuration-properties","title":"Configuration Properties","text":"

    The Settings class provides helpful properties for checking configuration state:

    "},{"location":"configuration/#api-key-availability","title":"API Key Availability","text":"

    Check which API keys are available:

    Usage:

    from src.utils.config import settings\n\n# Check API key availability\nif settings.has_openai_key:\n    # Use OpenAI\n    pass\n\nif settings.has_anthropic_key:\n    # Use Anthropic\n    pass\n\nif settings.has_huggingface_key:\n    # Use HuggingFace\n    pass\n\nif settings.has_any_llm_key:\n    # At least one LLM is available\n    pass\n
    "},{"location":"configuration/#service-availability","title":"Service Availability","text":"

    Check if external services are configured:

    Usage:

    from src.utils.config import settings\n\n# Check service availability\nif settings.modal_available:\n    # Use Modal sandbox\n    pass\n\nif settings.web_search_available:\n    # Web search is configured\n    pass\n
    "},{"location":"configuration/#api-key-retrieval","title":"API Key Retrieval","text":"

    Get the API key for the configured provider:

    For OpenAI-specific operations (e.g., Magentic mode):

    "},{"location":"configuration/#configuration-usage-in-codebase","title":"Configuration Usage in Codebase","text":"

    The configuration system is used throughout the codebase:

    "},{"location":"configuration/#llm-factory","title":"LLM Factory","text":"

    The LLM factory uses settings to create appropriate models:

    "},{"location":"configuration/#embedding-service","title":"Embedding Service","text":"

    The embedding service uses local embedding model configuration:

    "},{"location":"configuration/#orchestrator-factory","title":"Orchestrator Factory","text":"

    The orchestrator factory uses settings to determine mode:

    "},{"location":"configuration/#environment-variables-reference","title":"Environment Variables Reference","text":""},{"location":"configuration/#required-at-least-one-llm","title":"Required (at least one LLM)","text":""},{"location":"configuration/#llm-configuration-variables","title":"LLM Configuration Variables","text":""},{"location":"configuration/#embedding-configuration-variables","title":"Embedding Configuration Variables","text":""},{"location":"configuration/#web-search-configuration-variables","title":"Web Search Configuration Variables","text":""},{"location":"configuration/#pubmed-configuration-variables","title":"PubMed Configuration Variables","text":""},{"location":"configuration/#agent-configuration-variables","title":"Agent Configuration Variables","text":""},{"location":"configuration/#budget-configuration-variables","title":"Budget Configuration Variables","text":""},{"location":"configuration/#rag-configuration-variables","title":"RAG Configuration Variables","text":""},{"location":"configuration/#chromadb-configuration-variables","title":"ChromaDB Configuration Variables","text":""},{"location":"configuration/#external-services-variables","title":"External Services Variables","text":""},{"location":"configuration/#logging-configuration-variables","title":"Logging Configuration Variables","text":""},{"location":"configuration/#validation","title":"Validation","text":"

    Settings are validated on load using Pydantic validation:

    "},{"location":"configuration/#validation-examples","title":"Validation Examples","text":"

    The max_iterations field has range validation:

    The llm_provider field has literal validation:

    "},{"location":"configuration/#error-handling","title":"Error Handling","text":"

    Configuration errors raise ConfigurationError from src/utils/exceptions.py:

    ```22:25:src/utils/exceptions.py class ConfigurationError(DeepCriticalError): \"\"\"Raised when configuration is invalid.\"\"\"

    pass\n

    ```

    "},{"location":"configuration/#error-handling-example","title":"Error Handling Example","text":"

    python from src.utils.config import settings from src.utils.exceptions import ConfigurationError try: api_key = settings.get_api_key() except ConfigurationError as e: print(f\"Configuration error: {e}\")

    "},{"location":"configuration/#common-configuration-errors","title":"Common Configuration Errors","text":"
    1. Missing API Key: When get_api_key() is called but the required API key is not set
    2. Invalid Provider: When llm_provider is set to an unsupported value
    3. Out of Range: When numeric values exceed their min/max constraints
    4. Invalid Literal: When enum fields receive unsupported values
    "},{"location":"configuration/#configuration-best-practices","title":"Configuration Best Practices","text":"
    1. Use .env File: Store sensitive keys in .env file (add to .gitignore)
    2. Check Availability: Use properties like has_openai_key before accessing API keys
    3. Handle Errors: Always catch ConfigurationError when calling get_api_key()
    4. Validate Early: Configuration is validated on import, so errors surface immediately
    5. Use Defaults: Leverage sensible defaults for optional configuration
    "},{"location":"configuration/#future-enhancements","title":"Future Enhancements","text":"

    The following configurations are planned for future phases:

    1. Additional LLM Providers: DeepSeek, OpenRouter, Gemini, Perplexity, Azure OpenAI, Local models
    2. Model Selection: Reasoning/main/fast model configuration
    3. Service Integration: Additional service integrations and configurations
    "},{"location":"contributing/","title":"Contributing to The DETERMINATOR","text":"

    Thank you for your interest in contributing to The DETERMINATOR! This guide will help you get started.

    Note on Project Names: \"The DETERMINATOR\" is the product name, \"DeepCritical\" is the organization/project name, and \"determinator\" is the Python package name.

    "},{"location":"contributing/#git-workflow","title":"Git Workflow","text":""},{"location":"contributing/#repository-information","title":"Repository Information","text":""},{"location":"contributing/#dual-repository-setup","title":"Dual Repository Setup","text":"

    This project uses a dual repository setup:

    "},{"location":"contributing/#remote-configuration","title":"Remote Configuration","text":"

    When cloning, set up remotes as follows:

    # Clone from GitHub\ngit clone https://github.com/DeepCritical/GradioDemo.git\ncd GradioDemo\n\n# Add HuggingFace remote (optional, for deployment)\ngit remote add huggingface-upstream https://huggingface.co/spaces/DataQuests/DeepCritical\n

    Important: Never push directly to main or dev on HuggingFace. Always work through GitHub PRs. GitHub is the source of truth; HuggingFace is for deployment/demo only.

    "},{"location":"contributing/#package-manager","title":"Package Manager","text":"

    This project uses uv as the package manager. All commands should be prefixed with uv run to ensure they run in the correct environment.

    "},{"location":"contributing/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync all dependencies including dev extras\nuv sync --all-extras\n\n# Install pre-commit hooks\nuv run pre-commit install\n
    "},{"location":"contributing/#development-commands","title":"Development Commands","text":"
    # Installation\nuv sync --all-extras              # Install all dependencies including dev\nuv run pre-commit install          # Install pre-commit hooks\n\n# Code Quality Checks (run all before committing)\nuv run ruff check src tests       # Lint with ruff\nuv run ruff format src tests      # Format with ruff\nuv run mypy src                   # Type checking\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire  # Tests with coverage\n\n# Testing Commands\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire              # Run unit tests (excludes OpenAI tests)\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire                 # Run HuggingFace tests\nuv run pytest tests/ -v -p no:logfire                                  # Run all tests\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire  # Tests with terminal coverage\nuv run pytest --cov=src --cov-report=html -p no:logfire                # Generate HTML coverage report (opens htmlcov/index.html)\n\n# Documentation Commands\nuv run mkdocs build                # Build documentation\nuv run mkdocs serve                # Serve documentation locally (http://127.0.0.1:8000)\n
    "},{"location":"contributing/#test-markers","title":"Test Markers","text":"

    The project uses pytest markers to categorize tests. See Testing Guidelines for details:

    Note: The -p no:logfire flag disables the logfire plugin to avoid conflicts during testing.

    "},{"location":"contributing/#getting-started","title":"Getting Started","text":"
    1. Fork the repository on GitHub: DeepCritical/GradioDemo

    2. Clone your fork:

    git clone https://github.com/yourusername/GradioDemo.git\ncd GradioDemo\n
    1. Install dependencies:
    uv sync --all-extras\nuv run pre-commit install\n
    1. Create a feature branch:
    git checkout -b yourname-feature-name\n
    1. Make your changes following the guidelines below

    2. Run checks:

    uv run ruff check src tests\nuv run mypy src\nuv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire\n
    1. Commit and push:
    git commit -m \"Description of changes\"\ngit push origin yourname-feature-name\n
    1. Create a pull request on GitHub
    "},{"location":"contributing/#development-guidelines","title":"Development Guidelines","text":""},{"location":"contributing/#code-style","title":"Code Style","text":""},{"location":"contributing/#error-handling","title":"Error Handling","text":""},{"location":"contributing/#testing","title":"Testing","text":""},{"location":"contributing/#implementation-patterns","title":"Implementation Patterns","text":""},{"location":"contributing/#prompt-engineering","title":"Prompt Engineering","text":""},{"location":"contributing/#code-quality","title":"Code Quality","text":""},{"location":"contributing/#mcp-integration","title":"MCP Integration","text":""},{"location":"contributing/#mcp-tools","title":"MCP Tools","text":""},{"location":"contributing/#gradio-mcp-server","title":"Gradio MCP Server","text":""},{"location":"contributing/#common-pitfalls","title":"Common Pitfalls","text":"
    1. Blocking the event loop: Never use sync I/O in async functions
    2. Missing type hints: All functions must have complete type annotations
    3. Hallucinated citations: Always validate references
    4. Global mutable state: Use ContextVar or pass via parameters
    5. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
    6. Rate limiting: Always implement for external APIs
    7. Error chaining: Always use from e when raising exceptions
    "},{"location":"contributing/#key-principles","title":"Key Principles","text":"
    1. Type Safety First: All code must pass mypy --strict
    2. Async Everything: All I/O must be async
    3. Test-Driven: Write tests before implementation
    4. No Hallucinations: Validate all citations
    5. Graceful Degradation: Support free tier (HF Inference) when no API keys
    6. Lazy Loading: Don't require optional dependencies at import time
    7. Structured Logging: Use structlog, never print()
    8. Error Chaining: Always preserve exception context
    "},{"location":"contributing/#pull-request-process","title":"Pull Request Process","text":"
    1. Ensure all checks pass: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire
    2. Update documentation if needed
    3. Add tests for new features
    4. Update CHANGELOG if applicable
    5. Request review from maintainers
    6. Address review feedback
    7. Wait for approval before merging
    "},{"location":"contributing/#project-structure","title":"Project Structure","text":""},{"location":"contributing/#questions","title":"Questions?","text":"

    Thank you for contributing to The DETERMINATOR!

    "},{"location":"contributing/code-quality/","title":"Code Quality & Documentation","text":"

    This document outlines code quality standards and documentation requirements for The DETERMINATOR.

    "},{"location":"contributing/code-quality/#linting","title":"Linting","text":""},{"location":"contributing/code-quality/#type-checking","title":"Type Checking","text":""},{"location":"contributing/code-quality/#pre-commit","title":"Pre-commit","text":"

    Pre-commit hooks run automatically on commit to ensure code quality. Configuration is in .pre-commit-config.yaml.

    "},{"location":"contributing/code-quality/#installation","title":"Installation","text":"
    # Install dependencies (includes pre-commit package)\nuv sync --all-extras\n\n# Set up git hooks (must be run separately)\nuv run pre-commit install\n

    Note: uv sync --all-extras installs the pre-commit package, but you must run uv run pre-commit install separately to set up the git hooks.

    "},{"location":"contributing/code-quality/#pre-commit-hooks","title":"Pre-commit Hooks","text":"

    The following hooks run automatically on commit:

    1. ruff: Lints code and fixes issues automatically
    2. Runs on: src/ (excludes tests/, reference_repos/)
    3. Auto-fixes: Yes

    4. ruff-format: Formats code with ruff

    5. Runs on: src/ (excludes tests/, reference_repos/)
    6. Auto-fixes: Yes

    7. mypy: Type checking

    8. Runs on: src/ (excludes folder/)
    9. Additional dependencies: pydantic, pydantic-settings, tenacity, pydantic-ai

    10. pytest-unit: Runs unit tests (excludes OpenAI and embedding_provider tests)

    11. Runs: tests/unit/ with -m \"not openai and not embedding_provider\"
    12. Always runs: Yes (not just on changed files)

    13. pytest-local-embeddings: Runs local embedding tests

    14. Runs: tests/ with -m \"local_embeddings\"
    15. Always runs: Yes
    "},{"location":"contributing/code-quality/#manual-pre-commit-run","title":"Manual Pre-commit Run","text":"

    To run pre-commit hooks manually (without committing):

    uv run pre-commit run --all-files\n
    "},{"location":"contributing/code-quality/#troubleshooting","title":"Troubleshooting","text":""},{"location":"contributing/code-quality/#documentation","title":"Documentation","text":""},{"location":"contributing/code-quality/#building-documentation","title":"Building Documentation","text":"

    Documentation is built using MkDocs. Source files are in docs/, and the configuration is in mkdocs.yml.

    # Build documentation\nuv run mkdocs build\n\n# Serve documentation locally (http://127.0.0.1:8000)\nuv run mkdocs serve\n

    The documentation site is published at: https://deepcritical.github.io/GradioDemo/

    "},{"location":"contributing/code-quality/#docstrings","title":"Docstrings","text":"

    Example:

    "},{"location":"contributing/code-quality/#code-comments","title":"Code Comments","text":""},{"location":"contributing/code-quality/#see-also","title":"See Also","text":""},{"location":"contributing/code-style/","title":"Code Style & Conventions","text":"

    This document outlines the code style and conventions for The DETERMINATOR.

    "},{"location":"contributing/code-style/#package-manager","title":"Package Manager","text":"

    This project uses uv as the package manager. All commands should be prefixed with uv run to ensure they run in the correct environment.

    "},{"location":"contributing/code-style/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync all dependencies including dev extras\nuv sync --all-extras\n
    "},{"location":"contributing/code-style/#running-commands","title":"Running Commands","text":"

    All development commands should use uv run prefix:

    # Instead of: pytest tests/\nuv run pytest tests/\n\n# Instead of: ruff check src\nuv run ruff check src\n\n# Instead of: mypy src\nuv run mypy src\n

    This ensures commands run in the correct virtual environment managed by uv.

    "},{"location":"contributing/code-style/#type-safety","title":"Type Safety","text":""},{"location":"contributing/code-style/#pydantic-models","title":"Pydantic Models","text":""},{"location":"contributing/code-style/#async-patterns","title":"Async Patterns","text":"
    loop = asyncio.get_running_loop()\nresult = await loop.run_in_executor(None, cpu_bound_function, args)\n
    "},{"location":"contributing/code-style/#common-pitfalls","title":"Common Pitfalls","text":"
    1. Blocking the event loop: Never use sync I/O in async functions
    2. Missing type hints: All functions must have complete type annotations
    3. Global mutable state: Use ContextVar or pass via parameters
    4. Import errors: Lazy-load optional dependencies (magentic, modal, embeddings)
    "},{"location":"contributing/code-style/#see-also","title":"See Also","text":""},{"location":"contributing/error-handling/","title":"Error Handling & Logging","text":"

    This document outlines error handling and logging conventions for The DETERMINATOR.

    "},{"location":"contributing/error-handling/#exception-hierarchy","title":"Exception Hierarchy","text":"

    Use custom exception hierarchy (src/utils/exceptions.py):

    "},{"location":"contributing/error-handling/#error-handling-rules","title":"Error Handling Rules","text":"
    logger.error(\"Operation failed\", error=str(e), context=value)\n
    "},{"location":"contributing/error-handling/#logging","title":"Logging","text":""},{"location":"contributing/error-handling/#logging-examples","title":"Logging Examples","text":"
    logger.info(\"Starting search\", query=query, tools=[t.name for t in tools])\nlogger.warning(\"Search tool failed\", tool=tool.name, error=str(result))\nlogger.error(\"Assessment failed\", error=str(e))\n
    "},{"location":"contributing/error-handling/#error-chaining","title":"Error Chaining","text":"

    Always preserve exception context:

    try:\n    result = await api_call()\nexcept httpx.HTTPError as e:\n    raise SearchError(f\"API call failed: {e}\") from e\n
    "},{"location":"contributing/error-handling/#see-also","title":"See Also","text":""},{"location":"contributing/implementation-patterns/","title":"Implementation Patterns","text":"

    This document outlines common implementation patterns used in The DETERMINATOR.

    "},{"location":"contributing/implementation-patterns/#search-tools","title":"Search Tools","text":"

    All tools implement SearchTool protocol (src/tools/base.py):

    Example pattern:

    class MySearchTool:\n    @property\n    def name(self) -> str:\n        return \"mytool\"\n    \n    @retry(stop=stop_after_attempt(3), wait=wait_exponential(...))\n    async def search(self, query: str, max_results: int = 10) -> list[Evidence]:\n        # Implementation\n        return evidence_list\n
    "},{"location":"contributing/implementation-patterns/#judge-handlers","title":"Judge Handlers","text":""},{"location":"contributing/implementation-patterns/#agent-factory-pattern","title":"Agent Factory Pattern","text":""},{"location":"contributing/implementation-patterns/#state-management","title":"State Management","text":""},{"location":"contributing/implementation-patterns/#singleton-pattern","title":"Singleton Pattern","text":"

    Use @lru_cache(maxsize=1) for singletons:

    "},{"location":"contributing/implementation-patterns/#see-also","title":"See Also","text":""},{"location":"contributing/prompt-engineering/","title":"Prompt Engineering & Citation Validation","text":"

    This document outlines prompt engineering guidelines and citation validation rules.

    "},{"location":"contributing/prompt-engineering/#judge-prompts","title":"Judge Prompts","text":""},{"location":"contributing/prompt-engineering/#hypothesis-prompts","title":"Hypothesis Prompts","text":""},{"location":"contributing/prompt-engineering/#report-prompts","title":"Report Prompts","text":""},{"location":"contributing/prompt-engineering/#citation-validation","title":"Citation Validation","text":""},{"location":"contributing/prompt-engineering/#citation-validation-rules","title":"Citation Validation Rules","text":"
    1. Every reference URL must EXACTLY match a provided evidence URL
    2. Do NOT invent, fabricate, or hallucinate any references
    3. Do NOT modify paper titles, authors, dates, or URLs
    4. If unsure about a citation, OMIT it rather than guess
    5. Copy URLs exactly as provided - do not create similar-looking URLs
    "},{"location":"contributing/prompt-engineering/#evidence-selection","title":"Evidence Selection","text":""},{"location":"contributing/prompt-engineering/#see-also","title":"See Also","text":""},{"location":"contributing/testing/","title":"Testing Requirements","text":"

    This document outlines testing requirements and guidelines for The DETERMINATOR.

    "},{"location":"contributing/testing/#test-structure","title":"Test Structure","text":""},{"location":"contributing/testing/#test-markers","title":"Test Markers","text":"

    The project uses pytest markers to categorize tests. These markers are defined in pyproject.toml:

    "},{"location":"contributing/testing/#running-tests-by-marker","title":"Running Tests by Marker","text":"
    # Run only unit tests (excludes OpenAI tests by default)\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire\n\n# Run HuggingFace tests\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire\n\n# Run all tests\nuv run pytest tests/ -v -p no:logfire\n\n# Run only local embedding tests\nuv run pytest tests/ -v -m \"local_embeddings\" -p no:logfire\n\n# Exclude slow tests\nuv run pytest tests/ -v -m \"not slow\" -p no:logfire\n

    Note: The -p no:logfire flag disables the logfire plugin to avoid conflicts during testing.

    "},{"location":"contributing/testing/#mocking","title":"Mocking","text":""},{"location":"contributing/testing/#tdd-workflow","title":"TDD Workflow","text":"
    1. Write failing test in tests/unit/
    2. Implement in src/
    3. Ensure test passes
    4. Run checks: uv run ruff check src tests && uv run mypy src && uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire
    "},{"location":"contributing/testing/#test-command-examples","title":"Test Command Examples","text":"
    # Run unit tests (default, excludes OpenAI tests)\nuv run pytest tests/unit/ -v -m \"not openai\" -p no:logfire\n\n# Run HuggingFace tests\nuv run pytest tests/ -v -m \"huggingface\" -p no:logfire\n\n# Run all tests\nuv run pytest tests/ -v -p no:logfire\n
    "},{"location":"contributing/testing/#test-examples","title":"Test Examples","text":"
    @pytest.mark.unit\nasync def test_pubmed_search(mock_httpx_client):\n    tool = PubMedTool()\n    results = await tool.search(\"metformin\", max_results=5)\n    assert len(results) > 0\n    assert all(isinstance(r, Evidence) for r in results)\n\n@pytest.mark.integration\nasync def test_real_pubmed_search():\n    tool = PubMedTool()\n    results = await tool.search(\"metformin\", max_results=3)\n    assert len(results) <= 3\n
    "},{"location":"contributing/testing/#test-coverage","title":"Test Coverage","text":""},{"location":"contributing/testing/#terminal-coverage-report","title":"Terminal Coverage Report","text":"
    uv run pytest --cov=src --cov-report=term-missing tests/unit/ -v -m \"not openai\" -p no:logfire\n

    This shows coverage with missing lines highlighted in the terminal output.

    "},{"location":"contributing/testing/#html-coverage-report","title":"HTML Coverage Report","text":"
    uv run pytest --cov=src --cov-report=html -p no:logfire\n

    This generates an HTML coverage report in htmlcov/index.html. Open this file in your browser to see detailed coverage information.

    "},{"location":"contributing/testing/#coverage-goals","title":"Coverage Goals","text":""},{"location":"contributing/testing/#see-also","title":"See Also","text":""},{"location":"getting-started/examples/","title":"Examples","text":"

    This page provides examples of using The DETERMINATOR for various research tasks.

    "},{"location":"getting-started/examples/#basic-research-query","title":"Basic Research Query","text":""},{"location":"getting-started/examples/#example-1-drug-information","title":"Example 1: Drug Information","text":"

    Query:

    What are the latest treatments for Alzheimer's disease?\n

    What The DETERMINATOR Does: 1. Searches PubMed for recent papers 2. Searches ClinicalTrials.gov for active trials 3. Evaluates evidence quality 4. Synthesizes findings into a comprehensive report

    "},{"location":"getting-started/examples/#example-2-clinical-trial-search","title":"Example 2: Clinical Trial Search","text":"

    Query:

    What clinical trials are investigating metformin for cancer prevention?\n

    What The DETERMINATOR Does:

    1. Searches ClinicalTrials.gov for relevant trials
    2. Searches PubMed for supporting literature
    3. Provides trial details and status
    4. Summarizes findings
    "},{"location":"getting-started/examples/#advanced-research-queries","title":"Advanced Research Queries","text":""},{"location":"getting-started/examples/#example-3-comprehensive-review","title":"Example 3: Comprehensive Review","text":"

    Query:

    Review the evidence for using metformin as an anti-aging intervention, \nincluding clinical trials, mechanisms of action, and safety profile.\n

    What The DETERMINATOR Does: 1. Uses deep research mode (multi-section) 2. Searches multiple sources in parallel 3. Generates sections on: - Clinical trials - Mechanisms of action - Safety profile 4. Synthesizes comprehensive report

    "},{"location":"getting-started/examples/#example-4-hypothesis-testing","title":"Example 4: Hypothesis Testing","text":"

    Query:

    Test the hypothesis that regular exercise reduces Alzheimer's disease risk.\n

    What The DETERMINATOR Does: 1. Generates testable hypotheses 2. Searches for supporting/contradicting evidence 3. Performs statistical analysis (if Modal configured) 4. Provides verdict: SUPPORTED, REFUTED, or INCONCLUSIVE

    "},{"location":"getting-started/examples/#mcp-tool-examples","title":"MCP Tool Examples","text":""},{"location":"getting-started/examples/#using-search_pubmed","title":"Using search_pubmed","text":"
    Search PubMed for \"CRISPR gene editing cancer therapy\"\n
    "},{"location":"getting-started/examples/#using-search_clinical_trials","title":"Using search_clinical_trials","text":"
    Find active clinical trials for \"diabetes type 2 treatment\"\n
    "},{"location":"getting-started/examples/#using-search_all","title":"Using search_all","text":"
    Search all sources for \"COVID-19 vaccine side effects\"\n
    "},{"location":"getting-started/examples/#using-analyze_hypothesis","title":"Using analyze_hypothesis","text":"
    Analyze whether vitamin D supplementation reduces COVID-19 severity\n
    "},{"location":"getting-started/examples/#code-examples","title":"Code Examples","text":""},{"location":"getting-started/examples/#python-api-usage","title":"Python API Usage","text":"
    from src.orchestrator_factory import create_orchestrator\nfrom src.tools.search_handler import SearchHandler\nfrom src.agent_factory.judges import create_judge_handler\n\n# Create orchestrator\nsearch_handler = SearchHandler()\njudge_handler = create_judge_handler()\n
    # Run research query\nquery = \"What are the latest treatments for Alzheimer's disease?\"\nasync for event in orchestrator.run(query):\n    print(f\"Event: {event.type} - {event.data}\")\n
    "},{"location":"getting-started/examples/#gradio-ui-integration","title":"Gradio UI Integration","text":"
    import gradio as gr\nfrom src.app import create_research_interface\n\n# Create interface\ninterface = create_research_interface()\n\n# Launch\ninterface.launch(server_name=\"0.0.0.0\", server_port=7860)\n
    "},{"location":"getting-started/examples/#research-patterns","title":"Research Patterns","text":""},{"location":"getting-started/examples/#iterative-research","title":"Iterative Research","text":"

    Single-loop research with search-judge-synthesize cycles:

    from src.orchestrator.research_flow import IterativeResearchFlow\n
    async for event in flow.run(query):\n    # Handle events\n    pass\n
    "},{"location":"getting-started/examples/#deep-research","title":"Deep Research","text":"

    Multi-section parallel research:

    from src.orchestrator.research_flow import DeepResearchFlow\n
    async for event in flow.run(query):\n    # Handle events\n    pass\n
    "},{"location":"getting-started/examples/#configuration-examples","title":"Configuration Examples","text":""},{"location":"getting-started/examples/#basic-configuration","title":"Basic Configuration","text":"
    # .env file\nLLM_PROVIDER=openai\nOPENAI_API_KEY=your_key_here\nMAX_ITERATIONS=10\n
    "},{"location":"getting-started/examples/#advanced-configuration","title":"Advanced Configuration","text":"
    # .env file\nLLM_PROVIDER=anthropic\nANTHROPIC_API_KEY=your_key_here\nEMBEDDING_PROVIDER=local\nWEB_SEARCH_PROVIDER=duckduckgo\nMAX_ITERATIONS=20\nDEFAULT_TOKEN_LIMIT=200000\nUSE_GRAPH_EXECUTION=true\n
    "},{"location":"getting-started/examples/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/installation/","title":"Installation","text":"

    This guide will help you install and set up DeepCritical on your system.

    "},{"location":"getting-started/installation/#prerequisites","title":"Prerequisites","text":""},{"location":"getting-started/installation/#installation-steps","title":"Installation Steps","text":""},{"location":"getting-started/installation/#1-install-uv-recommended","title":"1. Install uv (Recommended)","text":"

    uv is a fast Python package installer and resolver. Install it using the standalone installer (recommended):

    Unix/macOS/Linux:

    curl -LsSf https://astral.sh/uv/install.sh | sh\n

    Windows (PowerShell):

    powershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n

    Alternative methods:

    # Using pipx (recommended if you have pipx installed)\npipx install uv\n\n# Or using pip\npip install uv\n

    After installation, restart your terminal or add ~/.cargo/bin to your PATH.

    "},{"location":"getting-started/installation/#2-clone-the-repository","title":"2. Clone the Repository","text":"
    git clone https://github.com/DeepCritical/GradioDemo.git\ncd GradioDemo\n
    "},{"location":"getting-started/installation/#3-install-dependencies","title":"3. Install Dependencies","text":"

    Using uv (recommended):

    uv sync\n

    Using pip:

    pip install -e .\n
    "},{"location":"getting-started/installation/#4-install-optional-dependencies","title":"4. Install Optional Dependencies","text":"

    For embeddings support (local sentence-transformers):

    uv sync --extra embeddings\n

    For Modal sandbox execution:

    uv sync --extra modal\n

    For Magentic orchestration:

    uv sync --extra magentic\n

    Install all extras:

    uv sync --all-extras\n
    "},{"location":"getting-started/installation/#5-configure-environment-variables","title":"5. Configure Environment Variables","text":"

    Create a .env file in the project root:

    # Required: At least one LLM provider\nLLM_PROVIDER=openai  # or \"anthropic\" or \"huggingface\"\nOPENAI_API_KEY=your_openai_api_key_here\n\n# Optional: Other services\nNCBI_API_KEY=your_ncbi_api_key_here  # For higher PubMed rate limits\nMODAL_TOKEN_ID=your_modal_token_id\nMODAL_TOKEN_SECRET=your_modal_token_secret\n

    See the Configuration Guide for all available options.

    "},{"location":"getting-started/installation/#6-verify-installation","title":"6. Verify Installation","text":"

    Run the application:

    uv run gradio run src/app.py\n

    Open your browser to http://localhost:7860 to verify the installation.

    "},{"location":"getting-started/installation/#development-setup","title":"Development Setup","text":"

    For development, install dev dependencies:

    uv sync --all-extras --dev\n

    Install pre-commit hooks:

    uv run pre-commit install\n
    "},{"location":"getting-started/installation/#troubleshooting","title":"Troubleshooting","text":""},{"location":"getting-started/installation/#common-issues","title":"Common Issues","text":"

    Import Errors: - Ensure you've installed all required dependencies - Check that Python 3.11+ is being used

    API Key Errors: - Verify your .env file is in the project root - Check that API keys are correctly formatted - Ensure at least one LLM provider is configured

    Module Not Found: - Run uv sync or pip install -e . again - Check that you're in the correct virtual environment

    Port Already in Use: - Change the port in src/app.py or use environment variable - Kill the process using port 7860

    "},{"location":"getting-started/installation/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/mcp-integration/","title":"MCP Integration","text":"

    The DETERMINATOR exposes a Model Context Protocol (MCP) server, allowing you to use its search tools directly from Claude Desktop or other MCP clients.

    "},{"location":"getting-started/mcp-integration/#what-is-mcp","title":"What is MCP?","text":"

    The Model Context Protocol (MCP) is a standard for connecting AI assistants to external tools and data sources. The DETERMINATOR implements an MCP server that exposes its search capabilities as MCP tools.

    "},{"location":"getting-started/mcp-integration/#mcp-server-url","title":"MCP Server URL","text":"

    When running locally:

    http://localhost:7860/gradio_api/mcp/\n
    "},{"location":"getting-started/mcp-integration/#claude-desktop-configuration","title":"Claude Desktop Configuration","text":""},{"location":"getting-started/mcp-integration/#1-locate-configuration-file","title":"1. Locate Configuration File","text":"

    macOS:

    ~/Library/Application Support/Claude/claude_desktop_config.json\n

    Windows:

    %APPDATA%\\Claude\\claude_desktop_config.json\n

    Linux:

    ~/.config/Claude/claude_desktop_config.json\n

    "},{"location":"getting-started/mcp-integration/#2-add-the-determinator-server","title":"2. Add The DETERMINATOR Server","text":"

    Edit claude_desktop_config.json and add:

    {\n  \"mcpServers\": {\n    \"determinator\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#3-restart-claude-desktop","title":"3. Restart Claude Desktop","text":"

    Close and restart Claude Desktop for changes to take effect.

    "},{"location":"getting-started/mcp-integration/#4-verify-connection","title":"4. Verify Connection","text":"

    In Claude Desktop, you should see The DETERMINATOR tools available: - search_pubmed - search_clinical_trials - search_biorxiv - search_all - analyze_hypothesis

    "},{"location":"getting-started/mcp-integration/#available-tools","title":"Available Tools","text":""},{"location":"getting-started/mcp-integration/#search_pubmed","title":"search_pubmed","text":"

    Search peer-reviewed biomedical literature from PubMed.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search PubMed for \"metformin diabetes\"\n

    "},{"location":"getting-started/mcp-integration/#search_clinical_trials","title":"search_clinical_trials","text":"

    Search ClinicalTrials.gov for interventional studies.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search clinical trials for \"Alzheimer's disease treatment\"\n

    "},{"location":"getting-started/mcp-integration/#search_biorxiv","title":"search_biorxiv","text":"

    Search bioRxiv/medRxiv preprints via Europe PMC.

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results (default: 10)

    Example:

    Search bioRxiv for \"CRISPR gene editing\"\n

    "},{"location":"getting-started/mcp-integration/#search_all","title":"search_all","text":"

    Search all sources simultaneously (PubMed, ClinicalTrials.gov, Europe PMC).

    Parameters: - query (string): Search query - max_results (integer, optional): Maximum number of results per source (default: 10)

    Example:

    Search all sources for \"COVID-19 vaccine efficacy\"\n

    "},{"location":"getting-started/mcp-integration/#analyze_hypothesis","title":"analyze_hypothesis","text":"

    Perform secure statistical analysis using Modal sandboxes.

    Parameters: - hypothesis (string): Hypothesis to analyze - data (string, optional): Data description or code

    Example:

    Analyze the hypothesis that metformin reduces cancer risk\n

    "},{"location":"getting-started/mcp-integration/#using-tools-in-claude-desktop","title":"Using Tools in Claude Desktop","text":"

    Once configured, you can ask Claude to use DeepCritical tools:

    Use DeepCritical to search PubMed for recent papers on Alzheimer's disease treatments.\n

    Claude will automatically: 1. Call the appropriate DeepCritical tool 2. Retrieve results 3. Use the results in its response

    "},{"location":"getting-started/mcp-integration/#troubleshooting","title":"Troubleshooting","text":""},{"location":"getting-started/mcp-integration/#connection-issues","title":"Connection Issues","text":"

    Server Not Found: - Ensure DeepCritical is running (uv run gradio run src/app.py) - Verify the URL in claude_desktop_config.json is correct - Check that port 7860 is not blocked by firewall

    Tools Not Appearing: - Restart Claude Desktop after configuration changes - Check Claude Desktop logs for errors - Verify MCP server is accessible at the configured URL

    "},{"location":"getting-started/mcp-integration/#authentication","title":"Authentication","text":"

    If DeepCritical requires authentication: - Configure API keys in DeepCritical settings - Use HuggingFace OAuth login - Ensure API keys are valid

    "},{"location":"getting-started/mcp-integration/#advanced-configuration","title":"Advanced Configuration","text":""},{"location":"getting-started/mcp-integration/#custom-port","title":"Custom Port","text":"

    If running on a different port, update the URL:

    {\n  \"mcpServers\": {\n    \"deepcritical\": {\n      \"url\": \"http://localhost:8080/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#multiple-instances","title":"Multiple Instances","text":"

    You can configure multiple DeepCritical instances:

    {\n  \"mcpServers\": {\n    \"deepcritical-local\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    },\n    \"deepcritical-remote\": {\n      \"url\": \"https://your-server.com/gradio_api/mcp/\"\n    }\n  }\n}\n
    "},{"location":"getting-started/mcp-integration/#next-steps","title":"Next Steps","text":""},{"location":"getting-started/quick-start/","title":"Single Command Deploy","text":"

    Deploy with docker instandly with a single command :

    docker run -it -p 7860:7860 --platform=linux/amd64 \\\n    -e DB_KEY=\"YOUR_VALUE_HERE\" \\\n    -e SERP_API=\"YOUR_VALUE_HERE\" \\\n    -e INFERENCE_API=\"YOUR_VALUE_HERE\" \\\n    -e MODAL_TOKEN_ID=\"YOUR_VALUE_HERE\" \\\n    -e MODAL_TOKEN_SECRET=\"YOUR_VALUE_HERE\" \\\n    -e NCBI_API_KEY=\"YOUR_VALUE_HERE\" \\\n    -e SERPER_API_KEY=\"YOUR_VALUE_HERE\" \\\n    -e CHROMA_DB_PATH=\"./chroma_db\" \\\n    -e CHROMA_DB_HOST=\"localhost\" \\\n    -e CHROMA_DB_PORT=\"8000\" \\\n    -e RAG_COLLECTION_NAME=\"deepcritical_evidence\" \\\n    -e RAG_SIMILARITY_TOP_K=\"5\" \\\n    -e RAG_AUTO_INGEST=\"true\" \\\n    -e USE_GRAPH_EXECUTION=\"false\" \\\n    -e DEFAULT_TOKEN_LIMIT=\"100000\" \\\n    -e DEFAULT_TIME_LIMIT_MINUTES=\"10\" \\\n    -e DEFAULT_ITERATIONS_LIMIT=\"10\" \\\n    -e WEB_SEARCH_PROVIDER=\"duckduckgo\" \\\n    -e MAX_ITERATIONS=\"10\" \\\n    -e SEARCH_TIMEOUT=\"30\" \\\n    -e LOG_LEVEL=\"DEBUG\" \\\n    -e EMBEDDING_PROVIDER=\"local\" \\\n    -e OPENAI_EMBEDDING_MODEL=\"text-embedding-3-small\" \\\n    -e LOCAL_EMBEDDING_MODEL=\"BAAI/bge-small-en-v1.5\" \\\n    -e HUGGINGFACE_EMBEDDING_MODEL=\"sentence-transformers/all-MiniLM-L6-v2\" \\\n    -e HF_FALLBACK_MODELS=\"Qwen/Qwen3-Next-80B-A3B-Thinking,Qwen/Qwen3-Next-80B-A3B-Instruct,meta-llama/Llama-3.3-70B-Instruct,meta-llama/Llama-3.1-8B-Instruct,HuggingFaceH4/zephyr-7b-beta,Qwen/Qwen2-7B-Instruct\" \\\n    -e HUGGINGFACE_MODEL=\"Qwen/Qwen3-Next-80B-A3B-Thinking\" \\\n    registry.hf.space/dataquests-deepcritical:latest python src/app.py\n   ```\n\n## Quick start guide\n\nGet up and running with The DETERMINATOR in minutes.\n\n## Start the Application\n\n```bash\ngradio src/app.py\n

    Open your browser to http://localhost:7860.

    "},{"location":"getting-started/quick-start/#first-research-query","title":"First Research Query","text":"
    1. Enter a Research Question

    Type your research question in the chat interface, for example: - \"What are the latest treatments for Alzheimer's disease?\" - \"Review the evidence for metformin in cancer prevention\" - \"What clinical trials are investigating COVID-19 vaccines?\"

    1. Submit the Query

    Click \"Submit\" or press Enter. The system will: - Generate observations about your query - Identify knowledge gaps - Search multiple sources (PubMed, ClinicalTrials.gov, Europe PMC) - Evaluate evidence quality - Synthesize findings into a report

    1. Review Results

    Watch the real-time progress in the chat interface: - Search operations and results - Evidence evaluation - Report generation - Final research report with citations

    "},{"location":"getting-started/quick-start/#authentication","title":"Authentication","text":""},{"location":"getting-started/quick-start/#huggingface-oauth-recommended","title":"HuggingFace OAuth (Recommended)","text":"
    1. Click \"Sign in with HuggingFace\" at the top of the app
    2. Authorize the application
    3. Your HuggingFace API token will be automatically used
    4. No need to manually enter API keys
    "},{"location":"getting-started/quick-start/#manual-api-key","title":"Manual API Key","text":"
    1. Open the Settings accordion
    2. Enter your API key:
    3. OpenAI API key
    4. Anthropic API key
    5. HuggingFace API key
    6. Click \"Save Settings\"
    7. Manual keys take priority over OAuth tokens
    "},{"location":"getting-started/quick-start/#understanding-the-interface","title":"Understanding the Interface","text":""},{"location":"getting-started/quick-start/#chat-interface","title":"Chat Interface","text":""},{"location":"getting-started/quick-start/#status-indicators","title":"Status Indicators","text":""},{"location":"getting-started/quick-start/#settings","title":"Settings","text":""},{"location":"getting-started/quick-start/#example-queries","title":"Example Queries","text":""},{"location":"getting-started/quick-start/#simple-query","title":"Simple Query","text":"
    What are the side effects of metformin?\n
    "},{"location":"getting-started/quick-start/#complex-query","title":"Complex Query","text":"
    Review the evidence for using metformin as an anti-aging intervention, \nincluding clinical trials, mechanisms of action, and safety profile.\n
    "},{"location":"getting-started/quick-start/#clinical-trial-query","title":"Clinical Trial Query","text":"
    What are the active clinical trials investigating Alzheimer's disease treatments?\n
    "},{"location":"getting-started/quick-start/#next-steps","title":"Next Steps","text":""},{"location":"overview/architecture/","title":"Architecture Overview","text":"

    The DETERMINATOR is a powerful generalist deep research agent system that uses iterative search-and-judge loops to comprehensively investigate any research question. It stops at nothing until finding precise answers, only stopping at configured limits (budget, time, iterations). The system automatically determines if medical knowledge sources are needed and adapts its search strategy accordingly. It supports multiple orchestration patterns, graph-based execution, parallel research workflows, and long-running task management with real-time streaming.

    "},{"location":"overview/architecture/#core-architecture","title":"Core Architecture","text":""},{"location":"overview/architecture/#orchestration-patterns","title":"Orchestration Patterns","text":"
    1. Graph Orchestrator (src/orchestrator/graph_orchestrator.py):
    2. Graph-based execution using Pydantic AI agents as nodes
    3. Supports both iterative and deep research patterns
    4. Node types: Agent, State, Decision, Parallel
    5. Edge types: Sequential, Conditional, Parallel
    6. Conditional routing based on knowledge gaps, budget, and iterations
    7. Parallel execution for concurrent research loops
    8. Event streaming via AsyncGenerator[AgentEvent] for real-time UI updates
    9. Fallback to agent chains when graph execution is disabled

    10. Deep Research Flow (src/orchestrator/research_flow.py):

    11. Pattern: Planner \u2192 Parallel Iterative Loops (one per section) \u2192 Synthesis
    12. Uses PlannerAgent to break query into report sections
    13. Runs IterativeResearchFlow instances in parallel per section via WorkflowManager
    14. Synthesizes results using LongWriterAgent or ProofreaderAgent
    15. Supports both graph execution (use_graph=True) and agent chains (use_graph=False)
    16. Budget tracking per section and globally
    17. State synchronization across parallel loops

    18. Iterative Research Flow (src/orchestrator/research_flow.py):

    19. Pattern: Generate observations \u2192 Evaluate gaps \u2192 Select tools \u2192 Execute \u2192 Judge \u2192 Continue/Complete
    20. Uses KnowledgeGapAgent, ToolSelectorAgent, ThinkingAgent, WriterAgent
    21. JudgeHandler assesses evidence sufficiency
    22. Iterates until research complete or constraints met (iterations, time, tokens)
    23. Supports graph execution and agent chains

    24. Magentic Orchestrator (src/orchestrator_magentic.py):

    25. Multi-agent coordination using agent-framework-core
    26. ChatAgent pattern with internal LLMs per agent
    27. Uses MagenticBuilder with participants: searcher, hypothesizer, judge, reporter
    28. Manager orchestrates agents via OpenAIChatClient
    29. Requires OpenAI API key (function calling support)
    30. Event-driven: converts Magentic events to AgentEvent for UI streaming
    31. Supports long-running workflows with max rounds and stall/reset handling

    32. Hierarchical Orchestrator (src/orchestrator_hierarchical.py):

    33. Uses SubIterationMiddleware with ResearchTeam and LLMSubIterationJudge
    34. Adapts Magentic ChatAgent to SubIterationTeam protocol
    35. Event-driven via asyncio.Queue for coordination
    36. Supports sub-iteration patterns for complex research tasks

    37. Legacy Simple Mode (src/legacy_orchestrator.py):

    38. Linear search-judge-synthesize loop
    39. Uses SearchHandlerProtocol and JudgeHandlerProtocol
    40. Generator-based design yielding AgentEvent objects
    41. Backward compatibility for simple use cases
    "},{"location":"overview/architecture/#long-running-task-support","title":"Long-Running Task Support","text":"

    The system is designed for long-running research tasks with comprehensive state management and streaming:

    1. Event Streaming:
    2. All orchestrators yield AgentEvent objects via AsyncGenerator
    3. Real-time UI updates through Gradio chat interface
    4. Event types: started, searching, search_complete, judging, judge_complete, looping, synthesizing, hypothesizing, complete, error
    5. Metadata includes iteration numbers, tool names, result counts, durations

    6. Budget Tracking (src/middleware/budget_tracker.py):

    7. Per-loop and global budget management
    8. Tracks: tokens, time (seconds), iterations
    9. Budget enforcement at decision nodes
    10. Token estimation (~4 chars per token)
    11. Early termination when budgets exceeded
    12. Budget summaries for monitoring

    13. Workflow Manager (src/middleware/workflow_manager.py):

    14. Coordinates parallel research loops
    15. Tracks loop status: pending, running, completed, failed, cancelled
    16. Synchronizes evidence between loops and global state
    17. Handles errors per loop (doesn't fail all if one fails)
    18. Supports loop cancellation and timeout handling
    19. Evidence deduplication across parallel loops

    20. State Management (src/middleware/state_machine.py):

    21. Thread-safe isolation using ContextVar for concurrent requests
    22. WorkflowState tracks: evidence, conversation history, embedding service
    23. Evidence deduplication by URL
    24. Semantic search via embedding service
    25. State persistence across long-running workflows
    26. Supports both iterative and deep research patterns

    27. Gradio UI (src/app.py):

    28. Real-time streaming of research progress
    29. Accordion-based UI for pending/done operations
    30. OAuth integration (HuggingFace)
    31. Multiple backend support (API keys, free tier)
    32. Handles long-running tasks with progress indicators
    33. Event accumulation for pending operations
    "},{"location":"overview/architecture/#graph-architecture","title":"Graph Architecture","text":"

    The graph orchestrator (src/orchestrator/graph_orchestrator.py) implements a flexible graph-based execution model:

    Node Types:

    Edge Types:

    Graph Patterns:

    Execution Flow:

    1. Graph construction from nodes and edges
    2. Graph validation (no cycles, all nodes reachable)
    3. Graph execution from entry node
    4. Node execution based on type
    5. Edge evaluation for next node(s)
    6. Parallel execution via asyncio.gather()
    7. State updates at state nodes
    8. Event streaming for UI
    "},{"location":"overview/architecture/#key-components","title":"Key Components","text":""},{"location":"overview/architecture/#research-team--parallel-execution","title":"Research Team & Parallel Execution","text":"

    The system supports complex research workflows through:

    1. WorkflowManager: Coordinates multiple parallel research loops
    2. Creates and tracks ResearchLoop instances
    3. Runs loops in parallel via asyncio.gather()
    4. Synchronizes evidence to global state
    5. Handles loop failures gracefully

    6. Deep Research Pattern: Breaks complex queries into sections

    7. Planner creates report outline with sections
    8. Each section runs as independent iterative research loop
    9. Loops execute in parallel
    10. Evidence shared across loops via global state
    11. Final synthesis combines all section results

    12. State Synchronization: Thread-safe evidence sharing

    13. Evidence deduplication by URL
    14. Global state accessible to all loops
    15. Semantic search across all collected evidence
    16. Conversation history tracking per iteration
    "},{"location":"overview/architecture/#configuration--modes","title":"Configuration & Modes","text":"

    Note: The UI provides separate controls for orchestrator mode and graph research mode. When using graph-based orchestrators (iterative/deep/auto), the graph research mode determines the specific pattern used within the graph execution.

    "},{"location":"overview/features/","title":"Features","text":"

    The DETERMINATOR provides a comprehensive set of features for AI-assisted research:

    "},{"location":"overview/features/#core-features","title":"Core Features","text":""},{"location":"overview/features/#multi-source-search","title":"Multi-Source Search","text":""},{"location":"overview/features/#mcp-integration","title":"MCP Integration","text":""},{"location":"overview/features/#authentication","title":"Authentication","text":""},{"location":"overview/features/#secure-code-execution","title":"Secure Code Execution","text":""},{"location":"overview/features/#semantic-search--rag","title":"Semantic Search & RAG","text":""},{"location":"overview/features/#orchestration-patterns","title":"Orchestration Patterns","text":"

    Orchestrator Modes: - simple: Legacy linear search-judge loop - advanced (or magentic): Multi-agent coordination (requires OpenAI API key) - iterative: Knowledge-gap-driven research with single loop - deep: Parallel section-based research with planning - auto: Intelligent mode detection based on query complexity

    Graph Research Modes (used within graph orchestrator): - iterative: Single research loop pattern - deep: Multi-section parallel research pattern - auto: Auto-detect pattern based on query complexity

    Execution Modes: - use_graph=True: Graph-based execution with parallel and conditional routing - use_graph=False: Agent chains with sequential execution (backward compatible)

    "},{"location":"overview/features/#real-time-streaming","title":"Real-Time Streaming","text":""},{"location":"overview/features/#budget-management","title":"Budget Management","text":""},{"location":"overview/features/#state-management","title":"State Management","text":""},{"location":"overview/features/#multimodal-input--output","title":"Multimodal Input & Output","text":""},{"location":"overview/features/#advanced-features","title":"Advanced Features","text":""},{"location":"overview/features/#agent-system","title":"Agent System","text":""},{"location":"overview/features/#search-tools","title":"Search Tools","text":""},{"location":"overview/features/#error-handling","title":"Error Handling","text":""},{"location":"overview/features/#configuration","title":"Configuration","text":""},{"location":"overview/features/#testing","title":"Testing","text":""},{"location":"overview/features/#ui-features","title":"UI Features","text":""},{"location":"overview/features/#gradio-interface","title":"Gradio Interface","text":""},{"location":"overview/features/#mcp-server","title":"MCP Server","text":""},{"location":"overview/features/#development-features","title":"Development Features","text":""},{"location":"overview/features/#code-quality","title":"Code Quality","text":""},{"location":"overview/features/#documentation","title":"Documentation","text":""},{"location":"overview/quick-start/","title":"Quick Start","text":"

    Get started with DeepCritical in minutes.

    "},{"location":"overview/quick-start/#installation","title":"Installation","text":"
    # Install uv if you haven't already (recommended: standalone installer)\n# Unix/macOS/Linux:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell):\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Alternative: pipx install uv\n# Or: pip install uv\n\n# Sync dependencies\nuv sync\n
    "},{"location":"overview/quick-start/#run-the-ui","title":"Run the UI","text":"
    # Start the Gradio app\nuv run gradio run src/app.py\n

    Open your browser to http://localhost:7860.

    "},{"location":"overview/quick-start/#basic-usage","title":"Basic Usage","text":""},{"location":"overview/quick-start/#1-authentication-required","title":"1. Authentication (REQUIRED)","text":"

    Authentication is mandatory - you must authenticate before using the application. The app will display an error message if you try to use it without authentication.

    HuggingFace OAuth Login (Recommended): - Click the \"Sign in with HuggingFace\" button at the top of the app - Your HuggingFace API token will be automatically used for AI inference - No need to manually enter API keys when logged in

    Manual API Key (Alternative): - Set environment variable HF_TOKEN or HUGGINGFACE_API_KEY before starting the app - The app will automatically use these tokens if OAuth login is not available - Supports HuggingFace API keys only (OpenAI/Anthropic keys are not used in the current implementation)

    "},{"location":"overview/quick-start/#2-start-a-research-query","title":"2. Start a Research Query","text":"
    1. Enter your research question in the chat interface
    2. Text Input: Type your question directly
    3. Image Input: Click the \ud83d\udcf7 icon to upload images (OCR will extract text)
    4. Audio Input: Click the \ud83c\udfa4 icon to record or upload audio (STT will transcribe to text)
    5. Click \"Submit\" or press Enter
    6. Watch the real-time progress as the system:
    7. Generates observations
    8. Identifies knowledge gaps
    9. Searches multiple sources
    10. Evaluates evidence
    11. Synthesizes findings
    12. Review the final research report
    13. Audio Output: If enabled, the final response will include audio synthesis (TTS)

    Multimodal Features: - Configure image/audio input and output in the sidebar settings - Image OCR and audio STT/TTS can be enabled/disabled independently - TTS voice and speed can be customized in the Audio Output settings

    "},{"location":"overview/quick-start/#3-mcp-integration-optional","title":"3. MCP Integration (Optional)","text":"

    Connect DeepCritical to Claude Desktop:

    1. Add to your claude_desktop_config.json:

      {\n  \"mcpServers\": {\n    \"deepcritical\": {\n      \"url\": \"http://localhost:7860/gradio_api/mcp/\"\n    }\n  }\n}\n

    2. Restart Claude Desktop

    3. Use DeepCritical tools directly from Claude Desktop
    "},{"location":"overview/quick-start/#available-tools","title":"Available Tools","text":"

    Note: The application automatically uses all available search tools (Neo4j, PubMed, ClinicalTrials.gov, Europe PMC, Web search, RAG) based on query analysis. Neo4j knowledge graph search is included by default for biomedical queries.

    "},{"location":"overview/quick-start/#next-steps","title":"Next Steps","text":""}]} \ No newline at end of file diff --git a/site/team/index.html b/site/team/index.html index 2465d347..74c22a2e 100644 --- a/site/team/index.html +++ b/site/team/index.html @@ -1 +1 @@ - Team - The DETERMINATOR
    Skip to content

    Team

    DeepCritical is developed by a team of researchers and developers working on AI-assisted research.

    Team Members

    ZJ

    Mario Aderman

    Joseph Pollack

    Virat Chauran

    Anna Bossler

    About

    The DeepCritical team met online in the Alzheimer's Critical Literature Review Group in the Hugging Science initiative. We're building the agent framework we want to use for AI-assisted research to turn the vast amounts of clinical data into cures.

    Contributing

    We welcome contributions! See the Contributing Guide for details.

    \ No newline at end of file + Team - The DETERMINATOR
    Skip to content

    Team

    DeepCritical is developed by a team of researchers and developers working on AI-assisted research.

    Team Members

    ZJ

    Mario Aderman

    Joseph Pollack

    Virat Chauran

    Anna Bossler

    About

    The DeepCritical team met online in the Alzheimer's Critical Literature Review Group in the Hugging Science initiative. We're building the agent framework we want to use for AI-assisted research to turn the vast amounts of clinical data into cures.

    Contributing

    We welcome contributions! See the Contributing Guide for details.

    \ No newline at end of file diff --git a/src/middleware/state_machine.py b/src/middleware/state_machine.py index 05fce970..d43e131e 100644 --- a/src/middleware/state_machine.py +++ b/src/middleware/state_machine.py @@ -136,3 +136,4 @@ def get_workflow_state() -> WorkflowState: + diff --git a/src/tools/searchxng_web_search.py b/src/tools/searchxng_web_search.py index 7dfda3ca..80cf8be5 100644 --- a/src/tools/searchxng_web_search.py +++ b/src/tools/searchxng_web_search.py @@ -122,3 +122,4 @@ async def search(self, query: str, max_results: int = 10) -> list[Evidence]: + diff --git a/src/tools/serper_web_search.py b/src/tools/serper_web_search.py index 4c486f12..79e9449e 100644 --- a/src/tools/serper_web_search.py +++ b/src/tools/serper_web_search.py @@ -122,3 +122,4 @@ async def search(self, query: str, max_results: int = 10) -> list[Evidence]: + diff --git a/src/tools/vendored/crawl_website.py b/src/tools/vendored/crawl_website.py index 75e12ac2..32fc2d94 100644 --- a/src/tools/vendored/crawl_website.py +++ b/src/tools/vendored/crawl_website.py @@ -134,3 +134,4 @@ async def fetch_page(url: str) -> str: + diff --git a/src/tools/vendored/searchxng_client.py b/src/tools/vendored/searchxng_client.py index 0f4754b1..2cf4ce83 100644 --- a/src/tools/vendored/searchxng_client.py +++ b/src/tools/vendored/searchxng_client.py @@ -103,3 +103,4 @@ async def search( + diff --git a/src/tools/vendored/serper_client.py b/src/tools/vendored/serper_client.py index d165aed4..6b54c10b 100644 --- a/src/tools/vendored/serper_client.py +++ b/src/tools/vendored/serper_client.py @@ -99,3 +99,4 @@ async def search( + diff --git a/src/tools/vendored/web_search_core.py b/src/tools/vendored/web_search_core.py index bcc5caca..391b5c2e 100644 --- a/src/tools/vendored/web_search_core.py +++ b/src/tools/vendored/web_search_core.py @@ -208,3 +208,4 @@ def is_valid_url(url: str) -> bool: + diff --git a/src/tools/web_search_factory.py b/src/tools/web_search_factory.py index 73d92d1e..fae4c5ff 100644 --- a/src/tools/web_search_factory.py +++ b/src/tools/web_search_factory.py @@ -75,3 +75,4 @@ def create_web_search_tool() -> SearchTool | None: + diff --git a/src/utils/markdown.css b/src/utils/markdown.css index 4a73fdd7..b083c296 100644 --- a/src/utils/markdown.css +++ b/src/utils/markdown.css @@ -13,3 +13,4 @@ body { + diff --git a/src/utils/md_to_pdf.py b/src/utils/md_to_pdf.py index d8848a66..940d707d 100644 --- a/src/utils/md_to_pdf.py +++ b/src/utils/md_to_pdf.py @@ -73,3 +73,4 @@ def md_to_pdf(md_text: str, pdf_file_path: str) -> None: + diff --git a/src/utils/report_generator.py b/src/utils/report_generator.py index 2c20623c..ad283050 100644 --- a/src/utils/report_generator.py +++ b/src/utils/report_generator.py @@ -176,3 +176,4 @@ def generate_report_from_evidence( + diff --git a/tests/unit/middleware/test_budget_tracker_phase7.py b/tests/unit/middleware/test_budget_tracker_phase7.py index 3338ad03..903addc1 100644 --- a/tests/unit/middleware/test_budget_tracker_phase7.py +++ b/tests/unit/middleware/test_budget_tracker_phase7.py @@ -159,3 +159,4 @@ def test_iteration_tokens_separate_per_loop(self) -> None: assert budget2.iteration_tokens[1] == 200 + diff --git a/tests/unit/middleware/test_state_machine.py b/tests/unit/middleware/test_state_machine.py index d03722dc..90fc3a4d 100644 --- a/tests/unit/middleware/test_state_machine.py +++ b/tests/unit/middleware/test_state_machine.py @@ -357,3 +357,4 @@ def context2(): + diff --git a/tests/unit/middleware/test_workflow_manager.py b/tests/unit/middleware/test_workflow_manager.py index 42d67658..3703390c 100644 --- a/tests/unit/middleware/test_workflow_manager.py +++ b/tests/unit/middleware/test_workflow_manager.py @@ -285,3 +285,4 @@ async def test_get_shared_evidence(self, monkeypatch) -> None: assert len(shared) == 1 assert shared[0].content == "Shared" +