Claude commited on
Commit
59ce7b1
Β·
unverified Β·
1 Parent(s): af58641

docs: Add comprehensive documentation structure

Browse files

Add professional documentation structure with:

Root-level standard docs:
- CONTRIBUTING.md - Contribution guidelines
- CHANGELOG.md - Release history tracking
- SECURITY.md - Vulnerability reporting policy
- CODE_OF_CONDUCT.md - Community standards

Documentation index:
- docs/README.md - Navigation and overview

Getting started guides:
- installation.md - Setup instructions
- quickstart.md - 5-minute guide
- configuration.md - Configuration options
- troubleshooting.md - Common issues

Architecture documentation:
- overview.md - High-level architecture
- component-inventory.md - Complete module catalog
- data-models.md - Pydantic model reference
- exception-hierarchy.md - Exception types

Development guides:
- testing.md - Testing strategy and patterns
- code-style.md - Style conventions
- release-process.md - Release workflow

Deployment guides:
- docker.md - Container deployment
- huggingface-spaces.md - Cloud deployment
- mcp-integration.md - MCP server setup

Technical debt tracking:
- index.md - Debt overview
- debt-registry.md - Itemized debt items (14 tracked)

Reference documentation:
- configuration.md - All config options
- environment-variables.md - Env var reference

CHANGELOG.md ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog
2
+
3
+ All notable changes to DeepBoner will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - Comprehensive documentation structure (CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md)
12
+ - Technical debt tracking documentation
13
+ - Component inventory documentation
14
+ - Data models reference documentation
15
+
16
+ ## [0.1.0] - 2025-12-04
17
+
18
+ ### Added
19
+ - **Core Research Agent**
20
+ - Search-and-judge loop with multi-tool orchestration
21
+ - PubMed E-utilities API integration
22
+ - ClinicalTrials.gov API integration
23
+ - Europe PMC API integration
24
+ - OpenAlex API integration
25
+ - LLM-based evidence quality assessment (Judge)
26
+ - Research report synthesis with citations
27
+
28
+ - **Multi-Agent Architecture**
29
+ - Microsoft Agent Framework integration (Magentic)
30
+ - SearchAgent, JudgeAgent, ReportAgent coordination
31
+ - Pydantic AI structured outputs
32
+ - LangGraph workflow state management (experimental)
33
+
34
+ - **Dual-Backend LLM Support**
35
+ - Free tier: HuggingFace Inference API (Qwen 2.5 7B)
36
+ - Paid tier: OpenAI GPT-5 (auto-detected with API key)
37
+ - Factory pattern for backend selection
38
+
39
+ - **Evidence Processing**
40
+ - Cross-source deduplication by PMID/DOI
41
+ - ChromaDB + Sentence-Transformers for embeddings
42
+ - LlamaIndex RAG support (premium tier)
43
+ - Citation validation and formatting
44
+
45
+ - **User Interface**
46
+ - Gradio streaming UI
47
+ - MCP (Model Context Protocol) server integration
48
+ - Claude Desktop tool support
49
+
50
+ - **Developer Experience**
51
+ - Makefile with common commands
52
+ - Pre-commit hooks (ruff, mypy)
53
+ - Comprehensive test suite (unit, integration, e2e)
54
+ - GitHub Actions CI/CD pipeline
55
+ - Docker support with model pre-loading
56
+
57
+ - **Documentation**
58
+ - README with quick start guide
59
+ - CLAUDE.md/AGENTS.md for AI agent guidance
60
+ - Architecture documentation with Mermaid diagrams
61
+ - Example scripts for all major features
62
+
63
+ ### Technical Notes
64
+
65
+ This release represents the completion of Phases 1-14 of the original development plan:
66
+
67
+ 1. Foundation (project structure, TDD setup)
68
+ 2. PubMed search implementation
69
+ 3. ClinicalTrials.gov integration
70
+ 4. Basic orchestrator loop
71
+ 5. Evidence quality judgment
72
+ 6. Report synthesis
73
+ 7. Europe PMC integration
74
+ 8. Evidence deduplication
75
+ 9. Advanced search refinement
76
+ 10. Hypothesis generation
77
+ 11. Mechanistic pathway analysis
78
+ 12. LangGraph workflow
79
+ 13. Microsoft Agent Framework integration
80
+ 14. Demo submission
81
+
82
+ ### Known Issues
83
+
84
+ See `docs/technical-debt/` for documented technical debt and known issues.
85
+
86
+ ---
87
+
88
+ ## Release Notes Format
89
+
90
+ For each release, document:
91
+
92
+ ### Added
93
+ New features and capabilities
94
+
95
+ ### Changed
96
+ Changes to existing functionality
97
+
98
+ ### Deprecated
99
+ Features that will be removed in future versions
100
+
101
+ ### Removed
102
+ Features that were removed
103
+
104
+ ### Fixed
105
+ Bug fixes
106
+
107
+ ### Security
108
+ Security-related changes
109
+
110
+ ---
111
+
112
+ [Unreleased]: https://github.com/The-Obstacle-Is-The-Way/DeepBoner/compare/v0.1.0...HEAD
113
+ [0.1.0]: https://github.com/The-Obstacle-Is-The-Way/DeepBoner/releases/tag/v0.1.0
CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or advances of any kind
22
+ * Trolling, insulting or derogatory comments, and personal or political attacks
23
+ * Public or private harassment
24
+ * Publishing others' private information without their explicit permission
25
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
26
+
27
+ ## Project-Specific Guidelines
28
+
29
+ Given DeepBoner's focus on sexual health research:
30
+
31
+ ### Respectful Discussion
32
+ - Sexual health is a legitimate medical topic deserving serious discussion
33
+ - Approach all topics with professionalism and scientific rigor
34
+ - Avoid jokes or comments that trivialize sexual health issues
35
+ - Remember that users may be dealing with personal health concerns
36
+
37
+ ### Inclusive Language
38
+ - Use inclusive, gender-neutral language when possible
39
+ - Recognize that sexual health affects all genders
40
+ - Avoid assumptions about users' identities or experiences
41
+
42
+ ### Scientific Integrity
43
+ - Base discussions on peer-reviewed evidence when possible
44
+ - Clearly distinguish between established science and speculation
45
+ - Respect the complexity of medical topics
46
+
47
+ ## Enforcement Responsibilities
48
+
49
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
50
+
51
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
52
+
53
+ ## Scope
54
+
55
+ This Code of Conduct applies within all community spaces, including:
56
+ - GitHub repository (issues, PRs, discussions)
57
+ - Discord/Slack channels (if applicable)
58
+ - Project-related social media
59
+ - Events and meetups
60
+
61
+ It also applies when an individual is officially representing the community in public spaces.
62
+
63
+ ## Enforcement
64
+
65
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement via:
66
+
67
+ 1. GitHub's reporting features
68
+ 2. Direct message to maintainers
69
+ 3. Email to repository owners
70
+
71
+ All complaints will be reviewed and investigated promptly and fairly.
72
+
73
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
74
+
75
+ ## Enforcement Guidelines
76
+
77
+ Community leaders will follow these Community Impact Guidelines:
78
+
79
+ ### 1. Correction
80
+
81
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional.
82
+
83
+ **Consequence**: A private, written warning providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
84
+
85
+ ### 2. Warning
86
+
87
+ **Community Impact**: A violation through a single incident or series of actions.
88
+
89
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved for a specified period. This includes avoiding interactions in community spaces as well as external channels. Violating these terms may lead to a temporary or permanent ban.
90
+
91
+ ### 3. Temporary Ban
92
+
93
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
94
+
95
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period. No public or private interaction with the people involved is allowed. Violating these terms may lead to a permanent ban.
96
+
97
+ ### 4. Permanent Ban
98
+
99
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
100
+
101
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
102
+
103
+ ## Attribution
104
+
105
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
106
+
107
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
108
+
109
+ ---
110
+
111
+ *"We take evidence-based community standards very seriously."* 🀝
CONTRIBUTING.md ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributing to DeepBoner
2
+
3
+ Thank you for your interest in contributing to DeepBoner! This document provides guidelines and instructions for contributing to the project.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Code of Conduct](#code-of-conduct)
8
+ - [Getting Started](#getting-started)
9
+ - [Development Setup](#development-setup)
10
+ - [Making Changes](#making-changes)
11
+ - [Testing](#testing)
12
+ - [Submitting Changes](#submitting-changes)
13
+ - [Code Style](#code-style)
14
+ - [Documentation](#documentation)
15
+
16
+ ## Code of Conduct
17
+
18
+ Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) to keep our community welcoming and respectful.
19
+
20
+ ## Getting Started
21
+
22
+ ### Prerequisites
23
+
24
+ - Python 3.11 or higher
25
+ - [uv](https://github.com/astral-sh/uv) package manager
26
+ - Git
27
+
28
+ ### Development Setup
29
+
30
+ 1. **Fork the repository** on GitHub
31
+
32
+ 2. **Clone your fork**:
33
+ ```bash
34
+ git clone https://github.com/YOUR_USERNAME/DeepBoner.git
35
+ cd DeepBoner
36
+ ```
37
+
38
+ 3. **Install dependencies**:
39
+ ```bash
40
+ make install
41
+ # or manually:
42
+ uv sync --all-extras && uv run pre-commit install
43
+ ```
44
+
45
+ 4. **Copy the environment template**:
46
+ ```bash
47
+ cp .env.example .env
48
+ # Edit .env with your API keys if needed
49
+ ```
50
+
51
+ 5. **Verify your setup**:
52
+ ```bash
53
+ make check
54
+ ```
55
+
56
+ ## Making Changes
57
+
58
+ ### Branch Naming Convention
59
+
60
+ - `feature/short-description` - New features
61
+ - `fix/short-description` - Bug fixes
62
+ - `docs/short-description` - Documentation changes
63
+ - `refactor/short-description` - Code refactoring
64
+ - `test/short-description` - Test additions/improvements
65
+
66
+ ### Commit Message Format
67
+
68
+ We follow conventional commit messages:
69
+
70
+ ```
71
+ type(scope): short description
72
+
73
+ Optional longer description explaining the change.
74
+
75
+ Closes #123
76
+ ```
77
+
78
+ Types:
79
+ - `feat` - New feature
80
+ - `fix` - Bug fix
81
+ - `docs` - Documentation only
82
+ - `style` - Code style (formatting, no logic change)
83
+ - `refactor` - Code refactoring
84
+ - `test` - Adding/updating tests
85
+ - `chore` - Build process, tooling, dependencies
86
+
87
+ Examples:
88
+ ```
89
+ feat(tools): add OpenAlex API integration
90
+ fix(pubmed): handle empty search results gracefully
91
+ docs(readme): update quick start instructions
92
+ ```
93
+
94
+ ## Testing
95
+
96
+ ### Running Tests
97
+
98
+ ```bash
99
+ # Run all tests
100
+ make test
101
+
102
+ # Run with coverage
103
+ make test-cov
104
+
105
+ # Run specific test file
106
+ uv run pytest tests/unit/utils/test_config.py -v
107
+
108
+ # Run specific test
109
+ uv run pytest tests/unit/utils/test_config.py::TestSettings::test_default_max_iterations -v
110
+ ```
111
+
112
+ ### Test Markers
113
+
114
+ - `@pytest.mark.unit` - Unit tests (mocked, fast)
115
+ - `@pytest.mark.integration` - Integration tests (real APIs)
116
+ - `@pytest.mark.slow` - Slow tests
117
+ - `@pytest.mark.e2e` - End-to-end tests
118
+
119
+ ### Writing Tests
120
+
121
+ - **TDD preferred**: Write tests first, then implementation
122
+ - **Location**: Place unit tests in `tests/unit/` mirroring `src/` structure
123
+ - **Mocking**: Use `respx` for httpx, `pytest-mock` for general mocking
124
+ - **Fixtures**: Add reusable fixtures to `tests/conftest.py`
125
+
126
+ Example test structure:
127
+ ```python
128
+ """Tests for search handler module."""
129
+ import pytest
130
+ from src.tools.search_handler import SearchHandler
131
+
132
+ class TestSearchHandler:
133
+ """Tests for SearchHandler class."""
134
+
135
+ @pytest.mark.unit
136
+ def test_parallel_search_returns_results(self, mock_httpx_client):
137
+ """Verify parallel search aggregates results correctly."""
138
+ handler = SearchHandler()
139
+ result = handler.search("test query")
140
+ assert len(result.evidence) > 0
141
+ ```
142
+
143
+ ## Code Style
144
+
145
+ ### Pre-commit Hooks
146
+
147
+ Pre-commit hooks run automatically on commit:
148
+ - **Ruff** - Linting and formatting
149
+ - **MyPy** - Type checking
150
+
151
+ To run manually:
152
+ ```bash
153
+ make lint # Check linting
154
+ make format # Auto-format code
155
+ make typecheck # Type checking
156
+ ```
157
+
158
+ ### Style Guidelines
159
+
160
+ 1. **Type hints required** - All functions must have type annotations
161
+ 2. **Docstrings** - Use Google-style docstrings for public APIs
162
+ 3. **Line length** - Maximum 100 characters
163
+ 4. **Imports** - Sorted by isort (handled by ruff)
164
+
165
+ ### Code Quality Rules
166
+
167
+ We use Ruff with these rule sets:
168
+ - `E` - pycodestyle errors
169
+ - `F` - pyflakes
170
+ - `B` - flake8-bugbear
171
+ - `I` - isort
172
+ - `N` - pep8-naming
173
+ - `UP` - pyupgrade
174
+ - `PL` - pylint
175
+ - `RUF` - ruff-specific
176
+
177
+ ## Submitting Changes
178
+
179
+ ### Pull Request Process
180
+
181
+ 1. **Ensure tests pass**: `make check`
182
+ 2. **Update documentation** if adding features
183
+ 3. **Create PR** against `main` branch
184
+ 4. **Fill out the PR template** with:
185
+ - Summary of changes
186
+ - Related issues
187
+ - Test plan
188
+ 5. **Wait for review** - Address any feedback
189
+
190
+ ### PR Checklist
191
+
192
+ - [ ] Tests added/updated and passing
193
+ - [ ] `make check` passes locally
194
+ - [ ] Documentation updated (if applicable)
195
+ - [ ] Commit messages follow convention
196
+ - [ ] No secrets or API keys committed
197
+ - [ ] Changes are focused (one concern per PR)
198
+
199
+ ## Documentation
200
+
201
+ ### Where to Document
202
+
203
+ - **README.md** - User-facing overview and quick start
204
+ - **CLAUDE.md** - Developer/AI agent reference
205
+ - **docs/** - Detailed documentation
206
+ - `architecture/` - System design
207
+ - `development/` - Developer guides
208
+ - `deployment/` - Deployment instructions
209
+ - `reference/` - API/config reference
210
+
211
+ ### Documentation Standards
212
+
213
+ - Use clear, concise language
214
+ - Include code examples where helpful
215
+ - Keep diagrams updated (Mermaid format)
216
+ - Link to related documentation
217
+
218
+ ## Getting Help
219
+
220
+ - **Issues**: Open a GitHub issue for bugs or feature requests
221
+ - **Discussions**: Use GitHub Discussions for questions
222
+
223
+ ## Recognition
224
+
225
+ Contributors will be recognized in release notes. Thank you for helping make DeepBoner better!
226
+
227
+ ---
228
+
229
+ *"Peer-reviewed contributions only. We take evidence-based code very seriously."* πŸ”¬
SECURITY.md ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | ------------------ |
7
+ | 0.1.x | :white_check_mark: |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ We take security seriously. If you discover a security vulnerability in DeepBoner, please report it responsibly.
12
+
13
+ ### How to Report
14
+
15
+ 1. **DO NOT** open a public GitHub issue for security vulnerabilities
16
+ 2. Email security concerns to the repository maintainers via GitHub's private vulnerability reporting
17
+ 3. Or use GitHub's Security Advisory feature: **Security** tab > **Report a vulnerability**
18
+
19
+ ### What to Include
20
+
21
+ - Description of the vulnerability
22
+ - Steps to reproduce
23
+ - Potential impact
24
+ - Suggested fix (if any)
25
+
26
+ ### Response Timeline
27
+
28
+ - **Acknowledgment**: Within 48 hours
29
+ - **Initial assessment**: Within 7 days
30
+ - **Fix timeline**: Depends on severity
31
+ - Critical: Within 48 hours
32
+ - High: Within 7 days
33
+ - Medium: Within 30 days
34
+ - Low: Next release cycle
35
+
36
+ ## Security Measures
37
+
38
+ ### API Key Handling
39
+
40
+ - API keys are loaded from environment variables only
41
+ - Keys are never logged or exposed in error messages
42
+ - `.env` files are gitignored
43
+ - No hardcoded credentials in source code
44
+
45
+ ### Dependency Security
46
+
47
+ - Regular dependency audits via `pip-audit`
48
+ - Security scanning with `bandit` in CI
49
+ - Pinned dependencies for reproducibility
50
+ - Known CVE fixes:
51
+ - `mcp>=1.23.0` - Fixes GHSA-9h52-p55h-vw2f
52
+ - `langgraph-checkpoint-sqlite>=3.0.0` - Fixes GHSA-wwqv-p2pp-99h5
53
+ - `urllib3>=2.6.0` - Fixes GHSA-gm62-xv2j-4w53 and GHSA-2xpw-w6gg-jr37
54
+
55
+ ### External API Security
56
+
57
+ - HTTPS enforced for all external API calls
58
+ - Rate limiting prevents abuse
59
+ - No sensitive data sent to external services (only search queries)
60
+
61
+ ### Input Validation
62
+
63
+ - Pydantic models for strict input validation
64
+ - Query sanitization before external API calls
65
+ - Length limits on user inputs
66
+
67
+ ## Security Best Practices for Users
68
+
69
+ ### API Keys
70
+
71
+ 1. Never commit `.env` files
72
+ 2. Use environment variables in production
73
+ 3. Rotate keys periodically
74
+ 4. Use minimal permissions (read-only where possible)
75
+
76
+ ### Deployment
77
+
78
+ 1. Use the provided Docker image for consistency
79
+ 2. Keep dependencies updated
80
+ 3. Monitor for security advisories
81
+ 4. Use HTTPS in production
82
+
83
+ ### HuggingFace Spaces
84
+
85
+ 1. Use Secrets (not public variables) for API keys
86
+ 2. The HF_TOKEN is used server-side only
87
+ 3. Users don't need their own tokens
88
+
89
+ ## Known Security Considerations
90
+
91
+ ### Third-Party APIs
92
+
93
+ DeepBoner queries external biomedical databases:
94
+ - PubMed (NCBI)
95
+ - ClinicalTrials.gov
96
+ - Europe PMC
97
+ - OpenAlex
98
+
99
+ These are trusted public APIs, but:
100
+ - Query content is visible to these services
101
+ - Rate limits apply
102
+ - Availability depends on upstream services
103
+
104
+ ### LLM Providers
105
+
106
+ - OpenAI and HuggingFace process your queries
107
+ - Review their privacy policies if handling sensitive research
108
+ - Consider on-premise alternatives for sensitive use cases
109
+
110
+ ### Local Data
111
+
112
+ - ChromaDB stores embeddings locally
113
+ - Default path: `./chroma_db/`
114
+ - Contains processed search results (not raw user data)
115
+ - Secure or delete when decommissioning
116
+
117
+ ## Security Updates
118
+
119
+ Security updates will be released as patch versions (e.g., 0.1.1) and announced via:
120
+ - GitHub Security Advisories
121
+ - Release notes
122
+
123
+ ---
124
+
125
+ *"Security is rock solid. We take evidence-based security very seriously."* πŸ”
docs/README.md ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DeepBoner Documentation
2
+
3
+ Welcome to the DeepBoner documentation. This directory contains comprehensive documentation for developers, contributors, and operators.
4
+
5
+ ## Quick Navigation
6
+
7
+ | Need to... | Go to... |
8
+ |------------|----------|
9
+ | Get started quickly | [Getting Started](getting-started/installation.md) |
10
+ | Understand the architecture | [Architecture Overview](architecture/overview.md) |
11
+ | Set up for development | [Development Guide](development/testing.md) |
12
+ | Deploy the application | [Deployment Guide](deployment/docker.md) |
13
+ | Look up configuration | [Reference](reference/configuration.md) |
14
+ | Track technical debt | [Technical Debt](technical-debt/index.md) |
15
+
16
+ ## Documentation Structure
17
+
18
+ ```
19
+ docs/
20
+ β”œβ”€β”€ README.md # This file - documentation index
21
+ β”‚
22
+ β”œβ”€β”€ getting-started/ # Onboarding documentation
23
+ β”‚ β”œβ”€β”€ installation.md # Installation guide
24
+ β”‚ β”œβ”€β”€ quickstart.md # 5-minute quickstart
25
+ β”‚ β”œβ”€β”€ configuration.md # Configuration guide
26
+ β”‚ └── troubleshooting.md # Common issues and solutions
27
+ β”‚
28
+ β”œβ”€β”€ architecture/ # System design documentation
29
+ β”‚ β”œβ”€β”€ overview.md # High-level architecture
30
+ β”‚ β”œβ”€β”€ system-registry.md # Service registry (canonical wiring)
31
+ β”‚ β”œβ”€β”€ workflow-diagrams.md # Visual workflow diagrams
32
+ β”‚ β”œβ”€β”€ component-inventory.md # Complete component catalog
33
+ β”‚ β”œβ”€β”€ data-models.md # Pydantic model documentation
34
+ β”‚ └── exception-hierarchy.md # Exception types and handling
35
+ β”‚
36
+ β”œβ”€β”€ development/ # Developer guides
37
+ β”‚ β”œβ”€β”€ testing.md # Testing strategy and patterns
38
+ β”‚ β”œβ”€β”€ code-style.md # Code style and conventions
39
+ β”‚ └── release-process.md # Release workflow
40
+ β”‚
41
+ β”œβ”€β”€ deployment/ # Deployment documentation
42
+ β”‚ β”œβ”€β”€ docker.md # Docker deployment
43
+ β”‚ β”œβ”€β”€ huggingface-spaces.md # HuggingFace Spaces deployment
44
+ β”‚ └── mcp-integration.md # MCP server setup
45
+ β”‚
46
+ β”œβ”€β”€ technical-debt/ # Known issues and improvements
47
+ β”‚ β”œβ”€β”€ index.md # Technical debt overview
48
+ β”‚ └── debt-registry.md # Itemized debt tracking
49
+ β”‚
50
+ β”œβ”€β”€ reference/ # API and configuration reference
51
+ β”‚ β”œβ”€β”€ configuration.md # All configuration options
52
+ β”‚ └── environment-variables.md # Environment variable reference
53
+ β”‚
54
+ β”œβ”€β”€ bugs/ # Bug tracking (existing)
55
+ β”‚ β”œβ”€β”€ active-bugs.md
56
+ β”‚ └── p3-progress-bar-positioning.md
57
+ β”‚
58
+ β”œβ”€β”€ decisions/ # Architecture Decision Records (existing)
59
+ β”‚ └── 2025-11-27-pr55-evaluation.md
60
+ β”‚
61
+ └── future-roadmap/ # Future feature specs (existing)
62
+ └── 16-pubmed-fulltext.md
63
+ ```
64
+
65
+ ## Documentation Standards
66
+
67
+ ### File Naming
68
+ - Use **kebab-case** for all filenames (e.g., `getting-started.md`)
69
+ - Keep names descriptive but concise
70
+
71
+ ### Content Guidelines
72
+ - Start each document with a clear title and purpose
73
+ - Include a table of contents for longer documents
74
+ - Use Mermaid diagrams for visual documentation
75
+ - Link to related documentation
76
+ - Keep content current - update when code changes
77
+
78
+ ### Markdown Conventions
79
+ - Use ATX-style headers (`#`, `##`, etc.)
80
+ - Code blocks with language specification
81
+ - Tables for structured data
82
+ - Admonitions for warnings/notes (where supported)
83
+
84
+ ## Key Documents
85
+
86
+ ### For New Developers
87
+ 1. [Installation](getting-started/installation.md) - Set up your environment
88
+ 2. [Quickstart](getting-started/quickstart.md) - Run your first query
89
+ 3. [Architecture Overview](architecture/overview.md) - Understand the system
90
+ 4. [Testing](development/testing.md) - Run and write tests
91
+
92
+ ### For Contributors
93
+ 1. [CONTRIBUTING.md](../CONTRIBUTING.md) - Contribution guidelines
94
+ 2. [Code Style](development/code-style.md) - Style conventions
95
+ 3. [Testing](development/testing.md) - Testing requirements
96
+
97
+ ### For Operators
98
+ 1. [Docker Deployment](deployment/docker.md) - Container deployment
99
+ 2. [HuggingFace Spaces](deployment/huggingface-spaces.md) - Cloud deployment
100
+ 3. [Configuration Reference](reference/configuration.md) - All options
101
+
102
+ ### For Understanding the Codebase
103
+ 1. [Component Inventory](architecture/component-inventory.md) - All modules
104
+ 2. [Data Models](architecture/data-models.md) - Core types
105
+ 3. [System Registry](architecture/system-registry.md) - Service wiring
106
+ 4. [Technical Debt](technical-debt/index.md) - Known issues
107
+
108
+ ## Related Documentation
109
+
110
+ - **[README.md](../README.md)** - Project overview and quick start
111
+ - **[CLAUDE.md](../CLAUDE.md)** - AI agent developer reference
112
+ - **[CHANGELOG.md](../CHANGELOG.md)** - Release history
113
+ - **[SECURITY.md](../SECURITY.md)** - Security policy
114
+ - **[CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md)** - Community guidelines
115
+
116
+ ## Contributing to Documentation
117
+
118
+ Documentation is code. Please:
119
+
120
+ 1. Keep docs updated when changing related code
121
+ 2. Follow the naming and style conventions
122
+ 3. Test links before committing
123
+ 4. Add new documents to this index
124
+
125
+ See [CONTRIBUTING.md](../CONTRIBUTING.md) for full guidelines.
126
+
127
+ ---
128
+
129
+ *"Well-documented boners only. We take evidence-based documentation very seriously."* πŸ“š
docs/architecture/component-inventory.md ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Component Inventory
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document provides a complete catalog of all components in the DeepBoner codebase.
6
+
7
+ ## Source Code Statistics
8
+
9
+ | Category | Count |
10
+ |----------|-------|
11
+ | Python files in `src/` | ~67 |
12
+ | Python files in `tests/` | ~76 |
13
+ | Total modules | ~143 |
14
+
15
+ ## Directory Structure
16
+
17
+ ```
18
+ src/
19
+ β”œβ”€β”€ app.py # Gradio UI entry point
20
+ β”œβ”€β”€ mcp_tools.py # MCP server tool wrappers
21
+ β”œβ”€β”€ orchestrators/ # Research orchestration
22
+ β”œβ”€β”€ clients/ # LLM backend adapters
23
+ β”œβ”€β”€ agents/ # Multi-agent components
24
+ β”œβ”€β”€ agent_factory/ # Agent creation
25
+ β”œβ”€β”€ tools/ # Search tool implementations
26
+ β”œβ”€β”€ services/ # Cross-cutting services
27
+ β”œβ”€β”€ prompts/ # LLM prompt templates
28
+ β”œβ”€β”€ utils/ # Shared utilities
29
+ β”œβ”€β”€ config/ # Domain configuration
30
+ β”œβ”€β”€ middleware/ # Processing middleware
31
+ └── state/ # State management
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Core Entry Points
37
+
38
+ ### `src/app.py`
39
+ **Purpose:** Main application entry point
40
+
41
+ | Component | Type | Description |
42
+ |-----------|------|-------------|
43
+ | `create_demo()` | Function | Creates Gradio interface |
44
+ | `main()` | Function | Application entry point |
45
+
46
+ **Dependencies:** Gradio, orchestrators, config
47
+
48
+ ### `src/mcp_tools.py`
49
+ **Purpose:** MCP (Model Context Protocol) tool wrappers
50
+
51
+ | Component | Type | Description |
52
+ |-----------|------|-------------|
53
+ | `search_pubmed()` | Tool | PubMed search wrapper |
54
+ | `search_clinical_trials()` | Tool | ClinicalTrials.gov wrapper |
55
+ | `search_europepmc()` | Tool | Europe PMC wrapper |
56
+ | `search_all_sources()` | Tool | Multi-source search |
57
+
58
+ ---
59
+
60
+ ## Orchestrators (`src/orchestrators/`)
61
+
62
+ ### `advanced.py`
63
+ **Purpose:** Main multi-agent orchestrator using Microsoft Agent Framework
64
+
65
+ | Component | Type | Description |
66
+ |-----------|------|-------------|
67
+ | `AdvancedOrchestrator` | Class | Primary research orchestrator |
68
+ | `run()` | Method | Execute research workflow |
69
+ | `_search_phase()` | Method | Search execution |
70
+ | `_judge_phase()` | Method | Evidence evaluation |
71
+ | `_synthesize_phase()` | Method | Report generation |
72
+
73
+ **Framework:** Microsoft Agent Framework (agent-framework-core)
74
+
75
+ ### `factory.py`
76
+ **Purpose:** Orchestrator selection
77
+
78
+ | Component | Type | Description |
79
+ |-----------|------|-------------|
80
+ | `OrchestratorFactory` | Class | Creates appropriate orchestrator |
81
+ | `create()` | Method | Factory method |
82
+
83
+ ### `base.py`
84
+ **Purpose:** Base orchestrator interface
85
+
86
+ | Component | Type | Description |
87
+ |-----------|------|-------------|
88
+ | `BaseOrchestrator` | ABC | Abstract base class |
89
+
90
+ ### `langgraph_orchestrator.py`
91
+ **Purpose:** LangGraph-based workflow (experimental)
92
+
93
+ | Component | Type | Description |
94
+ |-----------|------|-------------|
95
+ | `LangGraphOrchestrator` | Class | Workflow state machine |
96
+
97
+ ### `hierarchical.py`
98
+ **Purpose:** Hierarchical agent coordination
99
+
100
+ | Component | Type | Description |
101
+ |-----------|------|-------------|
102
+ | `HierarchicalOrchestrator` | Class | Manager-agent hierarchy |
103
+
104
+ ---
105
+
106
+ ## LLM Clients (`src/clients/`)
107
+
108
+ ### `factory.py`
109
+ **Purpose:** Auto-select LLM backend
110
+
111
+ | Component | Type | Description |
112
+ |-----------|------|-------------|
113
+ | `get_chat_client()` | Function | Returns appropriate client |
114
+
115
+ **Selection Logic:**
116
+ ```python
117
+ if settings.has_openai_key:
118
+ return OpenAIChatClient()
119
+ else:
120
+ return HuggingFaceChatClient()
121
+ ```
122
+
123
+ ### `huggingface.py`
124
+ **Purpose:** HuggingFace Inference API adapter
125
+
126
+ | Component | Type | Description |
127
+ |-----------|------|-------------|
128
+ | `HuggingFaceChatClient` | Class | Free tier LLM client |
129
+ | `chat_completion()` | Method | Generate completion |
130
+
131
+ **Model:** Qwen 2.5 7B Instruct (free tier)
132
+
133
+ ### `base.py`
134
+ **Purpose:** Client interface
135
+
136
+ | Component | Type | Description |
137
+ |-----------|------|-------------|
138
+ | `BaseChatClient` | ABC | Client interface |
139
+
140
+ ### `providers.py`
141
+ **Purpose:** Provider implementations
142
+
143
+ ### `registry.py`
144
+ **Purpose:** Provider registration
145
+
146
+ ---
147
+
148
+ ## Agents (`src/agents/`)
149
+
150
+ ### `search_agent.py`
151
+ | Component | Type | Description |
152
+ |-----------|------|-------------|
153
+ | `SearchAgent` | Class | Evidence gathering agent |
154
+
155
+ ### `judge_agent.py`
156
+ | Component | Type | Description |
157
+ |-----------|------|-------------|
158
+ | `JudgeAgent` | Class | Evidence evaluation |
159
+
160
+ ### `judge_agent_llm.py`
161
+ | Component | Type | Description |
162
+ |-----------|------|-------------|
163
+ | `LLMJudgeAgent` | Class | LLM-based judge implementation |
164
+
165
+ ### `report_agent.py`
166
+ | Component | Type | Description |
167
+ |-----------|------|-------------|
168
+ | `ReportAgent` | Class | Report synthesis |
169
+
170
+ ### `retrieval_agent.py`
171
+ | Component | Type | Description |
172
+ |-----------|------|-------------|
173
+ | `RetrievalAgent` | Class | Evidence retrieval coordination |
174
+
175
+ ### `hypothesis_agent.py`
176
+ | Component | Type | Description |
177
+ |-----------|------|-------------|
178
+ | `HypothesisAgent` | Class | Mechanistic hypothesis generation |
179
+
180
+ ### `magentic_agents.py`
181
+ | Component | Type | Description |
182
+ |-----------|------|-------------|
183
+ | Multi-agent mode | Module | Microsoft Agent Framework integration |
184
+
185
+ ### `state.py`
186
+ | Component | Type | Description |
187
+ |-----------|------|-------------|
188
+ | Agent state models | Module | Shared state definitions |
189
+
190
+ ### `tools.py`
191
+ | Component | Type | Description |
192
+ |-----------|------|-------------|
193
+ | Tool bindings | Module | Agent tool configuration |
194
+
195
+ ---
196
+
197
+ ## Graph Workflow (`src/agents/graph/`)
198
+
199
+ ### `workflow.py`
200
+ | Component | Type | Description |
201
+ |-----------|------|-------------|
202
+ | `create_workflow()` | Function | LangGraph workflow builder |
203
+
204
+ ### `nodes.py`
205
+ | Component | Type | Description |
206
+ |-----------|------|-------------|
207
+ | `search_node()` | Function | Search workflow node |
208
+ | `judge_node()` | Function | Judge workflow node |
209
+ | `report_node()` | Function | Report workflow node |
210
+
211
+ ### `state.py`
212
+ | Component | Type | Description |
213
+ |-----------|------|-------------|
214
+ | `WorkflowState` | Class | LangGraph state schema |
215
+
216
+ ---
217
+
218
+ ## Agent Factory (`src/agent_factory/`)
219
+
220
+ ### `judges.py`
221
+ **Purpose:** Evidence quality judgment
222
+
223
+ | Component | Type | Description |
224
+ |-----------|------|-------------|
225
+ | `create_judge()` | Function | Judge agent factory |
226
+ | `JudgeResult` | Model | Assessment output |
227
+
228
+ **Framework:** Pydantic AI
229
+
230
+ ### `agents.py`
231
+ | Component | Type | Description |
232
+ |-----------|------|-------------|
233
+ | Agent creation | Module | Factory functions |
234
+
235
+ ---
236
+
237
+ ## Search Tools (`src/tools/`)
238
+
239
+ ### `pubmed.py`
240
+ | Component | Type | Description |
241
+ |-----------|------|-------------|
242
+ | `PubMedTool` | Class | NCBI E-utilities client |
243
+ | `search()` | Method | Execute search |
244
+
245
+ **API:** PubMed E-utilities (eutils.ncbi.nlm.nih.gov)
246
+
247
+ ### `clinicaltrials.py`
248
+ | Component | Type | Description |
249
+ |-----------|------|-------------|
250
+ | `ClinicalTrialsTool` | Class | ClinicalTrials.gov client |
251
+ | `search()` | Method | Execute search |
252
+
253
+ **API:** ClinicalTrials.gov API (uses `requests` due to WAF blocking httpx)
254
+
255
+ ### `europepmc.py`
256
+ | Component | Type | Description |
257
+ |-----------|------|-------------|
258
+ | `EuropePMCTool` | Class | Europe PMC client |
259
+ | `search()` | Method | Execute search |
260
+
261
+ **API:** Europe PMC API
262
+
263
+ ### `openalex.py`
264
+ | Component | Type | Description |
265
+ |-----------|------|-------------|
266
+ | `OpenAlexTool` | Class | OpenAlex client |
267
+ | `search()` | Method | Execute search |
268
+
269
+ **API:** OpenAlex API
270
+
271
+ ### `search_handler.py`
272
+ | Component | Type | Description |
273
+ |-----------|------|-------------|
274
+ | `SearchHandler` | Class | Scatter-gather orchestration |
275
+ | `search_all()` | Method | Parallel multi-source search |
276
+
277
+ ### `query_utils.py`
278
+ | Component | Type | Description |
279
+ |-----------|------|-------------|
280
+ | Query utilities | Module | Query refinement and expansion |
281
+
282
+ ### `rate_limiter.py`
283
+ | Component | Type | Description |
284
+ |-----------|------|-------------|
285
+ | `RateLimiter` | Class | API rate limiting |
286
+
287
+ ### `base.py`
288
+ | Component | Type | Description |
289
+ |-----------|------|-------------|
290
+ | `BaseSearchTool` | ABC | Search tool interface |
291
+
292
+ ### `web_search.py`
293
+ | Component | Type | Description |
294
+ |-----------|------|-------------|
295
+ | Web search | Module | DuckDuckGo integration |
296
+
297
+ ---
298
+
299
+ ## Services (`src/services/`)
300
+
301
+ ### `embeddings.py`
302
+ | Component | Type | Description |
303
+ |-----------|------|-------------|
304
+ | `EmbeddingService` | Class | Local embedding service |
305
+ | `embed()` | Method | Generate embeddings |
306
+ | `deduplicate()` | Method | Cross-source deduplication |
307
+
308
+ **Stack:** sentence-transformers + ChromaDB
309
+
310
+ ### `llamaindex_rag.py`
311
+ | Component | Type | Description |
312
+ |-----------|------|-------------|
313
+ | `LlamaIndexRAG` | Class | Premium RAG service |
314
+
315
+ **Stack:** LlamaIndex + OpenAI embeddings + ChromaDB
316
+
317
+ ### `embedding_protocol.py`
318
+ | Component | Type | Description |
319
+ |-----------|------|-------------|
320
+ | `EmbeddingProtocol` | Protocol | Interface for embedding services |
321
+
322
+ ### `research_memory.py`
323
+ | Component | Type | Description |
324
+ |-----------|------|-------------|
325
+ | `ResearchMemory` | Class | Shared research state |
326
+
327
+ ---
328
+
329
+ ## Utilities (`src/utils/`)
330
+
331
+ ### `config.py`
332
+ | Component | Type | Description |
333
+ |-----------|------|-------------|
334
+ | `Settings` | Class | Pydantic Settings configuration |
335
+ | `settings` | Instance | Global settings singleton |
336
+ | `get_settings()` | Function | Settings factory |
337
+ | `configure_logging()` | Function | Logging setup |
338
+
339
+ ### `models.py`
340
+ | Component | Type | Description |
341
+ |-----------|------|-------------|
342
+ | `Evidence` | Model | Evidence with citation |
343
+ | `Citation` | Model | Source citation |
344
+ | `SearchResult` | Model | Search response |
345
+ | `JudgeAssessment` | Model | Judge evaluation |
346
+ | `ResearchReport` | Model | Final report |
347
+ | `AgentEvent` | Model | UI streaming events |
348
+
349
+ See [Data Models](data-models.md) for complete documentation.
350
+
351
+ ### `exceptions.py`
352
+ | Component | Type | Description |
353
+ |-----------|------|-------------|
354
+ | `DeepBonerError` | Exception | Base exception |
355
+ | `SearchError` | Exception | Search failures |
356
+ | `JudgeError` | Exception | Judge failures |
357
+ | `ConfigurationError` | Exception | Config errors |
358
+ | `RateLimitError` | Exception | Rate limits |
359
+
360
+ See [Exception Hierarchy](exception-hierarchy.md) for details.
361
+
362
+ ### `service_loader.py`
363
+ | Component | Type | Description |
364
+ |-----------|------|-------------|
365
+ | Service loading | Module | Tiered service selection |
366
+
367
+ ### `citation_validator.py`
368
+ | Component | Type | Description |
369
+ |-----------|------|-------------|
370
+ | Citation validation | Module | URL verification |
371
+
372
+ ### `text_utils.py`
373
+ | Component | Type | Description |
374
+ |-----------|------|-------------|
375
+ | Text utilities | Module | Text processing |
376
+
377
+ ### `parsers.py`
378
+ | Component | Type | Description |
379
+ |-----------|------|-------------|
380
+ | Response parsing | Module | LLM output parsing |
381
+
382
+ ### `dataloaders.py`
383
+ | Component | Type | Description |
384
+ |-----------|------|-------------|
385
+ | Data loading | Module | Data loading utilities |
386
+
387
+ ---
388
+
389
+ ## Configuration (`src/config/`)
390
+
391
+ ### `domain.py`
392
+ | Component | Type | Description |
393
+ |-----------|------|-------------|
394
+ | `ResearchDomain` | Enum | Research domain types |
395
+
396
+ ---
397
+
398
+ ## Prompts (`src/prompts/`)
399
+
400
+ | File | Purpose |
401
+ |------|---------|
402
+ | `search.py` | Query refinement prompts |
403
+ | `judge.py` | Evidence assessment prompts |
404
+ | `hypothesis.py` | Hypothesis generation prompts |
405
+ | `synthesis.py` | Evidence synthesis prompts |
406
+ | `report.py` | Report generation prompts |
407
+
408
+ ---
409
+
410
+ ## Middleware (`src/middleware/`)
411
+
412
+ ### `sub_iteration.py`
413
+ | Component | Type | Description |
414
+ |-----------|------|-------------|
415
+ | Sub-iteration | Module | Nested iteration logic |
416
+
417
+ ---
418
+
419
+ ## Reserved Directories
420
+
421
+ These directories exist but are placeholders for future features:
422
+
423
+ | Directory | Purpose |
424
+ |-----------|---------|
425
+ | `src/database_services/` | Future database services |
426
+ | `src/retrieval_factory/` | Future retrieval configuration |
427
+
428
+ ---
429
+
430
+ ## Test Structure
431
+
432
+ ```
433
+ tests/
434
+ β”œβ”€β”€ conftest.py # Shared fixtures
435
+ β”œβ”€β”€ unit/ # Unit tests (mocked)
436
+ β”‚ β”œβ”€β”€ orchestrators/
437
+ β”‚ β”œβ”€β”€ agents/
438
+ β”‚ β”œβ”€β”€ clients/
439
+ β”‚ β”œβ”€β”€ tools/
440
+ β”‚ β”œβ”€β”€ services/
441
+ β”‚ β”œβ”€β”€ utils/
442
+ β”‚ β”œβ”€β”€ prompts/
443
+ β”‚ β”œβ”€β”€ agent_factory/
444
+ β”‚ β”œβ”€β”€ config/
445
+ β”‚ β”œβ”€β”€ graph/
446
+ β”‚ └── mcp/
447
+ β”œβ”€β”€ integration/ # Integration tests (real APIs)
448
+ └── e2e/ # End-to-end tests
449
+ ```
450
+
451
+ ---
452
+
453
+ ## Related Documentation
454
+
455
+ - [Architecture Overview](overview.md)
456
+ - [Data Models](data-models.md)
457
+ - [Exception Hierarchy](exception-hierarchy.md)
458
+ - [System Registry](system-registry.md)
docs/architecture/data-models.md ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Data Models Reference
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document describes all Pydantic models used in DeepBoner.
6
+
7
+ ## Location
8
+
9
+ All core models are defined in `src/utils/models.py`.
10
+
11
+ ## Type Definitions
12
+
13
+ ### SourceName
14
+
15
+ ```python
16
+ SourceName = Literal["pubmed", "clinicaltrials", "europepmc", "preprint", "openalex", "web"]
17
+ ```
18
+
19
+ Centralized source type. Add new sources here when integrating new databases.
20
+
21
+ ---
22
+
23
+ ## Core Models
24
+
25
+ ### Citation
26
+
27
+ Represents a citation to a source document.
28
+
29
+ ```python
30
+ class Citation(BaseModel):
31
+ source: SourceName # Where this came from
32
+ title: str # Title (1-500 chars)
33
+ url: str # URL to source
34
+ date: str # Publication date (YYYY-MM-DD or 'Unknown')
35
+ authors: list[str] # Author list
36
+
37
+ MAX_AUTHORS_IN_CITATION: ClassVar[int] = 3
38
+
39
+ @property
40
+ def formatted(self) -> str:
41
+ """Format as citation string."""
42
+ ```
43
+
44
+ **Example:**
45
+ ```python
46
+ citation = Citation(
47
+ source="pubmed",
48
+ title="Effects of testosterone on female libido",
49
+ url="https://pubmed.ncbi.nlm.nih.gov/12345678",
50
+ date="2024-01-15",
51
+ authors=["Smith J", "Jones A", "Brown B"]
52
+ )
53
+ print(citation.formatted)
54
+ # "Smith J, Jones A, Brown B (2024-01-15). Effects of testosterone..."
55
+ ```
56
+
57
+ ---
58
+
59
+ ### Evidence
60
+
61
+ A piece of evidence retrieved from search.
62
+
63
+ ```python
64
+ class Evidence(BaseModel):
65
+ content: str # The actual text content (min 1 char)
66
+ citation: Citation # Source citation
67
+ relevance: float # Relevance score 0-1
68
+ metadata: dict[str, Any] # Additional metadata
69
+
70
+ model_config = {"frozen": True} # Immutable
71
+ ```
72
+
73
+ **Metadata fields** (source-dependent):
74
+ - `cited_by_count` - Citation count
75
+ - `concepts` - Subject concepts
76
+ - `is_open_access` - OA status
77
+ - `pmid` - PubMed ID
78
+ - `doi` - Digital Object Identifier
79
+
80
+ **Example:**
81
+ ```python
82
+ evidence = Evidence(
83
+ content="The study found significant improvement...",
84
+ citation=citation,
85
+ relevance=0.85,
86
+ metadata={"pmid": "12345678", "cited_by_count": 42}
87
+ )
88
+ ```
89
+
90
+ ---
91
+
92
+ ### SearchResult
93
+
94
+ Result of a search operation.
95
+
96
+ ```python
97
+ class SearchResult(BaseModel):
98
+ query: str # Original query
99
+ evidence: list[Evidence] # Retrieved evidence
100
+ sources_searched: list[SourceName] # Which sources were queried
101
+ total_found: int # Total matches
102
+ errors: list[str] # Any errors encountered
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Assessment Models
108
+
109
+ ### AssessmentDetails
110
+
111
+ Detailed assessment of evidence quality by the Judge.
112
+
113
+ ```python
114
+ class AssessmentDetails(BaseModel):
115
+ mechanism_score: int # 0-10: How well explained
116
+ mechanism_reasoning: str # Explanation (min 10 chars)
117
+ clinical_evidence_score: int # 0-10: Clinical strength
118
+ clinical_reasoning: str # Explanation (min 10 chars)
119
+ drug_candidates: list[str] # Specific drugs mentioned
120
+ key_findings: list[str] # Key findings
121
+ ```
122
+
123
+ ---
124
+
125
+ ### JudgeAssessment
126
+
127
+ Complete assessment from the Judge.
128
+
129
+ ```python
130
+ class JudgeAssessment(BaseModel):
131
+ details: AssessmentDetails
132
+ sufficient: bool # Is evidence sufficient?
133
+ confidence: float # 0-1 confidence
134
+ recommendation: Literal["continue", "synthesize"]
135
+ next_search_queries: list[str] # If continue, what to search
136
+ reasoning: str # Overall reasoning (min 20 chars)
137
+ ```
138
+
139
+ **Decision Logic:**
140
+ - `recommendation="continue"` β†’ More evidence needed, loop back
141
+ - `recommendation="synthesize"` β†’ Ready to generate report
142
+
143
+ ---
144
+
145
+ ## Event Models
146
+
147
+ ### AgentEvent
148
+
149
+ Event emitted by orchestrator for UI streaming.
150
+
151
+ ```python
152
+ class AgentEvent(BaseModel):
153
+ type: Literal[
154
+ "started",
155
+ "thinking",
156
+ "searching",
157
+ "search_complete",
158
+ "judging",
159
+ "judge_complete",
160
+ "looping",
161
+ "synthesizing",
162
+ "complete",
163
+ "error",
164
+ "streaming",
165
+ "hypothesizing",
166
+ "analyzing",
167
+ "analysis_complete",
168
+ "progress",
169
+ ]
170
+ message: str
171
+ data: Any = None
172
+ timestamp: datetime
173
+ iteration: int = 0
174
+
175
+ def to_markdown(self) -> str:
176
+ """Format event as markdown with emoji."""
177
+ ```
178
+
179
+ **Event Types:**
180
+ | Type | Icon | Meaning |
181
+ |------|------|---------|
182
+ | `started` | πŸš€ | Research started |
183
+ | `thinking` | ⏳ | Processing |
184
+ | `searching` | πŸ” | Searching databases |
185
+ | `search_complete` | πŸ“š | Search finished |
186
+ | `judging` | 🧠 | Evaluating evidence |
187
+ | `judge_complete` | βœ… | Judgment done |
188
+ | `looping` | πŸ”„ | Refining query |
189
+ | `synthesizing` | πŸ“ | Generating report |
190
+ | `complete` | πŸŽ‰ | Research complete |
191
+ | `error` | ❌ | Error occurred |
192
+ | `progress` | ⏱️ | Progress update |
193
+
194
+ ---
195
+
196
+ ## Hypothesis Models
197
+
198
+ ### MechanismHypothesis
199
+
200
+ A scientific hypothesis about drug mechanism.
201
+
202
+ ```python
203
+ class MechanismHypothesis(BaseModel):
204
+ drug: str # Drug being studied
205
+ target: str # Molecular target
206
+ pathway: str # Biological pathway
207
+ effect: str # Downstream effect
208
+ confidence: float # 0-1 confidence
209
+ supporting_evidence: list[str] # Supporting PMIDs/URLs
210
+ contradicting_evidence: list[str]
211
+ search_suggestions: list[str]
212
+
213
+ def to_search_queries(self) -> list[str]:
214
+ """Generate queries to test hypothesis."""
215
+ ```
216
+
217
+ ---
218
+
219
+ ### HypothesisAssessment
220
+
221
+ Assessment of evidence against hypotheses.
222
+
223
+ ```python
224
+ class HypothesisAssessment(BaseModel):
225
+ hypotheses: list[MechanismHypothesis]
226
+ primary_hypothesis: MechanismHypothesis | None
227
+ knowledge_gaps: list[str]
228
+ recommended_searches: list[str]
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Report Models
234
+
235
+ ### ReportSection
236
+
237
+ A section of the research report.
238
+
239
+ ```python
240
+ class ReportSection(BaseModel):
241
+ title: str
242
+ content: str
243
+ citations: list[str] = [] # Reserved for inline citations
244
+ ```
245
+
246
+ ---
247
+
248
+ ### ResearchReport
249
+
250
+ Structured scientific report (final output).
251
+
252
+ ```python
253
+ class ResearchReport(BaseModel):
254
+ title: str
255
+ executive_summary: str # 100-1000 chars
256
+ research_question: str
257
+
258
+ methodology: ReportSection
259
+ hypotheses_tested: list[dict[str, Any]]
260
+
261
+ mechanistic_findings: ReportSection
262
+ clinical_findings: ReportSection
263
+
264
+ drug_candidates: list[str]
265
+ limitations: list[str]
266
+ conclusion: str
267
+
268
+ references: list[dict[str, str]]
269
+
270
+ # Metadata
271
+ sources_searched: list[str]
272
+ total_papers_reviewed: int
273
+ search_iterations: int
274
+ confidence_score: float # 0-1
275
+
276
+ def to_markdown(self) -> str:
277
+ """Render report as markdown."""
278
+ ```
279
+
280
+ **Reference Format:**
281
+ ```python
282
+ {
283
+ "title": "Paper title",
284
+ "authors": "Smith J et al.",
285
+ "source": "pubmed",
286
+ "date": "2024-01-15",
287
+ "url": "https://..."
288
+ }
289
+ ```
290
+
291
+ ---
292
+
293
+ ## Configuration Models
294
+
295
+ ### OrchestratorConfig
296
+
297
+ Configuration for the orchestrator.
298
+
299
+ ```python
300
+ class OrchestratorConfig(BaseModel):
301
+ max_iterations: int = 10 # 1-20
302
+ max_results_per_tool: int = 10 # 1-50
303
+ search_timeout: float = 30.0 # 5-120 seconds
304
+ ```
305
+
306
+ ---
307
+
308
+ ## Model Relationships
309
+
310
+ ```
311
+ SearchResult
312
+ └── Evidence[]
313
+ └── Citation
314
+
315
+ JudgeAssessment
316
+ └── AssessmentDetails
317
+
318
+ ResearchReport
319
+ β”œβ”€β”€ ReportSection (methodology)
320
+ β”œβ”€β”€ ReportSection (mechanistic_findings)
321
+ β”œβ”€β”€ ReportSection (clinical_findings)
322
+ └── HypothesisAssessment
323
+ └── MechanismHypothesis[]
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Validation Notes
329
+
330
+ All models use Pydantic v2 with:
331
+
332
+ - **Field constraints** - `ge=0`, `le=1` for scores, `min_length` for strings
333
+ - **Frozen models** - Evidence is immutable (`frozen=True`)
334
+ - **Default factories** - Lists default to `[]` via `default_factory=list`
335
+
336
+ ---
337
+
338
+ ## Related Documentation
339
+
340
+ - [Component Inventory](component-inventory.md)
341
+ - [Exception Hierarchy](exception-hierarchy.md)
342
+ - [Architecture Overview](overview.md)
docs/architecture/exception-hierarchy.md ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Exception Hierarchy
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document describes all custom exceptions in DeepBoner.
6
+
7
+ ## Location
8
+
9
+ All exceptions are defined in `src/utils/exceptions.py`.
10
+
11
+ ## Exception Tree
12
+
13
+ ```
14
+ Exception (Python builtin)
15
+ └── DeepBonerError (base)
16
+ β”œβ”€β”€ SearchError
17
+ β”‚ └── RateLimitError
18
+ β”œβ”€β”€ JudgeError
19
+ β”œβ”€β”€ ConfigurationError
20
+ β”œβ”€β”€ EmbeddingError
21
+ β”œβ”€β”€ LLMError
22
+ β”‚ └── QuotaExceededError
23
+ └── SynthesisError
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Base Exception
29
+
30
+ ### DeepBonerError
31
+
32
+ ```python
33
+ class DeepBonerError(Exception):
34
+ """Base exception for all DeepBoner errors."""
35
+ pass
36
+ ```
37
+
38
+ **When to use:** Never directly. Use specific subclasses.
39
+
40
+ **Catch when:** You want to catch all DeepBoner-related errors.
41
+
42
+ ```python
43
+ try:
44
+ result = orchestrator.run(query)
45
+ except DeepBonerError as e:
46
+ logger.error(f"Research failed: {e}")
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Search Exceptions
52
+
53
+ ### SearchError
54
+
55
+ ```python
56
+ class SearchError(DeepBonerError):
57
+ """Raised when a search operation fails."""
58
+ pass
59
+ ```
60
+
61
+ **When raised:**
62
+ - External API returns error status
63
+ - Network timeout
64
+ - Invalid response format
65
+ - No results found (in strict mode)
66
+
67
+ **Example:**
68
+ ```python
69
+ from src.utils.exceptions import SearchError
70
+
71
+ if response.status_code != 200:
72
+ raise SearchError(f"PubMed returned {response.status_code}")
73
+ ```
74
+
75
+ ---
76
+
77
+ ### RateLimitError
78
+
79
+ ```python
80
+ class RateLimitError(SearchError):
81
+ """Raised when we hit API rate limits."""
82
+ pass
83
+ ```
84
+
85
+ **When raised:**
86
+ - HTTP 429 (Too Many Requests)
87
+ - PubMed rate limit exceeded
88
+ - ClinicalTrials.gov throttling
89
+
90
+ **Handling:**
91
+ ```python
92
+ from src.utils.exceptions import RateLimitError
93
+
94
+ try:
95
+ results = pubmed.search(query)
96
+ except RateLimitError:
97
+ await asyncio.sleep(60) # Wait and retry
98
+ results = pubmed.search(query)
99
+ ```
100
+
101
+ **Prevention:**
102
+ - Add `NCBI_API_KEY` for higher PubMed limits
103
+ - Use built-in rate limiter (`src/tools/rate_limiter.py`)
104
+
105
+ ---
106
+
107
+ ## Judge Exceptions
108
+
109
+ ### JudgeError
110
+
111
+ ```python
112
+ class JudgeError(DeepBonerError):
113
+ """Raised when the judge fails to assess evidence."""
114
+ pass
115
+ ```
116
+
117
+ **When raised:**
118
+ - LLM fails to produce valid assessment
119
+ - Assessment parsing fails
120
+ - Confidence below threshold
121
+ - Invalid judge response format
122
+
123
+ **Example:**
124
+ ```python
125
+ from src.utils.exceptions import JudgeError
126
+
127
+ if not assessment.details:
128
+ raise JudgeError("Judge produced incomplete assessment")
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Configuration Exceptions
134
+
135
+ ### ConfigurationError
136
+
137
+ ```python
138
+ class ConfigurationError(DeepBonerError):
139
+ """Raised when configuration is invalid."""
140
+ pass
141
+ ```
142
+
143
+ **When raised:**
144
+ - Required API key missing
145
+ - Invalid setting value
146
+ - Environment variable malformed
147
+ - Conflicting configuration
148
+
149
+ **Example:**
150
+ ```python
151
+ from src.utils.exceptions import ConfigurationError
152
+
153
+ def get_api_key(self) -> str:
154
+ if not self.openai_api_key:
155
+ raise ConfigurationError("OPENAI_API_KEY not set")
156
+ return self.openai_api_key
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Embedding Exceptions
162
+
163
+ ### EmbeddingError
164
+
165
+ ```python
166
+ class EmbeddingError(DeepBonerError):
167
+ """Raised when embedding or vector store operations fail."""
168
+ pass
169
+ ```
170
+
171
+ **When raised:**
172
+ - ChromaDB connection failure
173
+ - Sentence-transformers model load failure
174
+ - Vector dimension mismatch
175
+ - Embedding generation fails
176
+
177
+ **Example:**
178
+ ```python
179
+ from src.utils.exceptions import EmbeddingError
180
+
181
+ try:
182
+ embeddings = model.encode(texts)
183
+ except Exception as e:
184
+ raise EmbeddingError(f"Embedding failed: {e}")
185
+ ```
186
+
187
+ ---
188
+
189
+ ## LLM Exceptions
190
+
191
+ ### LLMError
192
+
193
+ ```python
194
+ class LLMError(DeepBonerError):
195
+ """Raised when LLM operations fail (API errors, parsing errors, etc.)."""
196
+ pass
197
+ ```
198
+
199
+ **When raised:**
200
+ - LLM API error
201
+ - Response parsing failure
202
+ - Invalid model output
203
+ - Context length exceeded
204
+
205
+ ---
206
+
207
+ ### QuotaExceededError
208
+
209
+ ```python
210
+ class QuotaExceededError(LLMError):
211
+ """Raised when LLM API quota is exceeded (402 errors)."""
212
+ pass
213
+ ```
214
+
215
+ **When raised:**
216
+ - OpenAI billing limit hit
217
+ - HuggingFace rate limit exceeded
218
+ - HTTP 402 Payment Required
219
+
220
+ **Handling:**
221
+ ```python
222
+ from src.utils.exceptions import QuotaExceededError
223
+
224
+ try:
225
+ response = client.chat_completion(messages)
226
+ except QuotaExceededError:
227
+ # Fall back to free tier or notify user
228
+ return fallback_response()
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Synthesis Exceptions
234
+
235
+ ### SynthesisError
236
+
237
+ ```python
238
+ class SynthesisError(DeepBonerError):
239
+ """Raised when report synthesis fails after trying all available models.
240
+
241
+ Attributes:
242
+ message: Human-readable error description
243
+ attempted_models: List of model IDs that were tried
244
+ errors: List of error messages from each failed attempt
245
+ """
246
+
247
+ def __init__(
248
+ self,
249
+ message: str,
250
+ attempted_models: list[str] | None = None,
251
+ errors: list[str] | None = None,
252
+ ) -> None:
253
+ super().__init__(message)
254
+ self.attempted_models = attempted_models or []
255
+ self.errors = errors or []
256
+ ```
257
+
258
+ **When raised:**
259
+ - All LLM models fail to synthesize report
260
+ - Report generation exceeds retry limit
261
+
262
+ **Example:**
263
+ ```python
264
+ from src.utils.exceptions import SynthesisError
265
+
266
+ if all_attempts_failed:
267
+ raise SynthesisError(
268
+ "Failed to synthesize report",
269
+ attempted_models=["gpt-5", "gpt-4o"],
270
+ errors=["Rate limit", "Context too long"]
271
+ )
272
+ ```
273
+
274
+ **Accessing details:**
275
+ ```python
276
+ try:
277
+ report = synthesize(evidence)
278
+ except SynthesisError as e:
279
+ print(f"Failed: {e}")
280
+ print(f"Tried models: {e.attempted_models}")
281
+ print(f"Errors: {e.errors}")
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Usage Patterns
287
+
288
+ ### Catching Specific Exceptions
289
+
290
+ ```python
291
+ from src.utils.exceptions import (
292
+ SearchError,
293
+ RateLimitError,
294
+ JudgeError,
295
+ )
296
+
297
+ try:
298
+ result = orchestrator.run(query)
299
+ except RateLimitError:
300
+ # Specific handling for rate limits
301
+ await rate_limiter.wait()
302
+ result = orchestrator.run(query)
303
+ except SearchError:
304
+ # General search failure
305
+ return empty_result()
306
+ except JudgeError:
307
+ # Judge failed, use default assessment
308
+ return default_assessment()
309
+ ```
310
+
311
+ ### Exception Chaining
312
+
313
+ ```python
314
+ try:
315
+ response = api_call()
316
+ except requests.RequestException as e:
317
+ raise SearchError(f"API call failed: {e}") from e
318
+ ```
319
+
320
+ ### Logging Exceptions
321
+
322
+ ```python
323
+ import structlog
324
+
325
+ logger = structlog.get_logger()
326
+
327
+ try:
328
+ results = search(query)
329
+ except DeepBonerError as e:
330
+ logger.error("operation_failed", error=str(e), exc_info=True)
331
+ raise
332
+ ```
333
+
334
+ ---
335
+
336
+ ## Best Practices
337
+
338
+ 1. **Use specific exceptions** - Don't raise `DeepBonerError` directly
339
+ 2. **Include context** - Error messages should explain what failed
340
+ 3. **Chain exceptions** - Use `from e` to preserve stack trace
341
+ 4. **Log before re-raising** - Capture context for debugging
342
+ 5. **Handle at boundaries** - Catch exceptions at API/UI boundaries
343
+
344
+ ---
345
+
346
+ ## Related Documentation
347
+
348
+ - [Component Inventory](component-inventory.md)
349
+ - [Data Models](data-models.md)
350
+ - [Troubleshooting](../getting-started/troubleshooting.md)
docs/architecture/overview.md ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Architecture Overview
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document provides a comprehensive overview of DeepBoner's architecture.
6
+
7
+ ## System Purpose
8
+
9
+ DeepBoner is an **AI-native sexual health research agent** that autonomously:
10
+ 1. Searches biomedical databases (PubMed, ClinicalTrials.gov, Europe PMC, OpenAlex)
11
+ 2. Evaluates evidence quality
12
+ 3. Synthesizes research reports with citations
13
+
14
+ ## High-Level Architecture
15
+
16
+ ```
17
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
18
+ β”‚ USER INTERFACE β”‚
19
+ β”‚ β”‚
20
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
21
+ β”‚ β”‚ Gradio UI β”‚ β”‚ MCP Server β”‚ β”‚ Examples β”‚ β”‚
22
+ β”‚ β”‚ (src/app) β”‚ β”‚(mcp_tools.py)β”‚ β”‚ (scripts) β”‚ β”‚
23
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
24
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
25
+ β”‚ β”‚ β”‚
26
+ β–Ό β–Ό β–Ό
27
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
28
+ β”‚ ORCHESTRATION LAYER β”‚
29
+ β”‚ β”‚
30
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
31
+ β”‚ β”‚ AdvancedOrchestrator β”‚ β”‚
32
+ β”‚ β”‚ (Microsoft Agent Framework) β”‚ β”‚
33
+ β”‚ β”‚ β”‚ β”‚
34
+ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
35
+ β”‚ β”‚ β”‚ Search β”‚ β†’ β”‚ Judge β”‚ β†’ β”‚ Report β”‚ β”‚ β”‚
36
+ β”‚ β”‚ β”‚ Agent β”‚ β”‚ Agent β”‚ β”‚ Agent β”‚ β”‚ β”‚
37
+ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
38
+ β”‚ β”‚ β”‚ β”‚
39
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
40
+ β”‚ β”‚
41
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
42
+ β”‚ β”‚ LangGraph Orchestrator β”‚ β”‚
43
+ β”‚ β”‚ (Experimental) β”‚ β”‚
44
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
45
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
46
+ β”‚
47
+ β–Ό
48
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
49
+ β”‚ LLM BACKENDS β”‚
50
+ β”‚ β”‚
51
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
52
+ β”‚ β”‚ OpenAI Client β”‚ β”‚ HuggingFace Client β”‚ β”‚
53
+ β”‚ β”‚ (GPT-5) β”‚ β”‚ (Qwen 2.5 7B) β”‚ β”‚
54
+ β”‚ β”‚ Premium Tier β”‚ β”‚ Free Tier β”‚ β”‚
55
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
56
+ β”‚ β”‚
57
+ β”‚ Auto-selected by ClientFactory based on API key β”‚
58
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
59
+ β”‚
60
+ β–Ό
61
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
62
+ β”‚ SEARCH TOOLS β”‚
63
+ β”‚ β”‚
64
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
65
+ β”‚ β”‚ PubMed β”‚ β”‚ClinicalTrialsβ”‚ β”‚EuropePMC β”‚ β”‚ OpenAlex β”‚ β”‚
66
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
67
+ β”‚ β”‚
68
+ β”‚ SearchHandler: Parallel scatter-gather β”‚
69
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
70
+ β”‚
71
+ β–Ό
72
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
73
+ β”‚ SERVICES β”‚
74
+ β”‚ β”‚
75
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
76
+ β”‚ β”‚ Embeddings β”‚ β”‚ LlamaIndex β”‚ β”‚ Research β”‚ β”‚
77
+ β”‚ β”‚ Service β”‚ β”‚ RAG β”‚ β”‚ Memory β”‚ β”‚
78
+ β”‚ β”‚ (local) β”‚ β”‚ (premium) β”‚ β”‚ (shared) β”‚ β”‚
79
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
80
+ β”‚ β”‚
81
+ β”‚ ChromaDB Vector Store β”‚
82
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
83
+ ```
84
+
85
+ ## Core Research Loop
86
+
87
+ The system operates on a **search-and-judge loop**:
88
+
89
+ ```
90
+ User Question
91
+ β”‚
92
+ β–Ό
93
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
94
+ β”‚ SEARCH β”‚ ← Query PubMed, ClinicalTrials, Europe PMC, OpenAlex
95
+ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
96
+ β”‚
97
+ β–Ό
98
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
99
+ β”‚ GATHER β”‚ ← Collect and deduplicate evidence (PMID/DOI)
100
+ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
101
+ β”‚
102
+ β–Ό
103
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
104
+ β”‚ JUDGE β”‚ ──► β”‚ "Enough evidence?"β”‚
105
+ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
106
+ β”‚ β”‚
107
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
108
+ β”‚ β”‚ β”‚
109
+ β–Ό β–Ό β–Ό
110
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
111
+ β”‚ REFINE β”‚ ← NO: Expand query β”‚ SYNTHESIZE β”‚ ← YES: Generate report
112
+ β”‚ & LOOP β”‚ and search again β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
113
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
114
+ ```
115
+
116
+ **Break Conditions:**
117
+ - Judge approves evidence as sufficient
118
+ - Token budget exceeded (50K max)
119
+ - Max iterations reached (default 10)
120
+
121
+ ## Framework Integration
122
+
123
+ DeepBoner combines two AI frameworks:
124
+
125
+ | Framework | Role | Usage |
126
+ |-----------|------|-------|
127
+ | **Microsoft Agent Framework** | Multi-agent orchestration | Manager β†’ Agent coordination |
128
+ | **Pydantic AI** | Structured outputs | Evidence models, judge assessments |
129
+
130
+ They work together - Microsoft AF handles the workflow, Pydantic AI handles data validation.
131
+
132
+ ## Dual-Backend Architecture
133
+
134
+ The system auto-selects LLM backend:
135
+
136
+ ```python
137
+ # src/clients/factory.py
138
+ def get_chat_client():
139
+ if settings.has_openai_key:
140
+ return OpenAIChatClient(...) # Premium
141
+ else:
142
+ return HuggingFaceChatClient(...) # Free
143
+ ```
144
+
145
+ | Tier | Backend | Model | Features |
146
+ |------|---------|-------|----------|
147
+ | Free | HuggingFace | Qwen 2.5 7B | Full functionality, slower |
148
+ | Premium | OpenAI | GPT-5 | Full functionality, faster |
149
+
150
+ **Same orchestration logic** - only the LLM differs.
151
+
152
+ ## Key Components
153
+
154
+ ### Orchestrators (`src/orchestrators/`)
155
+
156
+ | Component | File | Purpose |
157
+ |-----------|------|---------|
158
+ | AdvancedOrchestrator | `advanced.py` | Main multi-agent orchestrator |
159
+ | OrchestratorFactory | `factory.py` | Backend selection |
160
+ | LangGraphOrchestrator | `langgraph_orchestrator.py` | Experimental workflow engine |
161
+
162
+ ### Agents (`src/agents/`)
163
+
164
+ | Agent | File | Role |
165
+ |-------|------|------|
166
+ | SearchAgent | `search_agent.py` | Evidence retrieval |
167
+ | JudgeAgent | `judge_agent.py` | Evidence evaluation |
168
+ | ReportAgent | `report_agent.py` | Report synthesis |
169
+ | HypothesisAgent | `hypothesis_agent.py` | Mechanistic pathway analysis |
170
+
171
+ ### Tools (`src/tools/`)
172
+
173
+ | Tool | File | API |
174
+ |------|------|-----|
175
+ | PubMed | `pubmed.py` | NCBI E-utilities |
176
+ | ClinicalTrials | `clinicaltrials.py` | ClinicalTrials.gov |
177
+ | EuropePMC | `europepmc.py` | Europe PMC API |
178
+ | OpenAlex | `openalex.py` | OpenAlex API |
179
+ | SearchHandler | `search_handler.py` | Parallel orchestration |
180
+
181
+ ### Services (`src/services/`)
182
+
183
+ | Service | File | Purpose |
184
+ |---------|------|---------|
185
+ | EmbeddingService | `embeddings.py` | Local embeddings (sentence-transformers) |
186
+ | LlamaIndexRAG | `llamaindex_rag.py` | Premium RAG (OpenAI embeddings) |
187
+ | ResearchMemory | `research_memory.py` | Shared state across agents |
188
+
189
+ ## Data Flow
190
+
191
+ 1. **User Input** β†’ Gradio UI / MCP Client
192
+ 2. **Query** β†’ AdvancedOrchestrator
193
+ 3. **Search** β†’ SearchHandler β†’ [PubMed, ClinicalTrials, EuropePMC, OpenAlex]
194
+ 4. **Evidence** β†’ Deduplicated by PMID/DOI
195
+ 5. **Judge** β†’ LLM evaluates sufficiency
196
+ 6. **Loop or Synthesize** β†’ Based on judge decision
197
+ 7. **Report** β†’ Structured output with citations
198
+ 8. **Response** β†’ Back to user
199
+
200
+ ## Configuration
201
+
202
+ Settings are loaded from environment via Pydantic Settings:
203
+
204
+ ```python
205
+ # src/utils/config.py
206
+ class Settings(BaseSettings):
207
+ openai_api_key: str | None
208
+ huggingface_model: str = "Qwen/Qwen2.5-7B-Instruct"
209
+ max_iterations: int = 10
210
+ # ...
211
+ ```
212
+
213
+ See [Configuration Reference](../reference/configuration.md) for all options.
214
+
215
+ ## Related Documentation
216
+
217
+ - [Component Inventory](component-inventory.md) - Complete module catalog
218
+ - [Data Models](data-models.md) - Pydantic model reference
219
+ - [System Registry](system-registry.md) - Service wiring specification
220
+ - [Workflow Diagrams](workflow-diagrams.md) - Visual documentation
221
+
222
+ ---
223
+
224
+ *"Architecturally rock solid."* πŸ›οΈ
docs/deployment/docker.md ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Docker Deployment
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This guide covers deploying DeepBoner using Docker.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # Build the image
11
+ docker build -t deepboner .
12
+
13
+ # Run the container
14
+ docker run -p 7860:7860 deepboner
15
+ ```
16
+
17
+ Open http://localhost:7860
18
+
19
+ ## Dockerfile Overview
20
+
21
+ The project uses a multi-stage approach:
22
+
23
+ ```dockerfile
24
+ FROM python:3.11-slim
25
+
26
+ # Install system dependencies
27
+ RUN apt-get update && apt-get install -y git curl
28
+
29
+ # Install uv package manager
30
+ RUN pip install uv==0.5.4
31
+
32
+ # Copy project files
33
+ COPY pyproject.toml uv.lock src/ README.md .
34
+
35
+ # Install runtime dependencies (no dev tools)
36
+ RUN uv sync --frozen --no-dev --extra embeddings --extra magentic
37
+
38
+ # Create non-root user
39
+ RUN useradd --create-home appuser
40
+ USER appuser
41
+
42
+ # Pre-download embedding model
43
+ RUN uv run python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"
44
+
45
+ # Expose port and run
46
+ EXPOSE 7860
47
+ CMD ["uv", "run", "python", "-m", "src.app"]
48
+ ```
49
+
50
+ ## Building
51
+
52
+ ### Basic Build
53
+
54
+ ```bash
55
+ docker build -t deepboner .
56
+ ```
57
+
58
+ ### With Build Arguments
59
+
60
+ ```bash
61
+ # Custom tag
62
+ docker build -t deepboner:v0.1.0 .
63
+
64
+ # No cache (clean build)
65
+ docker build --no-cache -t deepboner .
66
+ ```
67
+
68
+ ### Multi-Platform Build
69
+
70
+ ```bash
71
+ docker buildx build --platform linux/amd64,linux/arm64 -t deepboner .
72
+ ```
73
+
74
+ ## Running
75
+
76
+ ### Basic Run
77
+
78
+ ```bash
79
+ docker run -p 7860:7860 deepboner
80
+ ```
81
+
82
+ ### With Environment Variables
83
+
84
+ ```bash
85
+ docker run -p 7860:7860 \
86
+ -e OPENAI_API_KEY=sk-your-key \
87
+ -e NCBI_API_KEY=your-ncbi-key \
88
+ -e LOG_LEVEL=INFO \
89
+ deepboner
90
+ ```
91
+
92
+ ### Using .env File
93
+
94
+ ```bash
95
+ docker run -p 7860:7860 --env-file .env deepboner
96
+ ```
97
+
98
+ ### With Persistent Storage
99
+
100
+ ```bash
101
+ # Persist ChromaDB data
102
+ docker run -p 7860:7860 \
103
+ -v $(pwd)/data/chroma:/app/chroma_db \
104
+ deepboner
105
+ ```
106
+
107
+ ### Detached Mode
108
+
109
+ ```bash
110
+ docker run -d -p 7860:7860 --name deepboner-app deepboner
111
+ ```
112
+
113
+ ## Configuration
114
+
115
+ ### Environment Variables
116
+
117
+ | Variable | Description | Required |
118
+ |----------|-------------|----------|
119
+ | `OPENAI_API_KEY` | OpenAI API key (premium mode) | No |
120
+ | `NCBI_API_KEY` | NCBI API key (higher rate limits) | No |
121
+ | `HF_TOKEN` | HuggingFace token | No |
122
+ | `LOG_LEVEL` | Logging level (DEBUG, INFO, WARNING, ERROR) | No |
123
+ | `MAX_ITERATIONS` | Max search iterations (1-50) | No |
124
+
125
+ ### Ports
126
+
127
+ | Port | Service |
128
+ |------|---------|
129
+ | 7860 | Gradio UI + MCP Server |
130
+
131
+ ### Volumes
132
+
133
+ | Path | Purpose |
134
+ |------|---------|
135
+ | `/app/chroma_db` | ChromaDB vector store |
136
+ | `/app/.cache` | HuggingFace model cache |
137
+
138
+ ## Health Check
139
+
140
+ The container includes a health check:
141
+
142
+ ```dockerfile
143
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
144
+ CMD curl -f http://localhost:7860/ || exit 1
145
+ ```
146
+
147
+ Check health status:
148
+
149
+ ```bash
150
+ docker inspect --format='{{.State.Health.Status}}' deepboner-app
151
+ ```
152
+
153
+ ## Docker Compose
154
+
155
+ Create `docker-compose.yml`:
156
+
157
+ ```yaml
158
+ version: '3.8'
159
+
160
+ services:
161
+ deepboner:
162
+ build: .
163
+ ports:
164
+ - "7860:7860"
165
+ environment:
166
+ - LOG_LEVEL=INFO
167
+ env_file:
168
+ - .env
169
+ volumes:
170
+ - chroma_data:/app/chroma_db
171
+ restart: unless-stopped
172
+ healthcheck:
173
+ test: ["CMD", "curl", "-f", "http://localhost:7860/"]
174
+ interval: 30s
175
+ timeout: 10s
176
+ retries: 3
177
+
178
+ volumes:
179
+ chroma_data:
180
+ ```
181
+
182
+ Run with:
183
+
184
+ ```bash
185
+ docker-compose up -d
186
+ ```
187
+
188
+ ## Production Considerations
189
+
190
+ ### Resource Limits
191
+
192
+ ```bash
193
+ docker run -p 7860:7860 \
194
+ --memory=4g \
195
+ --cpus=2 \
196
+ deepboner
197
+ ```
198
+
199
+ ### Logging
200
+
201
+ ```bash
202
+ # View logs
203
+ docker logs deepboner-app
204
+
205
+ # Follow logs
206
+ docker logs -f deepboner-app
207
+
208
+ # With timestamps
209
+ docker logs -t deepboner-app
210
+ ```
211
+
212
+ ### Security
213
+
214
+ The container runs as non-root user (`appuser`):
215
+
216
+ ```dockerfile
217
+ RUN useradd --create-home appuser
218
+ USER appuser
219
+ ```
220
+
221
+ Do not:
222
+ - Expose ports beyond 7860
223
+ - Mount sensitive host paths
224
+ - Run as root in production
225
+
226
+ ### Reverse Proxy
227
+
228
+ For production, use a reverse proxy (nginx, traefik):
229
+
230
+ ```nginx
231
+ server {
232
+ listen 80;
233
+ server_name deepboner.example.com;
234
+
235
+ location / {
236
+ proxy_pass http://localhost:7860;
237
+ proxy_http_version 1.1;
238
+ proxy_set_header Upgrade $http_upgrade;
239
+ proxy_set_header Connection "upgrade";
240
+ proxy_set_header Host $host;
241
+ }
242
+ }
243
+ ```
244
+
245
+ ## Troubleshooting
246
+
247
+ ### Container exits immediately
248
+
249
+ Check logs:
250
+ ```bash
251
+ docker logs deepboner-app
252
+ ```
253
+
254
+ Common causes:
255
+ - Missing environment variables
256
+ - Port conflict
257
+ - Insufficient memory
258
+
259
+ ### Slow startup
260
+
261
+ First run downloads models. Pre-warm the cache:
262
+ ```bash
263
+ # Build includes model download
264
+ docker build -t deepboner .
265
+ ```
266
+
267
+ ### Out of memory
268
+
269
+ Increase memory limit:
270
+ ```bash
271
+ docker run -p 7860:7860 --memory=8g deepboner
272
+ ```
273
+
274
+ ### Cannot connect to port
275
+
276
+ Check if port is in use:
277
+ ```bash
278
+ lsof -i :7860
279
+ ```
280
+
281
+ Use a different port:
282
+ ```bash
283
+ docker run -p 8080:7860 deepboner
284
+ ```
285
+
286
+ ## Related Documentation
287
+
288
+ - [HuggingFace Spaces Deployment](huggingface-spaces.md)
289
+ - [MCP Integration](mcp-integration.md)
290
+ - [Configuration Reference](../reference/configuration.md)
docs/deployment/huggingface-spaces.md ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HuggingFace Spaces Deployment
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This guide covers deploying DeepBoner to HuggingFace Spaces.
6
+
7
+ ## Overview
8
+
9
+ DeepBoner is deployed to HuggingFace Spaces at:
10
+ https://huggingface.co/spaces/MCP-1st-Birthday/DeepBoner
11
+
12
+ The Space runs the Gradio UI with MCP server support.
13
+
14
+ ## Space Configuration
15
+
16
+ The Space is configured via the README.md frontmatter:
17
+
18
+ ```yaml
19
+ ---
20
+ title: DeepBoner
21
+ emoji: πŸ†
22
+ colorFrom: pink
23
+ colorTo: purple
24
+ sdk: gradio
25
+ sdk_version: "6.0.1"
26
+ python_version: "3.11"
27
+ app_file: src/app.py
28
+ pinned: true
29
+ license: apache-2.0
30
+ short_description: "Deep Research Agent for the Strongest Boners"
31
+ tags:
32
+ - mcp-hackathon
33
+ - agents
34
+ - sexual-health
35
+ - pydantic-ai
36
+ - pubmed
37
+ ---
38
+ ```
39
+
40
+ ## Deployment Methods
41
+
42
+ ### Method 1: Git Push (Recommended)
43
+
44
+ ```bash
45
+ # Add HuggingFace remote
46
+ git remote add hf https://huggingface.co/spaces/MCP-1st-Birthday/DeepBoner
47
+
48
+ # Push to HuggingFace
49
+ git push hf main
50
+ ```
51
+
52
+ ### Method 2: HuggingFace Hub
53
+
54
+ Use the HuggingFace web interface to sync with GitHub.
55
+
56
+ ## Secrets Configuration
57
+
58
+ Configure secrets in Space Settings β†’ Variables and secrets:
59
+
60
+ | Secret | Purpose | Required |
61
+ |--------|---------|----------|
62
+ | `HF_TOKEN` | HuggingFace API token | Yes |
63
+ | `NCBI_API_KEY` | Higher PubMed rate limits | No |
64
+ | `OPENAI_API_KEY` | Premium mode (if offered) | No |
65
+
66
+ ### Setting Secrets
67
+
68
+ 1. Go to Space Settings
69
+ 2. Click "Variables and secrets"
70
+ 3. Add each secret:
71
+ - Name: `HF_TOKEN`
72
+ - Value: `hf_...` (your token)
73
+ - Click "Add"
74
+
75
+ **Important:** Use Secrets (not Variables) for API keys - secrets are hidden.
76
+
77
+ ## Build Process
78
+
79
+ When you push to HuggingFace:
80
+
81
+ 1. Space detects changes
82
+ 2. Builds from Dockerfile (if present) or requirements.txt
83
+ 3. Installs dependencies
84
+ 4. Starts the application
85
+
86
+ Build logs are visible in the Logs tab.
87
+
88
+ ## Collaboration Workflow
89
+
90
+ ### Branch Strategy
91
+
92
+ ```
93
+ GitHub (source of truth)
94
+ β”œβ”€β”€ main - Production, synced to HF
95
+ └── dev - Development integration
96
+
97
+ HuggingFace
98
+ β”œβ”€β”€ main - Production (from GitHub)
99
+ └── yourname-dev - Personal dev branches
100
+ ```
101
+
102
+ ### Guidelines
103
+
104
+ - **DO NOT** push directly to `main` on HuggingFace
105
+ - Use personal dev branches: `yourname-dev`
106
+ - GitHub is the source of truth for code review
107
+ - Sync production from GitHub only
108
+
109
+ ### Personal Development
110
+
111
+ ```bash
112
+ # Create your dev branch on HuggingFace
113
+ git checkout -b myname-dev
114
+ git push hf myname-dev
115
+
116
+ # Test on your branch
117
+ # Space will build from your branch if you switch to it
118
+ ```
119
+
120
+ ## Environment Differences
121
+
122
+ ### Local vs Spaces
123
+
124
+ | Aspect | Local | HuggingFace Spaces |
125
+ |--------|-------|-------------------|
126
+ | API Keys | `.env` file | Secrets |
127
+ | Storage | Persistent | Ephemeral |
128
+ | Port | 7860 | Assigned |
129
+ | Memory | Unlimited | Limited (based on tier) |
130
+
131
+ ### Handling Ephemeral Storage
132
+
133
+ ChromaDB data is not persisted on Space restart. For production use cases requiring persistence:
134
+
135
+ 1. Use external database
136
+ 2. Accept regeneration on restart
137
+ 3. Consider paid Spaces with persistent storage
138
+
139
+ ## Hardware Tiers
140
+
141
+ HuggingFace Spaces offers different hardware:
142
+
143
+ | Tier | CPU | RAM | GPU | Cost |
144
+ |------|-----|-----|-----|------|
145
+ | Free | 2 | 16GB | None | Free |
146
+ | CPU Basic | 2 | 16GB | None | $0.03/hr |
147
+ | CPU Upgrade | 8 | 32GB | None | $0.07/hr |
148
+ | T4 Small | 4 | 15GB | T4 | $0.60/hr |
149
+
150
+ DeepBoner runs on Free tier but benefits from CPU Upgrade for:
151
+ - Faster embedding generation
152
+ - More concurrent users
153
+
154
+ ## Monitoring
155
+
156
+ ### Logs
157
+
158
+ View logs in the Logs tab:
159
+ - Build logs (during deployment)
160
+ - Application logs (runtime)
161
+
162
+ ### Health
163
+
164
+ Check Space status:
165
+ - Green: Running
166
+ - Yellow: Building
167
+ - Red: Error
168
+
169
+ ## Troubleshooting
170
+
171
+ ### Build fails
172
+
173
+ 1. Check Build Logs tab
174
+ 2. Common issues:
175
+ - Invalid requirements.txt
176
+ - Missing files
177
+ - Syntax errors in config
178
+
179
+ ### App crashes on start
180
+
181
+ 1. Check Application Logs
182
+ 2. Common issues:
183
+ - Missing secrets
184
+ - Import errors
185
+ - Memory limits
186
+
187
+ ### Slow performance
188
+
189
+ 1. Check if on Free tier
190
+ 2. Consider CPU Upgrade
191
+ 3. Optimize model loading
192
+
193
+ ### Space sleeping
194
+
195
+ Free Spaces sleep after inactivity:
196
+ - Wake time: 30-60 seconds
197
+ - Consider "pinned" for popular Spaces
198
+
199
+ ## Git Hooks
200
+
201
+ To prevent accidental pushes to protected branches:
202
+
203
+ ```bash
204
+ # .git/hooks/pre-push
205
+ #!/bin/bash
206
+ protected_branches=("main" "dev")
207
+ current_branch=$(git rev-parse --abbrev-ref HEAD)
208
+ remote="$1"
209
+
210
+ if [[ "$remote" == "hf" || "$remote" == "huggingface" ]]; then
211
+ for branch in "${protected_branches[@]}"; do
212
+ if [[ "$current_branch" == "$branch" ]]; then
213
+ echo "Direct push to $branch on HuggingFace is not allowed."
214
+ exit 1
215
+ fi
216
+ done
217
+ fi
218
+ ```
219
+
220
+ ## Related Documentation
221
+
222
+ - [Docker Deployment](docker.md)
223
+ - [MCP Integration](mcp-integration.md)
224
+ - [Configuration Reference](../reference/configuration.md)
docs/deployment/mcp-integration.md ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MCP Integration Guide
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This guide covers setting up DeepBoner's MCP (Model Context Protocol) server for integration with Claude Desktop and other MCP clients.
6
+
7
+ ## Overview
8
+
9
+ DeepBoner exposes an MCP server via Gradio's built-in support. This allows Claude Desktop and other MCP-compatible clients to use DeepBoner's search tools directly.
10
+
11
+ ## MCP Server URL
12
+
13
+ When DeepBoner is running:
14
+
15
+ ```
16
+ http://localhost:7860/gradio_api/mcp/
17
+ ```
18
+
19
+ On HuggingFace Spaces:
20
+ ```
21
+ https://mcp-1st-birthday-deepboner.hf.space/gradio_api/mcp/
22
+ ```
23
+
24
+ ## Available Tools
25
+
26
+ | Tool | Description |
27
+ |------|-------------|
28
+ | `search_pubmed` | Search peer-reviewed biomedical literature |
29
+ | `search_clinical_trials` | Search ClinicalTrials.gov for active/completed trials |
30
+ | `search_europepmc` | Search Europe PMC preprints and papers |
31
+ | `search_all_sources` | Search all sources simultaneously with deduplication |
32
+
33
+ ### Tool Signatures
34
+
35
+ ```python
36
+ def search_pubmed(query: str, max_results: int = 10) -> list[Evidence]:
37
+ """Search PubMed for biomedical literature."""
38
+
39
+ def search_clinical_trials(query: str, max_results: int = 10) -> list[Evidence]:
40
+ """Search ClinicalTrials.gov."""
41
+
42
+ def search_europepmc(query: str, max_results: int = 10) -> list[Evidence]:
43
+ """Search Europe PMC."""
44
+
45
+ def search_all_sources(query: str, max_results_per_source: int = 10) -> SearchResult:
46
+ """Search all sources with cross-source deduplication."""
47
+ ```
48
+
49
+ ## Claude Desktop Setup
50
+
51
+ ### 1. Start DeepBoner
52
+
53
+ ```bash
54
+ uv run python src/app.py
55
+ ```
56
+
57
+ ### 2. Configure Claude Desktop
58
+
59
+ Edit your Claude Desktop configuration:
60
+
61
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
62
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
63
+
64
+ Add the MCP server:
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "deepboner": {
70
+ "url": "http://localhost:7860/gradio_api/mcp/"
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### 3. Restart Claude Desktop
77
+
78
+ Close and reopen Claude Desktop to load the new configuration.
79
+
80
+ ### 4. Verify Connection
81
+
82
+ In Claude Desktop, you should see DeepBoner's tools available. Try:
83
+
84
+ ```
85
+ Use the search_pubmed tool to find recent papers on testosterone therapy
86
+ ```
87
+
88
+ ## Using with HuggingFace Spaces
89
+
90
+ Point to the deployed Space:
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "deepboner-cloud": {
96
+ "url": "https://mcp-1st-birthday-deepboner.hf.space/gradio_api/mcp/"
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ Note: HuggingFace Spaces may sleep after inactivity. The first request will wake the Space (30-60 second delay).
103
+
104
+ ## Tool Implementation
105
+
106
+ Tools are defined in `src/mcp_tools.py`:
107
+
108
+ ```python
109
+ def search_pubmed(query: str, max_results: int = 10) -> list[Evidence]:
110
+ """Search PubMed for biomedical literature.
111
+
112
+ Args:
113
+ query: Search query for PubMed
114
+ max_results: Maximum number of results to return
115
+
116
+ Returns:
117
+ List of Evidence objects with citations
118
+ """
119
+ tool = PubMedTool()
120
+ result = tool.search(query, max_results=max_results)
121
+ return result.evidence
122
+ ```
123
+
124
+ ## Adding New Tools
125
+
126
+ To expose additional tools via MCP:
127
+
128
+ 1. Add the function to `src/mcp_tools.py`:
129
+
130
+ ```python
131
+ def search_openalex(query: str, max_results: int = 10) -> list[Evidence]:
132
+ """Search OpenAlex for scholarly metadata."""
133
+ tool = OpenAlexTool()
134
+ result = tool.search(query, max_results=max_results)
135
+ return result.evidence
136
+ ```
137
+
138
+ 2. Register in Gradio app (`src/app.py`):
139
+
140
+ The tools are automatically exposed via Gradio's MCP support when added to the interface.
141
+
142
+ ## Troubleshooting
143
+
144
+ ### Tools not appearing in Claude Desktop
145
+
146
+ 1. Verify DeepBoner is running:
147
+ ```bash
148
+ curl http://localhost:7860/gradio_api/mcp/
149
+ ```
150
+
151
+ 2. Check config syntax:
152
+ ```bash
153
+ cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | python -m json.tool
154
+ ```
155
+
156
+ 3. Restart Claude Desktop
157
+
158
+ ### Connection refused
159
+
160
+ - Check DeepBoner is running on port 7860
161
+ - Verify no firewall blocking
162
+ - Try accessing in browser: http://localhost:7860
163
+
164
+ ### Slow responses
165
+
166
+ - First query loads ML models
167
+ - HuggingFace Space may need to wake up
168
+ - External APIs have rate limits
169
+
170
+ ### Authentication errors
171
+
172
+ MCP server doesn't require authentication for local use. For production:
173
+ - Use API gateway
174
+ - Implement auth middleware
175
+
176
+ ## Security Considerations
177
+
178
+ ### Local Development
179
+
180
+ Local MCP server is accessible only from localhost by default.
181
+
182
+ ### Production
183
+
184
+ For production deployments:
185
+
186
+ 1. **Use HTTPS** - Enable TLS via reverse proxy
187
+ 2. **Add authentication** - Consider API keys or OAuth
188
+ 3. **Rate limit** - Prevent abuse
189
+ 4. **Monitor** - Log tool usage
190
+
191
+ ### Data Privacy
192
+
193
+ - Search queries are sent to external APIs (PubMed, etc.)
194
+ - Review external API privacy policies
195
+ - Don't expose sensitive research queries
196
+
197
+ ## Protocol Details
198
+
199
+ ### MCP Protocol Version
200
+
201
+ DeepBoner uses MCP protocol via Gradio 6.x integration.
202
+
203
+ ### Request/Response Format
204
+
205
+ Requests follow the MCP specification:
206
+
207
+ ```json
208
+ {
209
+ "jsonrpc": "2.0",
210
+ "method": "tools/call",
211
+ "params": {
212
+ "name": "search_pubmed",
213
+ "arguments": {
214
+ "query": "testosterone therapy",
215
+ "max_results": 10
216
+ }
217
+ },
218
+ "id": 1
219
+ }
220
+ ```
221
+
222
+ ## Related Documentation
223
+
224
+ - [Docker Deployment](docker.md)
225
+ - [HuggingFace Spaces](huggingface-spaces.md)
226
+ - [Component Inventory](../architecture/component-inventory.md)
docs/development/code-style.md ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Code Style Guide
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This guide covers code style conventions and tooling for DeepBoner.
6
+
7
+ ## Quick Reference
8
+
9
+ ```bash
10
+ # Auto-format code
11
+ make format
12
+
13
+ # Check linting
14
+ make lint
15
+
16
+ # Type check
17
+ make typecheck
18
+
19
+ # Run all checks
20
+ make check
21
+ ```
22
+
23
+ ## Tooling
24
+
25
+ ### Ruff (Linting & Formatting)
26
+
27
+ Configuration in `pyproject.toml`:
28
+
29
+ ```toml
30
+ [tool.ruff]
31
+ line-length = 100
32
+ target-version = "py311"
33
+ src = ["src", "tests"]
34
+
35
+ [tool.ruff.lint]
36
+ select = [
37
+ "E", # pycodestyle errors
38
+ "F", # pyflakes
39
+ "B", # flake8-bugbear
40
+ "I", # isort
41
+ "N", # pep8-naming
42
+ "UP", # pyupgrade
43
+ "PL", # pylint
44
+ "RUF", # ruff-specific
45
+ ]
46
+ ```
47
+
48
+ ### MyPy (Type Checking)
49
+
50
+ Configuration in `pyproject.toml`:
51
+
52
+ ```toml
53
+ [tool.mypy]
54
+ python_version = "3.11"
55
+ strict = true
56
+ ignore_missing_imports = true
57
+ disallow_untyped_defs = true
58
+ warn_return_any = true
59
+ ```
60
+
61
+ ### Pre-commit Hooks
62
+
63
+ Hooks run automatically on commit:
64
+
65
+ ```yaml
66
+ # .pre-commit-config.yaml
67
+ repos:
68
+ - repo: https://github.com/astral-sh/ruff-pre-commit
69
+ hooks:
70
+ - id: ruff
71
+ - id: ruff-format
72
+ - repo: https://github.com/pre-commit/mirrors-mypy
73
+ hooks:
74
+ - id: mypy
75
+ ```
76
+
77
+ ## Python Style
78
+
79
+ ### Type Hints
80
+
81
+ All functions must have type annotations:
82
+
83
+ ```python
84
+ # Good
85
+ def search(query: str, limit: int = 10) -> list[Evidence]:
86
+ """Search for evidence."""
87
+ pass
88
+
89
+ # Bad
90
+ def search(query, limit=10):
91
+ pass
92
+ ```
93
+
94
+ Use modern type hint syntax (Python 3.11+):
95
+
96
+ ```python
97
+ # Good
98
+ def process(items: list[str] | None) -> dict[str, int]:
99
+ pass
100
+
101
+ # Avoid (old syntax)
102
+ from typing import List, Dict, Optional
103
+ def process(items: Optional[List[str]]) -> Dict[str, int]:
104
+ pass
105
+ ```
106
+
107
+ ### Docstrings
108
+
109
+ Use Google-style docstrings for public APIs:
110
+
111
+ ```python
112
+ def search_pubmed(query: str, max_results: int = 10) -> SearchResult:
113
+ """Search PubMed for biomedical literature.
114
+
115
+ Args:
116
+ query: The search query string.
117
+ max_results: Maximum number of results to return.
118
+
119
+ Returns:
120
+ SearchResult containing evidence and metadata.
121
+
122
+ Raises:
123
+ SearchError: If the API call fails.
124
+ RateLimitError: If rate limit is exceeded.
125
+ """
126
+ pass
127
+ ```
128
+
129
+ ### Class Documentation
130
+
131
+ ```python
132
+ class SearchHandler:
133
+ """Orchestrates parallel searches across multiple sources.
134
+
135
+ This handler implements a scatter-gather pattern to query
136
+ multiple biomedical databases simultaneously.
137
+
138
+ Attributes:
139
+ sources: List of enabled search sources.
140
+ timeout: Timeout for each search in seconds.
141
+
142
+ Example:
143
+ handler = SearchHandler()
144
+ result = handler.search_all("testosterone therapy")
145
+ """
146
+
147
+ def __init__(self, sources: list[str] | None = None) -> None:
148
+ """Initialize the search handler.
149
+
150
+ Args:
151
+ sources: Optional list of sources to enable.
152
+ Defaults to all sources.
153
+ """
154
+ pass
155
+ ```
156
+
157
+ ### Imports
158
+
159
+ Imports are sorted by isort (via ruff):
160
+
161
+ ```python
162
+ # Standard library
163
+ import asyncio
164
+ from datetime import datetime
165
+ from typing import Any
166
+
167
+ # Third-party
168
+ import httpx
169
+ from pydantic import BaseModel
170
+
171
+ # Local
172
+ from src.utils.config import settings
173
+ from src.utils.exceptions import SearchError
174
+ ```
175
+
176
+ ### Line Length
177
+
178
+ Maximum 100 characters. Break long lines:
179
+
180
+ ```python
181
+ # Good - break at logical points
182
+ result = very_long_function_name(
183
+ first_argument=value1,
184
+ second_argument=value2,
185
+ third_argument=value3,
186
+ )
187
+
188
+ # Good - string continuation
189
+ message = (
190
+ "This is a very long message that needs to be "
191
+ "split across multiple lines for readability."
192
+ )
193
+ ```
194
+
195
+ ### Naming Conventions
196
+
197
+ | Type | Convention | Example |
198
+ |------|------------|---------|
199
+ | Classes | PascalCase | `SearchHandler` |
200
+ | Functions | snake_case | `search_pubmed` |
201
+ | Variables | snake_case | `max_results` |
202
+ | Constants | UPPER_SNAKE | `MAX_ITERATIONS` |
203
+ | Private | leading underscore | `_internal_method` |
204
+ | Type vars | PascalCase | `T`, `ConfigT` |
205
+
206
+ ### Exceptions
207
+
208
+ Custom exceptions in `src/utils/exceptions.py`:
209
+
210
+ ```python
211
+ from src.utils.exceptions import SearchError
212
+
213
+ # Raising
214
+ raise SearchError(f"API returned {status_code}")
215
+
216
+ # With cause
217
+ try:
218
+ response = client.get(url)
219
+ except httpx.HTTPError as e:
220
+ raise SearchError(f"Request failed: {e}") from e
221
+ ```
222
+
223
+ ## Pydantic Models
224
+
225
+ ### Model Definition
226
+
227
+ ```python
228
+ from pydantic import BaseModel, Field
229
+
230
+ class Evidence(BaseModel):
231
+ """A piece of evidence from search."""
232
+
233
+ content: str = Field(min_length=1, description="The evidence text")
234
+ relevance: float = Field(ge=0.0, le=1.0, default=0.0)
235
+ metadata: dict[str, Any] = Field(default_factory=dict)
236
+
237
+ model_config = {"frozen": True} # Make immutable
238
+ ```
239
+
240
+ ### Settings
241
+
242
+ ```python
243
+ from pydantic_settings import BaseSettings
244
+
245
+ class Settings(BaseSettings):
246
+ """Application settings from environment."""
247
+
248
+ model_config = SettingsConfigDict(
249
+ env_file=".env",
250
+ case_sensitive=False,
251
+ )
252
+
253
+ max_iterations: int = Field(default=10, ge=1, le=50)
254
+ ```
255
+
256
+ ## Async Code
257
+
258
+ ### Async Functions
259
+
260
+ ```python
261
+ async def search_async(query: str) -> SearchResult:
262
+ """Async search implementation."""
263
+ async with httpx.AsyncClient() as client:
264
+ response = await client.get(url)
265
+ return parse_response(response)
266
+ ```
267
+
268
+ ### Concurrent Execution
269
+
270
+ ```python
271
+ async def search_all(query: str) -> list[SearchResult]:
272
+ """Search all sources concurrently."""
273
+ tasks = [
274
+ search_pubmed(query),
275
+ search_clinicaltrials(query),
276
+ search_europepmc(query),
277
+ ]
278
+ return await asyncio.gather(*tasks, return_exceptions=True)
279
+ ```
280
+
281
+ ## Comments
282
+
283
+ ### When to Comment
284
+
285
+ ```python
286
+ # Good: Explain WHY, not WHAT
287
+ # PubMed rate limits without API key - add delay to avoid 429
288
+ await asyncio.sleep(0.34)
289
+
290
+ # Bad: Obvious comment
291
+ # Increment counter
292
+ counter += 1
293
+ ```
294
+
295
+ ### TODO Comments
296
+
297
+ ```python
298
+ # TODO(username): Description of what needs to be done
299
+ # TODO: Short-term fix, proper solution needs X
300
+ ```
301
+
302
+ ## Ignored Rules
303
+
304
+ Some rules are disabled for good reasons:
305
+
306
+ ```toml
307
+ ignore = [
308
+ "PLR0913", # Too many arguments (agents need many params)
309
+ "PLR0912", # Too many branches (complex orchestrator logic)
310
+ "PLR2004", # Magic values (statistical constants)
311
+ "PLW0603", # Global statement (singleton pattern)
312
+ "PLC0415", # Lazy imports for optional dependencies
313
+ ]
314
+ ```
315
+
316
+ ## File Organization
317
+
318
+ ### Module Structure
319
+
320
+ ```python
321
+ """Module docstring explaining purpose."""
322
+
323
+ # Imports (sorted)
324
+ import ...
325
+
326
+ # Constants
327
+ MAX_RESULTS = 100
328
+
329
+ # Type definitions
330
+ ResultType = dict[str, Any]
331
+
332
+ # Classes
333
+ class MyClass:
334
+ pass
335
+
336
+ # Functions
337
+ def my_function():
338
+ pass
339
+
340
+ # Module-level code (minimize)
341
+ if __name__ == "__main__":
342
+ main()
343
+ ```
344
+
345
+ ### Package Structure
346
+
347
+ ```
348
+ src/tools/
349
+ β”œβ”€β”€ __init__.py # Public exports
350
+ β”œβ”€β”€ base.py # Base classes
351
+ β”œβ”€β”€ pubmed.py # PubMed implementation
352
+ β”œβ”€β”€ clinicaltrials.py
353
+ └── search_handler.py
354
+ ```
355
+
356
+ ## Code Review Checklist
357
+
358
+ Before submitting a PR:
359
+
360
+ - [ ] All functions have type hints
361
+ - [ ] Public APIs have docstrings
362
+ - [ ] `make check` passes
363
+ - [ ] No hardcoded credentials
364
+ - [ ] Error cases are handled
365
+ - [ ] Tests cover new code
366
+
367
+ ---
368
+
369
+ ## Related Documentation
370
+
371
+ - [Testing Guide](testing.md)
372
+ - [Contributing Guide](../../CONTRIBUTING.md)
373
+ - [Architecture Overview](../architecture/overview.md)
docs/development/release-process.md ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Release Process
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document describes the release workflow for DeepBoner.
6
+
7
+ ## Version Numbering
8
+
9
+ DeepBoner uses [Semantic Versioning](https://semver.org/):
10
+
11
+ ```
12
+ MAJOR.MINOR.PATCH
13
+
14
+ 1.0.0 - First stable release
15
+ 0.2.0 - New features (backwards compatible)
16
+ 0.1.1 - Bug fixes only
17
+ ```
18
+
19
+ ### Pre-release Versions
20
+
21
+ ```
22
+ 0.1.0-alpha.1 - Early development
23
+ 0.1.0-beta.1 - Feature complete, testing
24
+ 0.1.0-rc.1 - Release candidate
25
+ ```
26
+
27
+ ## Release Workflow
28
+
29
+ ### 1. Prepare the Release
30
+
31
+ ```bash
32
+ # Ensure you're on main and up to date
33
+ git checkout main
34
+ git pull origin main
35
+
36
+ # Run all checks
37
+ make check
38
+ ```
39
+
40
+ ### 2. Update Version
41
+
42
+ Edit `pyproject.toml`:
43
+
44
+ ```toml
45
+ [project]
46
+ version = "0.2.0" # Update this
47
+ ```
48
+
49
+ ### 3. Update CHANGELOG
50
+
51
+ Add release notes to `CHANGELOG.md`:
52
+
53
+ ```markdown
54
+ ## [0.2.0] - 2025-12-15
55
+
56
+ ### Added
57
+ - New feature X
58
+
59
+ ### Fixed
60
+ - Bug in Y
61
+
62
+ ### Changed
63
+ - Improved Z
64
+ ```
65
+
66
+ ### 4. Create Release Commit
67
+
68
+ ```bash
69
+ git add pyproject.toml CHANGELOG.md
70
+ git commit -m "release: v0.2.0"
71
+ ```
72
+
73
+ ### 5. Tag the Release
74
+
75
+ ```bash
76
+ git tag -a v0.2.0 -m "Release v0.2.0"
77
+ ```
78
+
79
+ ### 6. Push
80
+
81
+ ```bash
82
+ git push origin main
83
+ git push origin v0.2.0
84
+ ```
85
+
86
+ ### 7. Create GitHub Release
87
+
88
+ 1. Go to GitHub β†’ Releases β†’ New Release
89
+ 2. Select the tag (v0.2.0)
90
+ 3. Copy release notes from CHANGELOG
91
+ 4. Publish release
92
+
93
+ ### 8. Deploy to HuggingFace Spaces
94
+
95
+ ```bash
96
+ # Push to HuggingFace
97
+ git push huggingface-upstream main
98
+ ```
99
+
100
+ ## Release Checklist
101
+
102
+ ### Before Release
103
+
104
+ - [ ] All tests pass (`make check`)
105
+ - [ ] CHANGELOG updated
106
+ - [ ] Version bumped in pyproject.toml
107
+ - [ ] Documentation updated
108
+ - [ ] No outstanding critical bugs
109
+ - [ ] Security audit clean (`uv run pip-audit`)
110
+
111
+ ### After Release
112
+
113
+ - [ ] GitHub release created
114
+ - [ ] HuggingFace Space updated
115
+ - [ ] Announce release (if significant)
116
+
117
+ ## Hotfix Process
118
+
119
+ For urgent fixes on released versions:
120
+
121
+ ```bash
122
+ # Create hotfix branch from tag
123
+ git checkout -b hotfix/0.1.1 v0.1.0
124
+
125
+ # Make fix
126
+ # ...
127
+
128
+ # Bump patch version
129
+ # Update CHANGELOG
130
+
131
+ # Commit and tag
132
+ git commit -m "fix: critical bug in X"
133
+ git tag -a v0.1.1 -m "Hotfix v0.1.1"
134
+
135
+ # Push
136
+ git push origin v0.1.1
137
+
138
+ # Merge back to main
139
+ git checkout main
140
+ git merge hotfix/0.1.1
141
+ git push origin main
142
+ ```
143
+
144
+ ## CI/CD Integration
145
+
146
+ Releases trigger GitHub Actions:
147
+
148
+ ```yaml
149
+ on:
150
+ push:
151
+ tags:
152
+ - 'v*'
153
+
154
+ jobs:
155
+ release:
156
+ runs-on: ubuntu-latest
157
+ steps:
158
+ - uses: actions/checkout@v4
159
+ - name: Build and test
160
+ run: make check
161
+ ```
162
+
163
+ ## Rollback Procedure
164
+
165
+ If a release has critical issues:
166
+
167
+ ```bash
168
+ # Revert to previous version in HuggingFace
169
+ git push huggingface-upstream v0.1.0:main --force
170
+
171
+ # Document in CHANGELOG
172
+ # Plan hotfix release
173
+ ```
174
+
175
+ ## Version Locations
176
+
177
+ Keep these in sync:
178
+
179
+ | File | Field |
180
+ |------|-------|
181
+ | `pyproject.toml` | `version = "X.Y.Z"` |
182
+ | `CHANGELOG.md` | `## [X.Y.Z] - YYYY-MM-DD` |
183
+ | Git tag | `vX.Y.Z` |
184
+
185
+ ---
186
+
187
+ ## Related Documentation
188
+
189
+ - [CHANGELOG](../../CHANGELOG.md)
190
+ - [Contributing Guide](../../CONTRIBUTING.md)
191
+ - [Deployment Guide](../deployment/docker.md)
docs/development/testing.md ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Testing Guide
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This guide covers testing strategy, patterns, and best practices for DeepBoner.
6
+
7
+ ## Quick Reference
8
+
9
+ ```bash
10
+ # Run all tests
11
+ make test
12
+
13
+ # Run with coverage
14
+ make test-cov
15
+
16
+ # Run specific file
17
+ uv run pytest tests/unit/utils/test_config.py -v
18
+
19
+ # Run specific test
20
+ uv run pytest tests/unit/utils/test_config.py::TestSettings::test_default -v
21
+
22
+ # Run by marker
23
+ uv run pytest -m unit # Unit tests only
24
+ uv run pytest -m integration # Integration tests only
25
+ uv run pytest -m "not slow" # Skip slow tests
26
+ ```
27
+
28
+ ## Test Organization
29
+
30
+ ```
31
+ tests/
32
+ β”œβ”€β”€ conftest.py # Shared fixtures
33
+ β”œβ”€β”€ unit/ # Unit tests (mocked, fast)
34
+ β”‚ β”œβ”€β”€ orchestrators/
35
+ β”‚ β”œβ”€β”€ agents/
36
+ β”‚ β”œβ”€β”€ clients/
37
+ β”‚ β”œβ”€β”€ tools/
38
+ β”‚ β”œβ”€β”€ services/
39
+ β”‚ β”œβ”€β”€ utils/
40
+ β”‚ β”œβ”€β”€ prompts/
41
+ β”‚ β”œβ”€β”€ agent_factory/
42
+ β”‚ β”œβ”€β”€ config/
43
+ β”‚ β”œβ”€β”€ graph/
44
+ β”‚ └── mcp/
45
+ β”œβ”€β”€ integration/ # Integration tests (real APIs)
46
+ └── e2e/ # End-to-end tests
47
+ ```
48
+
49
+ ### Directory Mapping
50
+
51
+ Tests mirror the `src/` structure:
52
+ - `src/tools/pubmed.py` β†’ `tests/unit/tools/test_pubmed.py`
53
+ - `src/utils/config.py` β†’ `tests/unit/utils/test_config.py`
54
+
55
+ ## Test Markers
56
+
57
+ ### Available Markers
58
+
59
+ | Marker | Purpose | Example |
60
+ |--------|---------|---------|
61
+ | `@pytest.mark.unit` | Unit tests (mocked) | Most tests |
62
+ | `@pytest.mark.integration` | Real API calls | API testing |
63
+ | `@pytest.mark.slow` | Long-running tests | Full pipeline |
64
+ | `@pytest.mark.e2e` | End-to-end tests | Complete flows |
65
+
66
+ ### Using Markers
67
+
68
+ ```python
69
+ import pytest
70
+
71
+ @pytest.mark.unit
72
+ def test_search_returns_results():
73
+ """Unit test with mocked API."""
74
+ pass
75
+
76
+ @pytest.mark.integration
77
+ def test_pubmed_real_api():
78
+ """Integration test with real PubMed API."""
79
+ pass
80
+ ```
81
+
82
+ ### Running by Marker
83
+
84
+ ```bash
85
+ uv run pytest -m unit # Only unit tests
86
+ uv run pytest -m "not integration" # Skip integration tests
87
+ uv run pytest -m "unit or slow" # Unit OR slow tests
88
+ ```
89
+
90
+ ## Test Fixtures
91
+
92
+ ### Core Fixtures (conftest.py)
93
+
94
+ #### `mock_httpx_client`
95
+
96
+ Mocks httpx for HTTP testing:
97
+
98
+ ```python
99
+ def test_pubmed_search(mock_httpx_client):
100
+ mock_httpx_client.get("https://eutils.ncbi.nlm.nih.gov/...").respond(
101
+ 200,
102
+ json={"esearchresult": {"idlist": ["12345"]}}
103
+ )
104
+
105
+ tool = PubMedTool()
106
+ result = tool.search("test query")
107
+ assert len(result.evidence) > 0
108
+ ```
109
+
110
+ #### `mock_llm_response`
111
+
112
+ Mocks LLM completions:
113
+
114
+ ```python
115
+ def test_judge_evaluates(mock_llm_response):
116
+ mock_llm_response("The evidence is sufficient.")
117
+
118
+ judge = JudgeAgent()
119
+ assessment = judge.assess(evidence)
120
+ assert assessment.sufficient
121
+ ```
122
+
123
+ #### `sample_evidence`
124
+
125
+ Provides test evidence data:
126
+
127
+ ```python
128
+ def test_synthesis(sample_evidence):
129
+ report = synthesizer.create_report(sample_evidence)
130
+ assert report.title
131
+ ```
132
+
133
+ ### Creating Fixtures
134
+
135
+ ```python
136
+ # tests/conftest.py
137
+
138
+ @pytest.fixture
139
+ def mock_search_handler(mocker):
140
+ """Mock SearchHandler for unit tests."""
141
+ handler = mocker.Mock(spec=SearchHandler)
142
+ handler.search_all.return_value = SearchResult(
143
+ query="test",
144
+ evidence=[],
145
+ sources_searched=["pubmed"],
146
+ total_found=0
147
+ )
148
+ return handler
149
+ ```
150
+
151
+ ## Mocking Patterns
152
+
153
+ ### HTTP Mocking with respx
154
+
155
+ ```python
156
+ import respx
157
+ from httpx import Response
158
+
159
+ @pytest.mark.unit
160
+ def test_api_call():
161
+ with respx.mock:
162
+ respx.get("https://api.example.com/data").mock(
163
+ return_value=Response(200, json={"result": "ok"})
164
+ )
165
+
166
+ result = make_api_call()
167
+ assert result == "ok"
168
+ ```
169
+
170
+ ### General Mocking with pytest-mock
171
+
172
+ ```python
173
+ def test_with_mock(mocker):
174
+ # Mock a function
175
+ mock_func = mocker.patch("src.tools.pubmed.fetch_results")
176
+ mock_func.return_value = {"results": []}
177
+
178
+ # Mock a class method
179
+ mocker.patch.object(PubMedTool, "search", return_value=[])
180
+
181
+ # Mock a property
182
+ mocker.patch.object(Settings, "has_openai_key", True)
183
+ ```
184
+
185
+ ### Mocking Async Functions
186
+
187
+ ```python
188
+ import pytest
189
+ from unittest.mock import AsyncMock
190
+
191
+ @pytest.mark.asyncio
192
+ async def test_async_search(mocker):
193
+ mock_search = AsyncMock(return_value=[])
194
+ mocker.patch.object(SearchHandler, "search_all", mock_search)
195
+
196
+ result = await handler.search_all("query")
197
+ assert result == []
198
+ ```
199
+
200
+ ## Writing Tests
201
+
202
+ ### Test Structure (AAA Pattern)
203
+
204
+ ```python
205
+ def test_search_handler_aggregates_results():
206
+ """Verify search handler combines results from multiple sources."""
207
+ # Arrange
208
+ handler = SearchHandler()
209
+ query = "testosterone therapy"
210
+
211
+ # Act
212
+ result = handler.search_all(query)
213
+
214
+ # Assert
215
+ assert len(result.evidence) > 0
216
+ assert "pubmed" in result.sources_searched
217
+ ```
218
+
219
+ ### Test Naming
220
+
221
+ ```python
222
+ # Good: Describes behavior
223
+ def test_judge_returns_continue_when_evidence_insufficient():
224
+ pass
225
+
226
+ def test_search_raises_rate_limit_error_on_429():
227
+ pass
228
+
229
+ # Bad: Vague
230
+ def test_judge():
231
+ pass
232
+
233
+ def test_search_error():
234
+ pass
235
+ ```
236
+
237
+ ### Testing Exceptions
238
+
239
+ ```python
240
+ import pytest
241
+ from src.utils.exceptions import SearchError
242
+
243
+ def test_search_raises_on_api_failure():
244
+ """Verify SearchError is raised when API returns error."""
245
+ with pytest.raises(SearchError) as exc_info:
246
+ search_with_failing_api()
247
+
248
+ assert "API returned 500" in str(exc_info.value)
249
+ ```
250
+
251
+ ### Async Tests
252
+
253
+ ```python
254
+ import pytest
255
+
256
+ @pytest.mark.asyncio
257
+ async def test_async_search():
258
+ """Test async search operation."""
259
+ result = await search_handler.search_all("query")
260
+ assert result is not None
261
+ ```
262
+
263
+ ## Test Data
264
+
265
+ ### Using Factories
266
+
267
+ ```python
268
+ # tests/factories.py
269
+
270
+ def make_evidence(
271
+ content: str = "Test content",
272
+ source: str = "pubmed",
273
+ relevance: float = 0.8
274
+ ) -> Evidence:
275
+ return Evidence(
276
+ content=content,
277
+ citation=Citation(
278
+ source=source,
279
+ title="Test Paper",
280
+ url="https://test.com",
281
+ date="2024-01-01",
282
+ authors=["Test Author"]
283
+ ),
284
+ relevance=relevance,
285
+ metadata={}
286
+ )
287
+ ```
288
+
289
+ ### Parameterized Tests
290
+
291
+ ```python
292
+ import pytest
293
+
294
+ @pytest.mark.parametrize("query,expected_count", [
295
+ ("testosterone", 10),
296
+ ("estrogen therapy", 5),
297
+ ("very specific rare condition", 0),
298
+ ])
299
+ def test_search_returns_expected_results(query, expected_count, mock_api):
300
+ result = search(query)
301
+ assert len(result.evidence) == expected_count
302
+ ```
303
+
304
+ ## Coverage
305
+
306
+ ### Running with Coverage
307
+
308
+ ```bash
309
+ # Terminal report
310
+ make test-cov
311
+
312
+ # HTML report
313
+ uv run pytest --cov=src --cov-report=html
314
+ open htmlcov/index.html
315
+ ```
316
+
317
+ ### Coverage Configuration
318
+
319
+ From `pyproject.toml`:
320
+
321
+ ```toml
322
+ [tool.coverage.run]
323
+ source = ["src"]
324
+ omit = ["*/__init__.py"]
325
+
326
+ [tool.coverage.report]
327
+ exclude_lines = [
328
+ "pragma: no cover",
329
+ "if TYPE_CHECKING:",
330
+ "raise NotImplementedError",
331
+ ]
332
+ ```
333
+
334
+ ### Coverage Targets
335
+
336
+ | Module | Target | Notes |
337
+ |--------|--------|-------|
338
+ | `utils/` | 90%+ | Core utilities |
339
+ | `tools/` | 80%+ | API wrappers |
340
+ | `orchestrators/` | 70%+ | Complex logic |
341
+ | `agents/` | 70%+ | LLM-dependent |
342
+
343
+ ## CI Integration
344
+
345
+ Tests run in GitHub Actions:
346
+
347
+ ```yaml
348
+ # .github/workflows/ci.yml
349
+ - name: Run Tests
350
+ run: uv run pytest --cov=src --cov-report=xml
351
+
352
+ - name: Upload Coverage
353
+ uses: codecov/codecov-action@v4
354
+ ```
355
+
356
+ ## Best Practices
357
+
358
+ ### Do
359
+
360
+ - Write tests before implementation (TDD)
361
+ - Use descriptive test names
362
+ - Test edge cases and error conditions
363
+ - Keep tests fast (mock external dependencies)
364
+ - Use fixtures for shared setup
365
+ - Test one behavior per test
366
+
367
+ ### Don't
368
+
369
+ - Test implementation details
370
+ - Make tests dependent on order
371
+ - Use real API keys in tests
372
+ - Skip error handling tests
373
+ - Leave flaky tests unfixed
374
+
375
+ ## Troubleshooting
376
+
377
+ ### Tests pass locally but fail in CI
378
+
379
+ 1. Check for hardcoded paths
380
+ 2. Verify timezone handling
381
+ 3. Look for async timing issues
382
+ 4. Check environment variables
383
+
384
+ ### Async test hangs
385
+
386
+ ```python
387
+ # Add timeout
388
+ @pytest.mark.asyncio
389
+ @pytest.mark.timeout(10)
390
+ async def test_with_timeout():
391
+ pass
392
+ ```
393
+
394
+ ### Mock not working
395
+
396
+ ```python
397
+ # Ensure correct import path
398
+ mocker.patch("src.tools.pubmed.PubMedTool") # Correct
399
+ mocker.patch("tools.pubmed.PubMedTool") # Wrong
400
+ ```
401
+
402
+ ---
403
+
404
+ ## Related Documentation
405
+
406
+ - [Code Style Guide](code-style.md)
407
+ - [Contributing Guide](../../CONTRIBUTING.md)
408
+ - [Component Inventory](../architecture/component-inventory.md)
docs/getting-started/configuration.md ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Configuration Guide
2
+
3
+ DeepBoner uses [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) for configuration, loading values from environment variables and `.env` files.
4
+
5
+ ## Configuration Sources
6
+
7
+ Settings are loaded in this order (later sources override earlier):
8
+
9
+ 1. Default values in code
10
+ 2. `.env` file in project root
11
+ 3. Environment variables
12
+
13
+ ## Quick Setup
14
+
15
+ ```bash
16
+ # Copy the template
17
+ cp .env.example .env
18
+
19
+ # Edit with your settings
20
+ nano .env # or your preferred editor
21
+ ```
22
+
23
+ ## Configuration Categories
24
+
25
+ ### LLM Configuration
26
+
27
+ | Variable | Type | Default | Description |
28
+ |----------|------|---------|-------------|
29
+ | `LLM_PROVIDER` | string | `"openai"` | LLM provider: `"openai"` or `"huggingface"` |
30
+ | `OPENAI_API_KEY` | string | None | OpenAI API key (enables premium mode) |
31
+ | `OPENAI_MODEL` | string | `"gpt-5"` | OpenAI model to use |
32
+ | `HUGGINGFACE_MODEL` | string | `"Qwen/Qwen2.5-7B-Instruct"` | HuggingFace model for free tier |
33
+ | `HF_TOKEN` | string | None | HuggingFace token for gated models |
34
+
35
+ **Notes:**
36
+ - If `OPENAI_API_KEY` is set, OpenAI is used automatically
37
+ - Without any key, free HuggingFace tier is used
38
+ - See CLAUDE.md for critical notes on HuggingFace model selection
39
+
40
+ ### Embedding Configuration
41
+
42
+ | Variable | Type | Default | Description |
43
+ |----------|------|---------|-------------|
44
+ | `OPENAI_EMBEDDING_MODEL` | string | `"text-embedding-3-small"` | OpenAI embedding model (premium RAG) |
45
+ | `LOCAL_EMBEDDING_MODEL` | string | `"all-MiniLM-L6-v2"` | Local sentence-transformers model |
46
+
47
+ ### External Services
48
+
49
+ | Variable | Type | Default | Description |
50
+ |----------|------|---------|-------------|
51
+ | `NCBI_API_KEY` | string | None | NCBI API key for higher PubMed rate limits |
52
+ | `CHROMA_DB_PATH` | string | `"./chroma_db"` | ChromaDB storage path |
53
+
54
+ ### Agent Configuration
55
+
56
+ | Variable | Type | Default | Description |
57
+ |----------|------|---------|-------------|
58
+ | `MAX_ITERATIONS` | int | `10` | Maximum search-judge loop iterations (1-50) |
59
+ | `ADVANCED_MAX_ROUNDS` | int | `5` | Max coordination rounds for multi-agent mode |
60
+ | `ADVANCED_TIMEOUT` | float | `600.0` | Timeout for advanced mode in seconds |
61
+ | `SEARCH_TIMEOUT` | int | `30` | Seconds to wait for each search operation |
62
+
63
+ ### Logging
64
+
65
+ | Variable | Type | Default | Description |
66
+ |----------|------|---------|-------------|
67
+ | `LOG_LEVEL` | string | `"INFO"` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
68
+
69
+ ## Example Configurations
70
+
71
+ ### Minimal (Free Tier)
72
+
73
+ ```bash
74
+ # .env - No keys required
75
+ LOG_LEVEL=INFO
76
+ MAX_ITERATIONS=5
77
+ ```
78
+
79
+ ### Development
80
+
81
+ ```bash
82
+ # .env
83
+ LOG_LEVEL=DEBUG
84
+ MAX_ITERATIONS=3
85
+ SEARCH_TIMEOUT=15
86
+ ```
87
+
88
+ ### Production (With OpenAI)
89
+
90
+ ```bash
91
+ # .env
92
+ OPENAI_API_KEY=sk-your-production-key
93
+ NCBI_API_KEY=your-ncbi-key
94
+ LOG_LEVEL=WARNING
95
+ MAX_ITERATIONS=10
96
+ CHROMA_DB_PATH=/data/chroma_db
97
+ ```
98
+
99
+ ### HuggingFace Spaces
100
+
101
+ ```bash
102
+ # Set as Secrets in Space Settings
103
+ HF_TOKEN=hf_your-token
104
+ NCBI_API_KEY=your-ncbi-key
105
+ ```
106
+
107
+ ## Backend Selection Logic
108
+
109
+ The system auto-selects backends based on available keys:
110
+
111
+ ```
112
+ Has OPENAI_API_KEY?
113
+ β”œβ”€β”€ YES β†’ OpenAI GPT-5 (premium)
114
+ └── NO β†’ HuggingFace Qwen 2.5 7B (free)
115
+ ```
116
+
117
+ Both backends use the same orchestration logic - only the LLM differs.
118
+
119
+ ## Programmatic Access
120
+
121
+ Access settings in code:
122
+
123
+ ```python
124
+ from src.utils.config import settings
125
+
126
+ # Check available backends
127
+ if settings.has_openai_key:
128
+ print("Premium mode available")
129
+
130
+ # Get specific settings
131
+ print(f"Max iterations: {settings.max_iterations}")
132
+ print(f"Log level: {settings.log_level}")
133
+ ```
134
+
135
+ ## Validation
136
+
137
+ Settings are validated on load:
138
+
139
+ ```python
140
+ from src.utils.config import Settings
141
+
142
+ # These will raise ValidationError
143
+ Settings(max_iterations=100) # Must be 1-50
144
+ Settings(log_level="TRACE") # Invalid level
145
+ ```
146
+
147
+ ## Security Notes
148
+
149
+ - Never commit `.env` files to git
150
+ - Use environment variables in production
151
+ - API keys are never logged
152
+ - See [SECURITY.md](../../SECURITY.md) for full security policy
153
+
154
+ ## Troubleshooting
155
+
156
+ **Settings not loading?**
157
+ - Check file is named `.env` (not `.env.txt`)
158
+ - Verify file is in project root
159
+ - Check for syntax errors (no spaces around `=`)
160
+
161
+ **API key not working?**
162
+ - Verify key is valid and not expired
163
+ - Check for trailing whitespace
164
+ - Ensure correct variable name
165
+
166
+ See [Troubleshooting](troubleshooting.md) for more help.
167
+
168
+ ## Related Documentation
169
+
170
+ - [Environment Variables Reference](../reference/environment-variables.md)
171
+ - [Installation Guide](installation.md)
172
+ - [Deployment Guide](../deployment/docker.md)
docs/getting-started/installation.md ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Installation Guide
2
+
3
+ This guide covers installing DeepBoner for development or local use.
4
+
5
+ ## Prerequisites
6
+
7
+ ### Required
8
+ - **Python 3.11+** - Required for type hints and async features
9
+ - **uv** - Fast Python package manager ([install guide](https://github.com/astral-sh/uv))
10
+ - **Git** - For version control
11
+
12
+ ### Optional
13
+ - **Docker** - For containerized deployment
14
+ - **OpenAI API key** - For premium features (GPT-5)
15
+ - **NCBI API key** - For higher PubMed rate limits
16
+
17
+ ## Quick Install
18
+
19
+ ```bash
20
+ # Clone the repository
21
+ git clone https://github.com/The-Obstacle-Is-The-Way/DeepBoner.git
22
+ cd DeepBoner
23
+
24
+ # Install all dependencies (including dev tools)
25
+ make install
26
+ ```
27
+
28
+ This runs `uv sync --all-extras && uv run pre-commit install` behind the scenes.
29
+
30
+ ## Manual Installation
31
+
32
+ If you prefer not to use `make`:
33
+
34
+ ```bash
35
+ # Install uv if not already installed
36
+ pip install uv
37
+
38
+ # Sync all dependencies
39
+ uv sync --all-extras
40
+
41
+ # Install pre-commit hooks
42
+ uv run pre-commit install
43
+ ```
44
+
45
+ ## Optional Dependencies
46
+
47
+ DeepBoner has optional dependency groups for specific features:
48
+
49
+ ```bash
50
+ # Core only (no dev tools)
51
+ uv sync
52
+
53
+ # With development tools
54
+ uv sync --extra dev
55
+
56
+ # With Microsoft Agent Framework (Magentic)
57
+ uv sync --extra magentic
58
+
59
+ # With LlamaIndex RAG support
60
+ uv sync --extra rag
61
+
62
+ # Everything
63
+ uv sync --all-extras
64
+ ```
65
+
66
+ ## Environment Configuration
67
+
68
+ 1. Copy the example environment file:
69
+ ```bash
70
+ cp .env.example .env
71
+ ```
72
+
73
+ 2. Edit `.env` with your settings:
74
+ ```bash
75
+ # Required for premium features
76
+ OPENAI_API_KEY=sk-your-key-here
77
+
78
+ # Optional: Higher PubMed rate limits
79
+ NCBI_API_KEY=your-ncbi-key-here
80
+
81
+ # Optional: HuggingFace token for gated models
82
+ HF_TOKEN=hf_your-token-here
83
+ ```
84
+
85
+ See [Configuration Guide](configuration.md) for all options.
86
+
87
+ ## Verify Installation
88
+
89
+ Run the quality checks to verify everything works:
90
+
91
+ ```bash
92
+ make check
93
+ ```
94
+
95
+ This runs:
96
+ - Linting (ruff)
97
+ - Type checking (mypy)
98
+ - Unit tests (pytest)
99
+
100
+ All checks should pass before you start development.
101
+
102
+ ## Running the Application
103
+
104
+ Start the Gradio UI:
105
+
106
+ ```bash
107
+ uv run python src/app.py
108
+ ```
109
+
110
+ Open http://localhost:7860 in your browser.
111
+
112
+ ## Docker Installation
113
+
114
+ For containerized deployment:
115
+
116
+ ```bash
117
+ # Build the image
118
+ docker build -t deepboner .
119
+
120
+ # Run the container
121
+ docker run -p 7860:7860 --env-file .env deepboner
122
+ ```
123
+
124
+ See [Docker Deployment](../deployment/docker.md) for details.
125
+
126
+ ## Troubleshooting
127
+
128
+ ### Common Issues
129
+
130
+ **uv not found**
131
+ ```bash
132
+ pip install uv
133
+ # or
134
+ curl -LsSf https://astral.sh/uv/install.sh | sh
135
+ ```
136
+
137
+ **Python version mismatch**
138
+ ```bash
139
+ # Check your Python version
140
+ python --version
141
+
142
+ # Should be 3.11 or higher
143
+ # Use pyenv to manage versions if needed
144
+ ```
145
+
146
+ **Pre-commit hook failures**
147
+ ```bash
148
+ # Run formatting to fix most issues
149
+ make format
150
+ ```
151
+
152
+ **Import errors after install**
153
+ ```bash
154
+ # Ensure you're using uv run
155
+ uv run python -c "import src.app"
156
+ ```
157
+
158
+ See [Troubleshooting](troubleshooting.md) for more solutions.
159
+
160
+ ## Next Steps
161
+
162
+ - [Quickstart Guide](quickstart.md) - Run your first query
163
+ - [Configuration Guide](configuration.md) - Configure all options
164
+ - [Architecture Overview](../architecture/overview.md) - Understand the system
docs/getting-started/quickstart.md ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Quickstart Guide
2
+
3
+ Get DeepBoner running in 5 minutes.
4
+
5
+ ## Prerequisites
6
+
7
+ - Python 3.11+ installed
8
+ - Repository cloned and dependencies installed (see [Installation](installation.md))
9
+
10
+ ## 1. Start the Application
11
+
12
+ ```bash
13
+ # From the repository root
14
+ uv run python src/app.py
15
+ ```
16
+
17
+ You should see:
18
+ ```
19
+ Running on local URL: http://127.0.0.1:7860
20
+ ```
21
+
22
+ ## 2. Open the UI
23
+
24
+ Navigate to http://localhost:7860 in your browser.
25
+
26
+ You'll see a chat interface with:
27
+ - Input field for research questions
28
+ - Optional API key input (for premium features)
29
+ - Research results display
30
+
31
+ ## 3. Ask Your First Question
32
+
33
+ Try one of these example queries:
34
+
35
+ ```
36
+ What drugs improve female libido post-menopause?
37
+ ```
38
+
39
+ ```
40
+ Clinical trials for ED alternatives to PDE5 inhibitors?
41
+ ```
42
+
43
+ ```
44
+ Evidence for testosterone therapy in women with HSDD?
45
+ ```
46
+
47
+ ## 4. Understanding the Output
48
+
49
+ DeepBoner will:
50
+
51
+ 1. **Search** multiple biomedical databases:
52
+ - PubMed (peer-reviewed literature)
53
+ - ClinicalTrials.gov (active/completed trials)
54
+ - Europe PMC (preprints and papers)
55
+ - OpenAlex (scholarly metadata)
56
+
57
+ 2. **Judge** evidence quality using LLM
58
+
59
+ 3. **Loop** if more evidence is needed
60
+
61
+ 4. **Synthesize** a research report with citations
62
+
63
+ You'll see status updates as each phase completes.
64
+
65
+ ## 5. Free vs Premium Mode
66
+
67
+ ### Free Mode (No API Key)
68
+
69
+ - Uses HuggingFace Inference API
70
+ - Model: Qwen 2.5 7B Instruct
71
+ - Slower but fully functional
72
+
73
+ ### Premium Mode (With OpenAI Key)
74
+
75
+ - Enter your OpenAI API key in the UI
76
+ - Uses GPT-5 for better synthesis
77
+ - Faster and more detailed reports
78
+
79
+ To use premium mode:
80
+ 1. Get an API key from [OpenAI](https://platform.openai.com)
81
+ 2. Enter it in the "OpenAI API Key" field
82
+ 3. Your queries will automatically use GPT-5
83
+
84
+ ## 6. Using MCP Tools
85
+
86
+ DeepBoner exposes MCP (Model Context Protocol) tools for integration with Claude Desktop and other clients.
87
+
88
+ ### MCP Server URL
89
+ ```
90
+ http://localhost:7860/gradio_api/mcp/
91
+ ```
92
+
93
+ ### Available Tools
94
+ - `search_pubmed` - Search peer-reviewed literature
95
+ - `search_clinical_trials` - Search clinical trials
96
+ - `search_europepmc` - Search Europe PMC
97
+ - `search_all_sources` - Search all sources with deduplication
98
+
99
+ ### Claude Desktop Configuration
100
+
101
+ Add to your `claude_desktop_config.json`:
102
+ ```json
103
+ {
104
+ "mcpServers": {
105
+ "deepboner": {
106
+ "url": "http://localhost:7860/gradio_api/mcp/"
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ ## Example Scripts
113
+
114
+ For programmatic usage, see the example scripts:
115
+
116
+ ```bash
117
+ # Search demo
118
+ uv run python examples/search_demo/run_search.py
119
+
120
+ # Full orchestrator demo
121
+ uv run python examples/orchestrator_demo/run_agent.py
122
+
123
+ # Multi-agent demo (requires OpenAI key)
124
+ uv run python examples/orchestrator_demo/run_magentic.py
125
+ ```
126
+
127
+ ## Next Steps
128
+
129
+ - [Configuration Guide](configuration.md) - Customize settings
130
+ - [MCP Integration](../deployment/mcp-integration.md) - Set up Claude Desktop
131
+ - [Architecture Overview](../architecture/overview.md) - Understand how it works
132
+
133
+ ## Troubleshooting
134
+
135
+ **Slow first response?**
136
+ - First query loads ML models (sentence-transformers)
137
+ - Subsequent queries are faster
138
+
139
+ **No results?**
140
+ - Check your internet connection
141
+ - External APIs may have rate limits
142
+
143
+ **Rate limit errors?**
144
+ - Add NCBI_API_KEY for higher PubMed limits
145
+ - Wait and retry
146
+
147
+ See [Troubleshooting](troubleshooting.md) for more help.
docs/getting-started/troubleshooting.md ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Troubleshooting Guide
2
+
3
+ Common issues and their solutions.
4
+
5
+ ## Installation Issues
6
+
7
+ ### uv not found
8
+
9
+ **Symptom:** `command not found: uv`
10
+
11
+ **Solution:**
12
+ ```bash
13
+ # Install uv
14
+ pip install uv
15
+ # or
16
+ curl -LsSf https://astral.sh/uv/install.sh | sh
17
+ ```
18
+
19
+ ### Python version mismatch
20
+
21
+ **Symptom:** `Python 3.11+ required` or syntax errors
22
+
23
+ **Solution:**
24
+ ```bash
25
+ # Check version
26
+ python --version
27
+
28
+ # Install Python 3.11+ via pyenv
29
+ pyenv install 3.11
30
+ pyenv local 3.11
31
+ ```
32
+
33
+ ### Dependency conflicts
34
+
35
+ **Symptom:** Package version conflicts during install
36
+
37
+ **Solution:**
38
+ ```bash
39
+ # Clean install
40
+ rm -rf .venv uv.lock
41
+ uv sync --all-extras
42
+ ```
43
+
44
+ ## Runtime Issues
45
+
46
+ ### Slow first query
47
+
48
+ **Symptom:** First query takes 30+ seconds
49
+
50
+ **Cause:** Model loading (sentence-transformers) on first use
51
+
52
+ **Solution:** This is expected. Subsequent queries are faster.
53
+
54
+ ### Rate limit errors
55
+
56
+ **Symptom:** `RateLimitError` or 429 HTTP status
57
+
58
+ **Cause:** Too many requests to external APIs
59
+
60
+ **Solutions:**
61
+ 1. Add NCBI API key for PubMed:
62
+ ```bash
63
+ NCBI_API_KEY=your-key-here
64
+ ```
65
+ 2. Wait and retry (rate limits reset)
66
+ 3. Reduce `MAX_ITERATIONS`
67
+
68
+ ### No search results
69
+
70
+ **Symptom:** Empty results from searches
71
+
72
+ **Possible causes:**
73
+ - Network issues
74
+ - External API downtime
75
+ - Query too specific
76
+
77
+ **Solutions:**
78
+ 1. Check internet connection
79
+ 2. Try a broader query
80
+ 3. Check API status:
81
+ - [PubMed Status](https://www.ncbi.nlm.nih.gov/Status/)
82
+ - [ClinicalTrials.gov](https://clinicaltrials.gov/)
83
+
84
+ ### HuggingFace 500/401 errors
85
+
86
+ **Symptom:** Internal server errors or auth errors from HuggingFace
87
+
88
+ **Cause:** Large models (70B+) are routed to unreliable third-party providers
89
+
90
+ **Solution:** Use default model (Qwen 2.5 7B) which stays on HuggingFace native infrastructure. See CLAUDE.md for details.
91
+
92
+ ### OpenAI API errors
93
+
94
+ **Symptom:** Authentication errors with OpenAI
95
+
96
+ **Solutions:**
97
+ 1. Verify key is valid: https://platform.openai.com/api-keys
98
+ 2. Check for typos in `.env`
99
+ 3. Ensure no trailing whitespace
100
+ 4. Check quota: https://platform.openai.com/usage
101
+
102
+ ### Import errors
103
+
104
+ **Symptom:** `ModuleNotFoundError` when running
105
+
106
+ **Solution:**
107
+ ```bash
108
+ # Always use uv run
109
+ uv run python src/app.py
110
+
111
+ # Not this
112
+ python src/app.py # Won't find dependencies
113
+ ```
114
+
115
+ ### ChromaDB errors
116
+
117
+ **Symptom:** Embedding or vector store errors
118
+
119
+ **Solutions:**
120
+ ```bash
121
+ # Clear the database
122
+ rm -rf ./chroma_db
123
+
124
+ # Verify path is writable
125
+ ls -la ./
126
+ ```
127
+
128
+ ## Development Issues
129
+
130
+ ### Pre-commit hook failures
131
+
132
+ **Symptom:** Commits rejected by pre-commit
133
+
134
+ **Solution:**
135
+ ```bash
136
+ # Auto-fix formatting
137
+ make format
138
+
139
+ # Check manually
140
+ make lint
141
+ make typecheck
142
+ ```
143
+
144
+ ### Type checking errors
145
+
146
+ **Symptom:** mypy errors on valid code
147
+
148
+ **Solutions:**
149
+ ```bash
150
+ # Update stubs
151
+ uv add --dev types-package-name
152
+
153
+ # Or add ignore comment (last resort)
154
+ # type: ignore[error-code]
155
+ ```
156
+
157
+ ### Test failures
158
+
159
+ **Symptom:** Tests pass locally but fail in CI
160
+
161
+ **Possible causes:**
162
+ - Environment differences
163
+ - Async timing issues
164
+ - Missing test data
165
+
166
+ **Solutions:**
167
+ ```bash
168
+ # Run exactly like CI
169
+ make check
170
+
171
+ # Run specific test with verbose output
172
+ uv run pytest tests/unit/path/test_file.py -v -s
173
+ ```
174
+
175
+ ## UI Issues
176
+
177
+ ### Gradio not starting
178
+
179
+ **Symptom:** Application exits immediately or port conflict
180
+
181
+ **Solutions:**
182
+ ```bash
183
+ # Check if port is in use
184
+ lsof -i :7860
185
+
186
+ # Kill existing process
187
+ kill -9 $(lsof -t -i :7860)
188
+
189
+ # Or use different port
190
+ uv run python -c "import gradio; print(gradio.__version__)"
191
+ ```
192
+
193
+ ### MCP tools not appearing
194
+
195
+ **Symptom:** Claude Desktop doesn't show DeepBoner tools
196
+
197
+ **Solutions:**
198
+ 1. Verify URL: `http://localhost:7860/gradio_api/mcp/`
199
+ 2. Check Claude Desktop config syntax
200
+ 3. Restart Claude Desktop after config change
201
+ 4. Ensure DeepBoner is running
202
+
203
+ ## Deployment Issues
204
+
205
+ ### Docker build fails
206
+
207
+ **Symptom:** Dockerfile build errors
208
+
209
+ **Solutions:**
210
+ ```bash
211
+ # Clean build
212
+ docker build --no-cache -t deepboner .
213
+
214
+ # Check disk space
215
+ docker system df
216
+ docker system prune
217
+ ```
218
+
219
+ ### Container exits immediately
220
+
221
+ **Symptom:** Container starts and stops
222
+
223
+ **Solution:**
224
+ ```bash
225
+ # Check logs
226
+ docker logs <container_id>
227
+
228
+ # Run interactively
229
+ docker run -it deepboner bash
230
+ ```
231
+
232
+ ### HuggingFace Spaces issues
233
+
234
+ **Symptom:** Space fails to build or run
235
+
236
+ **Solutions:**
237
+ 1. Check Spaces logs in HuggingFace UI
238
+ 2. Verify `requirements.txt` matches `pyproject.toml`
239
+ 3. Check secrets are set correctly
240
+
241
+ ## Getting More Help
242
+
243
+ ### Enable debug logging
244
+
245
+ ```bash
246
+ LOG_LEVEL=DEBUG uv run python src/app.py
247
+ ```
248
+
249
+ ### Check system info
250
+
251
+ ```bash
252
+ uv run python -c "
253
+ import sys
254
+ print(f'Python: {sys.version}')
255
+
256
+ import src
257
+ print(f'DeepBoner loaded')
258
+
259
+ from src.utils.config import settings
260
+ print(f'OpenAI key: {bool(settings.openai_api_key)}')
261
+ print(f'HF key: {bool(settings.hf_token)}')
262
+ "
263
+ ```
264
+
265
+ ### Report an issue
266
+
267
+ If you can't resolve the issue:
268
+
269
+ 1. Search existing issues: https://github.com/The-Obstacle-Is-The-Way/DeepBoner/issues
270
+ 2. Create a new issue with:
271
+ - Steps to reproduce
272
+ - Expected vs actual behavior
273
+ - Environment info (Python version, OS)
274
+ - Relevant logs (redact API keys)
275
+
276
+ ## Related Documentation
277
+
278
+ - [Installation Guide](installation.md)
279
+ - [Configuration Guide](configuration.md)
280
+ - [SECURITY.md](../../SECURITY.md)
docs/reference/configuration.md ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Configuration Reference
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ Complete reference for all configuration options in DeepBoner.
6
+
7
+ ## Configuration System
8
+
9
+ DeepBoner uses [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) for configuration management.
10
+
11
+ ### Loading Order
12
+
13
+ 1. Default values in code (`src/utils/config.py`)
14
+ 2. `.env` file in project root
15
+ 3. Environment variables (highest priority)
16
+
17
+ ### Location
18
+
19
+ ```
20
+ /home/user/DeepBoner/
21
+ β”œβ”€β”€ .env # Your configuration (not in git)
22
+ β”œβ”€β”€ .env.example # Template (in git)
23
+ └── src/utils/config.py # Settings class
24
+ ```
25
+
26
+ ## Settings Class
27
+
28
+ ```python
29
+ from src.utils.config import settings
30
+
31
+ # Access settings
32
+ print(settings.max_iterations)
33
+ print(settings.has_openai_key)
34
+ ```
35
+
36
+ ## Configuration Categories
37
+
38
+ ### LLM Configuration
39
+
40
+ | Setting | Type | Default | Env Variable | Description |
41
+ |---------|------|---------|--------------|-------------|
42
+ | `llm_provider` | Literal["openai", "huggingface"] | `"openai"` | `LLM_PROVIDER` | LLM backend to use |
43
+ | `openai_api_key` | str \| None | None | `OPENAI_API_KEY` | OpenAI API key |
44
+ | `openai_model` | str | `"gpt-5"` | `OPENAI_MODEL` | OpenAI model name |
45
+ | `huggingface_model` | str \| None | `"Qwen/Qwen2.5-7B-Instruct"` | `HUGGINGFACE_MODEL` | HuggingFace model |
46
+ | `hf_token` | str \| None | None | `HF_TOKEN` | HuggingFace API token |
47
+
48
+ ### Embedding Configuration
49
+
50
+ | Setting | Type | Default | Env Variable | Description |
51
+ |---------|------|---------|--------------|-------------|
52
+ | `openai_embedding_model` | str | `"text-embedding-3-small"` | `OPENAI_EMBEDDING_MODEL` | OpenAI embeddings model |
53
+ | `local_embedding_model` | str | `"all-MiniLM-L6-v2"` | `LOCAL_EMBEDDING_MODEL` | Local sentence-transformers model |
54
+
55
+ ### External Services
56
+
57
+ | Setting | Type | Default | Env Variable | Description |
58
+ |---------|------|---------|--------------|-------------|
59
+ | `ncbi_api_key` | str \| None | None | `NCBI_API_KEY` | NCBI API key for PubMed |
60
+ | `chroma_db_path` | str | `"./chroma_db"` | `CHROMA_DB_PATH` | ChromaDB storage path |
61
+
62
+ ### Agent Configuration
63
+
64
+ | Setting | Type | Default | Env Variable | Description |
65
+ |---------|------|---------|--------------|-------------|
66
+ | `max_iterations` | int | 10 | `MAX_ITERATIONS` | Max search-judge iterations (1-50) |
67
+ | `advanced_max_rounds` | int | 5 | `ADVANCED_MAX_ROUNDS` | Max multi-agent rounds (1-20) |
68
+ | `advanced_timeout` | float | 600.0 | `ADVANCED_TIMEOUT` | Advanced mode timeout seconds (60-900) |
69
+ | `search_timeout` | int | 30 | `SEARCH_TIMEOUT` | Per-search timeout seconds |
70
+
71
+ ### Domain Configuration
72
+
73
+ | Setting | Type | Default | Env Variable | Description |
74
+ |---------|------|---------|--------------|-------------|
75
+ | `research_domain` | ResearchDomain | `SEXUAL_HEALTH` | `RESEARCH_DOMAIN` | Research domain focus |
76
+
77
+ ### Logging
78
+
79
+ | Setting | Type | Default | Env Variable | Description |
80
+ |---------|------|---------|--------------|-------------|
81
+ | `log_level` | Literal["DEBUG", "INFO", "WARNING", "ERROR"] | `"INFO"` | `LOG_LEVEL` | Logging verbosity |
82
+
83
+ ## Helper Properties
84
+
85
+ The Settings class provides convenience properties:
86
+
87
+ ```python
88
+ settings.has_openai_key # bool - Is OpenAI key set?
89
+ settings.has_huggingface_key # bool - Is HF token set?
90
+ settings.has_any_llm_key # bool - Any LLM key available?
91
+ ```
92
+
93
+ ## Helper Methods
94
+
95
+ ```python
96
+ # Get API key for configured provider
97
+ api_key = settings.get_api_key()
98
+
99
+ # Get OpenAI key (raises ConfigurationError if not set)
100
+ openai_key = settings.get_openai_api_key()
101
+ ```
102
+
103
+ ## Backend Selection Logic
104
+
105
+ ```python
106
+ # Automatic backend selection
107
+ if settings.has_openai_key:
108
+ # Use OpenAI GPT-5
109
+ client = OpenAIChatClient(api_key=settings.openai_api_key)
110
+ else:
111
+ # Use HuggingFace free tier
112
+ client = HuggingFaceChatClient(model=settings.huggingface_model)
113
+ ```
114
+
115
+ ## Validation
116
+
117
+ Settings are validated on load:
118
+
119
+ ```python
120
+ # These will raise ValidationError
121
+ Settings(max_iterations=100) # Must be 1-50
122
+ Settings(log_level="TRACE") # Invalid level
123
+ Settings(advanced_timeout=10) # Minimum is 60
124
+ ```
125
+
126
+ ## Example Configurations
127
+
128
+ ### Minimal (Free Tier)
129
+
130
+ ```bash
131
+ # .env
132
+ LOG_LEVEL=INFO
133
+ MAX_ITERATIONS=5
134
+ ```
135
+
136
+ ### Development
137
+
138
+ ```bash
139
+ # .env
140
+ LOG_LEVEL=DEBUG
141
+ MAX_ITERATIONS=3
142
+ SEARCH_TIMEOUT=15
143
+ ```
144
+
145
+ ### Production (Premium)
146
+
147
+ ```bash
148
+ # .env
149
+ OPENAI_API_KEY=sk-...
150
+ NCBI_API_KEY=...
151
+ LOG_LEVEL=WARNING
152
+ MAX_ITERATIONS=10
153
+ ADVANCED_TIMEOUT=300
154
+ CHROMA_DB_PATH=/data/chroma
155
+ ```
156
+
157
+ ### HuggingFace Spaces
158
+
159
+ Set as Secrets (not Variables) in Space Settings:
160
+
161
+ ```
162
+ HF_TOKEN=hf_...
163
+ NCBI_API_KEY=...
164
+ ```
165
+
166
+ ## Programmatic Configuration
167
+
168
+ Override settings in code (useful for testing):
169
+
170
+ ```python
171
+ from src.utils.config import Settings
172
+
173
+ # Create with overrides
174
+ test_settings = Settings(
175
+ max_iterations=3,
176
+ log_level="DEBUG",
177
+ _env_file=None # Ignore .env
178
+ )
179
+ ```
180
+
181
+ ## Related Documentation
182
+
183
+ - [Environment Variables](environment-variables.md)
184
+ - [Getting Started - Configuration](../getting-started/configuration.md)
185
+ - [Troubleshooting](../getting-started/troubleshooting.md)
docs/reference/environment-variables.md ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment Variables Reference
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ Complete reference for all environment variables used by DeepBoner.
6
+
7
+ ## Quick Reference
8
+
9
+ | Variable | Required | Default | Description |
10
+ |----------|----------|---------|-------------|
11
+ | `OPENAI_API_KEY` | No* | - | OpenAI API key |
12
+ | `HF_TOKEN` | No | - | HuggingFace token |
13
+ | `NCBI_API_KEY` | No | - | NCBI/PubMed API key |
14
+ | `LLM_PROVIDER` | No | `openai` | LLM backend |
15
+ | `MAX_ITERATIONS` | No | `10` | Max search iterations |
16
+ | `LOG_LEVEL` | No | `INFO` | Logging level |
17
+
18
+ *At least one of OPENAI_API_KEY or HF_TOKEN is needed for full functionality.
19
+
20
+ ## LLM Configuration
21
+
22
+ ### OPENAI_API_KEY
23
+
24
+ OpenAI API key for premium features.
25
+
26
+ ```bash
27
+ OPENAI_API_KEY=sk-proj-xxxx
28
+ ```
29
+
30
+ - **Format:** Starts with `sk-` or `sk-proj-`
31
+ - **Source:** https://platform.openai.com/api-keys
32
+ - **Effect:** Enables OpenAI GPT-5 as the LLM backend
33
+
34
+ ### ANTHROPIC_API_KEY
35
+
36
+ Anthropic API key (reserved for future use).
37
+
38
+ ```bash
39
+ ANTHROPIC_API_KEY=sk-ant-xxxx
40
+ ```
41
+
42
+ ### LLM_PROVIDER
43
+
44
+ Explicitly select LLM provider.
45
+
46
+ ```bash
47
+ LLM_PROVIDER=openai # Use OpenAI
48
+ LLM_PROVIDER=huggingface # Use HuggingFace
49
+ ```
50
+
51
+ - **Default:** `openai`
52
+ - **Note:** Auto-detection uses OPENAI_API_KEY presence
53
+
54
+ ### OPENAI_MODEL
55
+
56
+ OpenAI model name.
57
+
58
+ ```bash
59
+ OPENAI_MODEL=gpt-5
60
+ OPENAI_MODEL=gpt-4o
61
+ ```
62
+
63
+ - **Default:** `gpt-5`
64
+
65
+ ### HUGGINGFACE_MODEL
66
+
67
+ HuggingFace model for free tier.
68
+
69
+ ```bash
70
+ HUGGINGFACE_MODEL=Qwen/Qwen2.5-7B-Instruct
71
+ ```
72
+
73
+ - **Default:** `Qwen/Qwen2.5-7B-Instruct`
74
+ - **Warning:** Large models (70B+) route to unreliable third-party providers
75
+
76
+ ### HF_TOKEN
77
+
78
+ HuggingFace API token.
79
+
80
+ ```bash
81
+ HF_TOKEN=hf_xxxx
82
+ ```
83
+
84
+ - **Source:** https://huggingface.co/settings/tokens
85
+ - **Effect:** Enables gated models and higher rate limits
86
+
87
+ ## Embedding Configuration
88
+
89
+ ### OPENAI_EMBEDDING_MODEL
90
+
91
+ OpenAI embedding model for premium RAG.
92
+
93
+ ```bash
94
+ OPENAI_EMBEDDING_MODEL=text-embedding-3-small
95
+ OPENAI_EMBEDDING_MODEL=text-embedding-3-large
96
+ ```
97
+
98
+ - **Default:** `text-embedding-3-small`
99
+ - **Requires:** `OPENAI_API_KEY`
100
+
101
+ ### LOCAL_EMBEDDING_MODEL
102
+
103
+ Local sentence-transformers model.
104
+
105
+ ```bash
106
+ LOCAL_EMBEDDING_MODEL=all-MiniLM-L6-v2
107
+ LOCAL_EMBEDDING_MODEL=all-mpnet-base-v2
108
+ ```
109
+
110
+ - **Default:** `all-MiniLM-L6-v2`
111
+ - **Note:** Downloaded on first use
112
+
113
+ ## External Services
114
+
115
+ ### NCBI_API_KEY
116
+
117
+ NCBI API key for higher PubMed rate limits.
118
+
119
+ ```bash
120
+ NCBI_API_KEY=xxxx
121
+ ```
122
+
123
+ - **Source:** https://www.ncbi.nlm.nih.gov/account/settings/
124
+ - **Effect:** 10 requests/second instead of 3
125
+
126
+ ### CHROMA_DB_PATH
127
+
128
+ ChromaDB storage location.
129
+
130
+ ```bash
131
+ CHROMA_DB_PATH=./chroma_db
132
+ CHROMA_DB_PATH=/data/vectors
133
+ ```
134
+
135
+ - **Default:** `./chroma_db`
136
+ - **Note:** Directory is created if it doesn't exist
137
+
138
+ ## Agent Configuration
139
+
140
+ ### MAX_ITERATIONS
141
+
142
+ Maximum search-judge loop iterations.
143
+
144
+ ```bash
145
+ MAX_ITERATIONS=10
146
+ MAX_ITERATIONS=5 # Faster but less thorough
147
+ MAX_ITERATIONS=20 # More thorough
148
+ ```
149
+
150
+ - **Default:** `10`
151
+ - **Range:** `1` to `50`
152
+
153
+ ### ADVANCED_MAX_ROUNDS
154
+
155
+ Maximum multi-agent coordination rounds.
156
+
157
+ ```bash
158
+ ADVANCED_MAX_ROUNDS=5
159
+ ```
160
+
161
+ - **Default:** `5`
162
+ - **Range:** `1` to `20`
163
+
164
+ ### ADVANCED_TIMEOUT
165
+
166
+ Timeout for advanced mode in seconds.
167
+
168
+ ```bash
169
+ ADVANCED_TIMEOUT=600 # 10 minutes
170
+ ADVANCED_TIMEOUT=300 # 5 minutes
171
+ ```
172
+
173
+ - **Default:** `600.0`
174
+ - **Range:** `60.0` to `900.0`
175
+
176
+ ### SEARCH_TIMEOUT
177
+
178
+ Per-search operation timeout in seconds.
179
+
180
+ ```bash
181
+ SEARCH_TIMEOUT=30
182
+ ```
183
+
184
+ - **Default:** `30`
185
+
186
+ ## Logging
187
+
188
+ ### LOG_LEVEL
189
+
190
+ Logging verbosity.
191
+
192
+ ```bash
193
+ LOG_LEVEL=DEBUG # Verbose
194
+ LOG_LEVEL=INFO # Normal
195
+ LOG_LEVEL=WARNING # Errors and warnings
196
+ LOG_LEVEL=ERROR # Errors only
197
+ ```
198
+
199
+ - **Default:** `INFO`
200
+
201
+ ## Gradio Configuration
202
+
203
+ ### GRADIO_SERVER_NAME
204
+
205
+ Server bind address.
206
+
207
+ ```bash
208
+ GRADIO_SERVER_NAME=0.0.0.0 # All interfaces
209
+ GRADIO_SERVER_NAME=127.0.0.1 # Localhost only
210
+ ```
211
+
212
+ - **Default:** Set in Dockerfile for containers
213
+
214
+ ### GRADIO_SERVER_PORT
215
+
216
+ Server port.
217
+
218
+ ```bash
219
+ GRADIO_SERVER_PORT=7860
220
+ ```
221
+
222
+ - **Default:** `7860`
223
+
224
+ ## Python Configuration
225
+
226
+ ### PYTHONPATH
227
+
228
+ Python module search path.
229
+
230
+ ```bash
231
+ PYTHONPATH=/app
232
+ ```
233
+
234
+ - **Note:** Set automatically in Docker
235
+
236
+ ## .env File Format
237
+
238
+ ```bash
239
+ # Comments start with #
240
+ KEY=value # No quotes needed for simple values
241
+ KEY="value" # Quotes for values with spaces
242
+ KEY='value' # Single quotes also work
243
+
244
+ # Empty lines are ignored
245
+
246
+ # Multi-line values not supported - use single line
247
+ ```
248
+
249
+ ## Security Notes
250
+
251
+ 1. **Never commit .env files** - They're in .gitignore
252
+ 2. **Use secrets for production** - HuggingFace Secrets, Docker secrets
253
+ 3. **Rotate keys regularly** - Especially for production
254
+ 4. **Limit permissions** - Use read-only keys where possible
255
+
256
+ ## Validation
257
+
258
+ Variables are validated on application startup:
259
+
260
+ ```python
261
+ # Invalid values raise ValidationError
262
+ MAX_ITERATIONS=100 # Error: must be 1-50
263
+ LOG_LEVEL=TRACE # Error: invalid level
264
+ ```
265
+
266
+ ## Debugging
267
+
268
+ Check loaded configuration:
269
+
270
+ ```bash
271
+ LOG_LEVEL=DEBUG uv run python -c "
272
+ from src.utils.config import settings
273
+ print(f'Provider: {settings.llm_provider}')
274
+ print(f'Has OpenAI: {settings.has_openai_key}')
275
+ print(f'Has HF: {settings.has_huggingface_key}')
276
+ print(f'Max Iterations: {settings.max_iterations}')
277
+ "
278
+ ```
279
+
280
+ ## Related Documentation
281
+
282
+ - [Configuration Reference](configuration.md)
283
+ - [Getting Started - Configuration](../getting-started/configuration.md)
284
+ - [Deployment - Docker](../deployment/docker.md)
docs/technical-debt/debt-registry.md ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Technical Debt Registry
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This document tracks all known technical debt items in the DeepBoner codebase.
6
+
7
+ ## Summary Dashboard
8
+
9
+ | Category | Open | In Progress | Resolved |
10
+ |----------|------|-------------|----------|
11
+ | Architecture | 3 | 0 | 0 |
12
+ | Code Quality | 4 | 0 | 0 |
13
+ | Testing | 2 | 0 | 0 |
14
+ | Documentation | 2 | 0 | 0 |
15
+ | Performance | 2 | 0 | 0 |
16
+ | Dependencies | 1 | 0 | 0 |
17
+ | **Total** | **14** | **0** | **0** |
18
+
19
+ ---
20
+
21
+ ## Architecture
22
+
23
+ ### DEBT-001: Duplicate Agent Guide Files
24
+
25
+ **Category:** Architecture
26
+ **Severity:** Low
27
+ **Added:** 2025-12-06
28
+ **Status:** Open
29
+
30
+ **Description:**
31
+ CLAUDE.md, AGENTS.md, and GEMINI.md contain ~95% identical content. This violates DRY (Don't Repeat Yourself) and makes maintenance difficult.
32
+
33
+ **Impact:**
34
+ - Changes must be made in 3 places
35
+ - Risk of documentation drift
36
+ - Confusion about which file is canonical
37
+
38
+ **Current Workaround:**
39
+ Manual synchronization when updating.
40
+
41
+ **Proposed Solution:**
42
+ 1. Keep CLAUDE.md as the canonical reference
43
+ 2. Make AGENTS.md and GEMINI.md symlinks or include-references
44
+ 3. Or consolidate into single DEVELOPMENT.md
45
+
46
+ **Effort Estimate:** S
47
+
48
+ ---
49
+
50
+ ### DEBT-002: Reserved but Empty Directories
51
+
52
+ **Category:** Architecture
53
+ **Severity:** Low
54
+ **Added:** 2025-12-06
55
+ **Status:** Open
56
+
57
+ **Description:**
58
+ `src/database_services/` and `src/retrieval_factory/` exist but are empty placeholders for future features.
59
+
60
+ **Impact:**
61
+ - Confusion about project structure
62
+ - Empty imports may cause issues
63
+
64
+ **Current Workaround:**
65
+ Document as "reserved" in component inventory.
66
+
67
+ **Proposed Solution:**
68
+ Either implement the features or remove the directories.
69
+
70
+ **Effort Estimate:** S
71
+
72
+ ---
73
+
74
+ ### DEBT-003: Experimental LangGraph Orchestrator
75
+
76
+ **Category:** Architecture
77
+ **Severity:** Medium
78
+ **Added:** 2025-12-06
79
+ **Status:** Open
80
+
81
+ **Description:**
82
+ `src/orchestrators/langgraph_orchestrator.py` is marked as experimental and may not be fully tested or integrated.
83
+
84
+ **Impact:**
85
+ - Unclear which orchestrator is preferred
86
+ - May have untested edge cases
87
+ - Maintenance burden of two orchestrators
88
+
89
+ **Current Workaround:**
90
+ Default to AdvancedOrchestrator in production.
91
+
92
+ **Proposed Solution:**
93
+ Either promote to production status with full testing, or deprecate and remove.
94
+
95
+ **Effort Estimate:** M
96
+
97
+ ---
98
+
99
+ ## Code Quality
100
+
101
+ ### DEBT-004: Complex Orchestrator Logic
102
+
103
+ **Category:** Code Quality
104
+ **Severity:** Medium
105
+ **Added:** 2025-12-06
106
+ **Status:** Open
107
+
108
+ **Description:**
109
+ `src/orchestrators/advanced.py` has complex branching logic that required disabling pylint rules (PLR0912, PLR0913).
110
+
111
+ **Impact:**
112
+ - Difficult to understand and maintain
113
+ - Higher bug risk
114
+ - Harder to test comprehensively
115
+
116
+ **Current Workaround:**
117
+ Suppressed linter warnings with explicit ignores.
118
+
119
+ **Proposed Solution:**
120
+ Refactor into smaller, focused methods. Consider command pattern for orchestration steps.
121
+
122
+ **Effort Estimate:** L
123
+
124
+ ---
125
+
126
+ ### DEBT-005: Magic Numbers in Code
127
+
128
+ **Category:** Code Quality
129
+ **Severity:** Low
130
+ **Added:** 2025-12-06
131
+ **Status:** Open
132
+
133
+ **Description:**
134
+ Some statistical constants and thresholds are hardcoded (e.g., p-values, score thresholds), requiring PLR2004 ignore.
135
+
136
+ **Impact:**
137
+ - Difficult to tune parameters
138
+ - Magic numbers obscure intent
139
+
140
+ **Current Workaround:**
141
+ Documented with comments where used.
142
+
143
+ **Proposed Solution:**
144
+ Move to configuration or constants module with documentation.
145
+
146
+ **Effort Estimate:** S
147
+
148
+ ---
149
+
150
+ ### DEBT-006: Global Singleton Pattern
151
+
152
+ **Category:** Code Quality
153
+ **Severity:** Low
154
+ **Added:** 2025-12-06
155
+ **Status:** Open
156
+
157
+ **Description:**
158
+ Settings uses a singleton pattern (`settings = get_settings()`), requiring PLW0603 ignore.
159
+
160
+ **Impact:**
161
+ - Harder to test with different configurations
162
+ - Global state can cause issues
163
+
164
+ **Current Workaround:**
165
+ Test fixtures override settings.
166
+
167
+ **Proposed Solution:**
168
+ Consider dependency injection for settings, especially in tests.
169
+
170
+ **Effort Estimate:** M
171
+
172
+ ---
173
+
174
+ ### DEBT-007: ClinicalTrials Uses requests Instead of httpx
175
+
176
+ **Category:** Code Quality
177
+ **Severity:** Low
178
+ **Added:** 2025-12-06
179
+ **Status:** Open
180
+
181
+ **Description:**
182
+ `src/tools/clinicaltrials.py` uses `requests` library while rest of codebase uses `httpx` because ClinicalTrials.gov WAF blocks httpx.
183
+
184
+ **Impact:**
185
+ - Inconsistent HTTP client usage
186
+ - Two libraries for same purpose
187
+
188
+ **Current Workaround:**
189
+ Documented in code comments and pyproject.toml.
190
+
191
+ **Proposed Solution:**
192
+ 1. Investigate httpx headers/options that work with WAF
193
+ 2. Or accept this as necessary divergence and document
194
+
195
+ **Effort Estimate:** M
196
+
197
+ ---
198
+
199
+ ## Testing
200
+
201
+ ### DEBT-008: Integration Tests Require Real APIs
202
+
203
+ **Category:** Testing
204
+ **Severity:** Medium
205
+ **Added:** 2025-12-06
206
+ **Status:** Open
207
+
208
+ **Description:**
209
+ Integration tests marked with `@pytest.mark.integration` make real API calls, which can be slow and flaky.
210
+
211
+ **Impact:**
212
+ - Slow CI runs
213
+ - Flaky tests due to network issues
214
+ - Rate limit risks
215
+
216
+ **Current Workaround:**
217
+ Integration tests are not run in CI by default.
218
+
219
+ **Proposed Solution:**
220
+ 1. Use VCR-style recording for reproducible tests
221
+ 2. Set up isolated test environment
222
+ 3. Better mock infrastructure for external APIs
223
+
224
+ **Effort Estimate:** L
225
+
226
+ ---
227
+
228
+ ### DEBT-009: Incomplete E2E Test Coverage
229
+
230
+ **Category:** Testing
231
+ **Severity:** Medium
232
+ **Added:** 2025-12-06
233
+ **Status:** Open
234
+
235
+ **Description:**
236
+ End-to-end tests exist but don't cover all user scenarios, especially error paths.
237
+
238
+ **Impact:**
239
+ - Production bugs may not be caught in testing
240
+ - Edge cases untested
241
+
242
+ **Current Workaround:**
243
+ Manual testing before releases.
244
+
245
+ **Proposed Solution:**
246
+ Expand E2E test suite with more scenarios, especially:
247
+ - Error handling
248
+ - Rate limit recovery
249
+ - Multiple iterations
250
+
251
+ **Effort Estimate:** L
252
+
253
+ ---
254
+
255
+ ## Documentation
256
+
257
+ ### DEBT-010: Outdated Inline Comments
258
+
259
+ **Category:** Documentation
260
+ **Severity:** Low
261
+ **Added:** 2025-12-06
262
+ **Status:** Open
263
+
264
+ **Description:**
265
+ Some code comments may reference old architecture or removed features from rapid hackathon development.
266
+
267
+ **Impact:**
268
+ - Confusion when reading code
269
+ - Comments don't match implementation
270
+
271
+ **Current Workaround:**
272
+ None - requires manual review.
273
+
274
+ **Proposed Solution:**
275
+ Systematic review of comments during code review process.
276
+
277
+ **Effort Estimate:** M
278
+
279
+ ---
280
+
281
+ ### DEBT-011: Missing API Documentation
282
+
283
+ **Category:** Documentation
284
+ **Severity:** Low
285
+ **Added:** 2025-12-06
286
+ **Status:** Open
287
+
288
+ **Description:**
289
+ No formal API documentation (e.g., Sphinx-generated) for public interfaces.
290
+
291
+ **Impact:**
292
+ - Developers must read source code
293
+ - Hard to know public vs internal APIs
294
+
295
+ **Current Workaround:**
296
+ Docstrings in code serve as documentation.
297
+
298
+ **Proposed Solution:**
299
+ Consider generating API docs with Sphinx or mkdocs.
300
+
301
+ **Effort Estimate:** M
302
+
303
+ ---
304
+
305
+ ## Performance
306
+
307
+ ### DEBT-012: Model Loading on First Request
308
+
309
+ **Category:** Performance
310
+ **Severity:** Low
311
+ **Added:** 2025-12-06
312
+ **Status:** Open
313
+
314
+ **Description:**
315
+ Sentence-transformers model is loaded on first query, causing slow initial response.
316
+
317
+ **Impact:**
318
+ - First query takes 30+ seconds
319
+ - Poor user experience on first use
320
+
321
+ **Current Workaround:**
322
+ Docker pre-downloads the model during build.
323
+
324
+ **Proposed Solution:**
325
+ 1. Pre-warm model on application startup
326
+ 2. Or accept cold start with loading indicator
327
+
328
+ **Effort Estimate:** S
329
+
330
+ ---
331
+
332
+ ### DEBT-013: No Connection Pooling
333
+
334
+ **Category:** Performance
335
+ **Severity:** Low
336
+ **Added:** 2025-12-06
337
+ **Status:** Open
338
+
339
+ **Description:**
340
+ External API calls may not fully utilize connection pooling.
341
+
342
+ **Impact:**
343
+ - Slower requests due to connection overhead
344
+ - Higher latency under load
345
+
346
+ **Current Workaround:**
347
+ httpx AsyncClient provides some pooling.
348
+
349
+ **Proposed Solution:**
350
+ Audit and optimize connection handling for external APIs.
351
+
352
+ **Effort Estimate:** S
353
+
354
+ ---
355
+
356
+ ## Dependencies
357
+
358
+ ### DEBT-014: Pinned Beta Dependencies
359
+
360
+ **Category:** Dependencies
361
+ **Severity:** Medium
362
+ **Added:** 2025-12-06
363
+ **Status:** Open
364
+
365
+ **Description:**
366
+ `agent-framework-core==1.0.0b*` is a beta release, pinned to avoid breaking changes.
367
+
368
+ **Impact:**
369
+ - May miss bug fixes and improvements
370
+ - Beta software may have stability issues
371
+
372
+ **Current Workaround:**
373
+ Version pinning with explicit documentation.
374
+
375
+ **Proposed Solution:**
376
+ 1. Monitor for stable release
377
+ 2. Upgrade and test when 1.0.0 releases
378
+ 3. Add integration tests specific to agent framework
379
+
380
+ **Effort Estimate:** M
381
+
382
+ ---
383
+
384
+ ## Resolved Items
385
+
386
+ *No items resolved yet.*
387
+
388
+ ---
389
+
390
+ ## How to Update This Registry
391
+
392
+ ### Adding Items
393
+
394
+ 1. Create new section with next DEBT-XXX number
395
+ 2. Fill in all fields
396
+ 3. Update summary dashboard
397
+
398
+ ### Resolving Items
399
+
400
+ 1. Change status to "Resolved"
401
+ 2. Add resolution notes
402
+ 3. Move to "Resolved Items" section
403
+ 4. Update summary dashboard
404
+
405
+ ### Review Schedule
406
+
407
+ - Weekly: Triage new items
408
+ - Sprint: Plan debt reduction
409
+ - Monthly: Review progress
docs/technical-debt/index.md ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Technical Debt Overview
2
+
3
+ > **Last Updated**: 2025-12-06
4
+
5
+ This directory tracks technical debt, known issues, and areas for improvement in the DeepBoner codebase.
6
+
7
+ ## What is Technical Debt?
8
+
9
+ Technical debt is the implied cost of future work caused by choosing an easy (but limited) solution now instead of a better approach that would take longer. Like financial debt, it accumulates interest over time.
10
+
11
+ ## Documentation Structure
12
+
13
+ ```
14
+ technical-debt/
15
+ β”œβ”€β”€ index.md # This file - overview and summary
16
+ └── debt-registry.md # Itemized debt tracking
17
+ ```
18
+
19
+ ## Current Debt Summary
20
+
21
+ | Category | Count | Severity |
22
+ |----------|-------|----------|
23
+ | Architecture | 3 | Medium |
24
+ | Code Quality | 4 | Low |
25
+ | Testing | 2 | Medium |
26
+ | Documentation | 2 | Low |
27
+ | Performance | 2 | Low |
28
+ | Dependencies | 1 | Medium |
29
+
30
+ **Total Items:** 14
31
+
32
+ ## Severity Levels
33
+
34
+ | Level | Description | Action |
35
+ |-------|-------------|--------|
36
+ | **Critical** | Blocks production or security risk | Fix immediately |
37
+ | **High** | Significant impact on reliability | Fix this sprint |
38
+ | **Medium** | Impacts developer experience | Plan for fix |
39
+ | **Low** | Nice to have improvement | Backlog |
40
+
41
+ ## How to Use This Documentation
42
+
43
+ ### For Developers
44
+
45
+ 1. Before starting work, check if your area has known debt
46
+ 2. When you encounter issues, document them here
47
+ 3. When fixing debt, update the registry
48
+
49
+ ### For Planning
50
+
51
+ 1. Review debt before sprint planning
52
+ 2. Allocate capacity for debt reduction
53
+ 3. Prioritize by severity and effort
54
+
55
+ ### For New Contributors
56
+
57
+ 1. Read this to understand known limitations
58
+ 2. Don't be surprised by documented issues
59
+ 3. Consider fixing debt as a contribution
60
+
61
+ ## Adding New Debt Items
62
+
63
+ Add to `debt-registry.md` using this format:
64
+
65
+ ```markdown
66
+ ### DEBT-XXX: Short Title
67
+
68
+ **Category:** Architecture | Code Quality | Testing | Documentation | Performance | Dependencies
69
+ **Severity:** Critical | High | Medium | Low
70
+ **Added:** YYYY-MM-DD
71
+ **Status:** Open | In Progress | Resolved
72
+
73
+ **Description:**
74
+ What is the issue?
75
+
76
+ **Impact:**
77
+ How does this affect the codebase/users?
78
+
79
+ **Current Workaround:**
80
+ How are we handling this now?
81
+
82
+ **Proposed Solution:**
83
+ How should we fix this?
84
+
85
+ **Effort Estimate:** S | M | L | XL
86
+ ```
87
+
88
+ ## Debt Reduction Goals
89
+
90
+ ### Phase 1 (Current)
91
+ - Document all known debt (this effort)
92
+ - Prioritize by impact
93
+
94
+ ### Phase 2 (Near-term)
95
+ - Address all High severity items
96
+ - Reduce Medium items by 50%
97
+
98
+ ### Phase 3 (Long-term)
99
+ - Clear all Medium and High items
100
+ - Establish debt budget (no net increase)
101
+
102
+ ## Related Documentation
103
+
104
+ - [Debt Registry](debt-registry.md) - Complete itemized list
105
+ - [Bugs](../bugs/active-bugs.md) - Active bug tracking
106
+ - [Contributing](../../CONTRIBUTING.md) - How to help