Spaces:
Running
Tools Architecture
DeepCritical implements a protocol-based search tool system for retrieving evidence from multiple sources.
SearchTool Protocol
All tools implement the SearchTool protocol from src/tools/base.py:
class SearchTool(Protocol):
@property
def name(self) -> str: ...
async def search(
self,
query: str,
max_results: int = 10
) -> list[Evidence]: ...
Rate Limiting
All tools use the @retry decorator from tenacity:
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(...)
)
async def search(self, query: str, max_results: int = 10) -> list[Evidence]:
# Implementation
Tools with API rate limits implement _rate_limit() method and use shared rate limiters from src/tools/rate_limiter.py.
Error Handling
Tools raise custom exceptions:
SearchError: General search failuresRateLimitError: Rate limit exceeded
Tools handle HTTP errors (429, 500, timeout) and return empty lists on non-critical errors (with warning logs).
Query Preprocessing
Tools use preprocess_query() from src/tools/query_utils.py to:
- Remove noise from queries
- Expand synonyms
- Normalize query format
Evidence Conversion
All tools convert API responses to Evidence objects with:
Citation: Title, URL, date, authorscontent: Evidence textrelevance_score: 0.0-1.0 relevance scoremetadata: Additional metadata
Missing fields are handled gracefully with defaults.
Tool Implementations
PubMed Tool
File: src/tools/pubmed.py
API: NCBI E-utilities (ESearch → EFetch)
Rate Limiting:
- 0.34s between requests (3 req/sec without API key)
- 0.1s between requests (10 req/sec with NCBI API key)
Features:
- XML parsing with
xmltodict - Handles single vs. multiple articles
- Query preprocessing
- Evidence conversion with metadata extraction
ClinicalTrials Tool
File: src/tools/clinicaltrials.py
API: ClinicalTrials.gov API v2
Important: Uses requests library (NOT httpx) because WAF blocks httpx TLS fingerprint.
Execution: Runs in thread pool: await asyncio.to_thread(requests.get, ...)
Filtering:
- Only interventional studies
- Status:
COMPLETED,ACTIVE_NOT_RECRUITING,RECRUITING,ENROLLING_BY_INVITATION
Features:
- Parses nested JSON structure
- Extracts trial metadata
- Evidence conversion
Europe PMC Tool
File: src/tools/europepmc.py
API: Europe PMC REST API
Features:
- Handles preprint markers:
[PREPRINT - Not peer-reviewed] - Builds URLs from DOI or PMID
- Checks
pubTypeListfor preprint detection - Includes both preprints and peer-reviewed articles
RAG Tool
File: src/tools/rag_tool.py
Purpose: Semantic search within collected evidence
Implementation: Wraps LlamaIndexRAGService
Features:
- Returns Evidence from RAG results
- Handles evidence ingestion
- Semantic similarity search
- Metadata preservation
Search Handler
File: src/tools/search_handler.py
Purpose: Orchestrates parallel searches across multiple tools
Features:
- Uses
asyncio.gather()withreturn_exceptions=True - Aggregates results into
SearchResult - Handles tool failures gracefully
- Deduplicates results by URL
Tool Registration
Tools are registered in the search handler:
from src.tools.pubmed import PubMedTool
from src.tools.clinicaltrials import ClinicalTrialsTool
from src.tools.europepmc import EuropePMCTool
search_handler = SearchHandler(
tools=[
PubMedTool(),
ClinicalTrialsTool(),
EuropePMCTool(),
]
)
See Also
- Services - RAG and embedding services
- API Reference - Tools - API documentation
- Contributing - Implementation Patterns - Development guidelines