# julio-balladares/deepresearch architecture

> Architecture diagram of the GitHub repository julio-balladares/deepresearch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-04). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/julio-balladares/deepresearch
- Repository: https://github.com/julio-balladares/deepresearch

## Overview

#### Purpose and Public Entry Points
DeepResearch is a Python library for AI-assisted OSINT: it turns a topic into a research plan, web searches, collected evidence, iterative gap analysis, and a structured Pydantic result. Primary embedding APIs are `run_deep_research` and dictionary routing, exported through `deepresearch/__init__.py`; orchestration is implemented in `deepresearch/pipeline.py` and API adaptation in `deepresearch/router.py`.

#### Request, Result, and Configuration Boundary
Typed request, plan, source, round, and final-result contracts form the internal data boundary in `deepresearch/models.py`. Runtime limits, provider selection, credentials, cache settings, and endpoint overrides are loaded from environment-backed configuration in `deepresearch/config.py`. This makes caller-supplied request settings and environment policy distinct from pipeline execution.

#### Research Orchestration
`deepresearch/pipeline.py` is the central control flow. It coordinates target interpretation, planning, query generation, search/read collection, source limits/deduplication, multi-round iteration, gap evaluation, and final result assembly. `deepresearch/service.py` provides the service-facing façade around this pipeline, separating application integration from lower-level stages.

#### LLM Planning and Provider Abstraction
Planning and synthesis-like AI tasks are divided between `deepresearch/planner.py` and `deepresearch/gaps.py`: the former derives target profiles, subquestions, and query plans; the latter determines unresolved research gaps to drive later rounds. `deepresearch/llm.py` abstracts calls to configured providers—including OpenAI, Anthropic, Gemini, Mistral, DeepSeek, xAI, OpenRouter, Perplexity, and Ollama—behind a common interface. Provider API keys and optional base URLs remain infrastructure concerns rather than pipeline logic.

#### Evidence Acquisition
`deepresearch/search.py` is the external search boundary, using SerpApi and a caller-selected Google, Bing, Yahoo, DuckDuckGo, or Yandex engine to turn planned queries into candidate web sources. `deepresearch/reader.py` is the page-content boundary: it fetches and constrains source text when page reading is enabled. The pipeline retains structured source metadata such as URL, domain, search snippet, associated query/subquestion, and fetch status.

#### Caching and Iterative Controls
`deepresearch/cache.py` provides local persistence for LLM responses, search results, and page reads, reducing repeated provider and network calls. Cache location and enablement are controlled via configuration. Iteration is explicitly bounded by settings such as rounds, queries, sources per query, total sources, per-source characters, final context size, and LLM timeout, primarily applied across `deepresearch/pipeline.py`, `deepresearch/search.py`, and `deepresearch/reader.py`.

#### Runtime and External Dependencies
The package runs as a Python library installed through `pyproject.toml`, with no indicated standalone server or web UI. Required external services are SerpApi plus one selected LLM provider; Ollama supports a local-model route. Utility cross-cutting behavior resides in `deepresearch/utils.py`, while tests currently focus on LLM behavior in `tests/test_llm.py`.

Main entry points: [`deepresearch/pipeline.py`](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/pipeline.py) (Research orchestrator), [`deepresearch/llm.py`](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/llm.py) (LLM provider interface), [`deepresearch/cache.py`](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/cache.py) (Local cache), [`deepresearch/__init__.py`](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/__init__.py) (Package exports)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_public["Public API"]
  node_package["Package exports<br/>Python package<br/>[__init__.py]"]
  node_router["Dictionary router<br/>API adapter<br/>[router.py]"]
  node_service["Service façade<br/>integration façade<br/>[service.py]"]
  node_packaging["Python package install<br/>package metadata<br/>[pyproject.toml]"]
end

subgraph group_core["Research Pipeline"]
  node_models["Research contracts<br/>Pydantic models<br/>[models.py]"]
  node_config["Runtime configuration<br/>environment settings<br/>[config.py]"]
  node_pipeline{{"Research orchestrator<br/>multi-round workflow<br/>[pipeline.py]"}}
  node_planner["Plan generator<br/>LLM planning<br/>[planner.py]"]
  node_gaps["Gap evaluator<br/>LLM evaluation<br/>[gaps.py]"]
end

subgraph group_adapters["AI &amp; Evidence Adapters"]
  node_search["Web search<br/>search adapter<br/>[search.py]"]
  node_reader["Page reader<br/>content fetcher<br/>[reader.py]"]
  node_llm["LLM provider interface<br/>provider abstraction<br/>[llm.py]"]
  node_cache[("Local cache<br/>persistent cache<br/>[cache.py]")]
end

subgraph group_external["External Services"]
  node_serpapi(("SerpApi<br/>search service"))
  node_llm_providers(("Configured LLM provider<br/>AI service or Ollama"))
end

node_packaging -->|"installs"| node_package
node_package -->|"exports routing"| node_router
node_package -->|"exports run API"| node_pipeline
node_router -->|"adapts dictionaries"| node_service
node_service -->|"invokes"| node_pipeline
node_pipeline -->|"reads and returns contracts"| node_models
node_pipeline -->|"applies limits and policy"| node_config
node_pipeline -->|"creates plan"| node_planner
node_pipeline -->|"executes queries"| node_search
node_pipeline -->|"reads selected sources"| node_reader
node_pipeline -->|"evaluates evidence gaps"| node_gaps
node_planner -->|"uses"| node_llm
node_gaps -->|"uses"| node_llm
node_llm -->|"provider calls"| node_llm_providers
node_search -->|"search requests"| node_serpapi
node_pipeline -->|"reuses responses"| node_cache
node_search -.->|"caches results"| node_cache
node_reader -.->|"caches reads"| node_cache
node_llm -.->|"caches responses"| node_cache
node_gaps -->|"drives next round"| node_pipeline

click node_package "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/__init__.py"
click node_router "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/router.py"
click node_service "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/service.py"
click node_models "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/models.py"
click node_config "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/config.py"
click node_pipeline "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/pipeline.py"
click node_planner "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/planner.py"
click node_gaps "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/gaps.py"
click node_search "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/search.py"
click node_reader "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/reader.py"
click node_llm "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/llm.py"
click node_cache "https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/cache.py"
click node_packaging "https://github.com/julio-balladares/deepresearch/blob/main/pyproject.toml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_package,node_router,node_service,node_packaging toneBlue
class node_models,node_config,node_pipeline,node_planner,node_gaps toneAmber
class node_search,node_reader,node_llm,node_cache toneMint
class node_serpapi,node_llm_providers toneRose
```

## Components

### Public API

- [Package exports](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/__init__.py): Python package · Exports embedding APIs. · `deepresearch/__init__.py`
- [Dictionary router](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/router.py): API adapter · `deepresearch/router.py`
- [Service façade](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/service.py): integration façade · `deepresearch/service.py`
- [Python package install](https://github.com/julio-balladares/deepresearch/blob/main/pyproject.toml): package metadata · `pyproject.toml`

### Research Pipeline

- [Research contracts](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/models.py): Pydantic models · Typed request, plan, evidence, round, and result boundary. · `deepresearch/models.py`
- [Runtime configuration](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/config.py): environment settings · `deepresearch/config.py`
- [Research orchestrator](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/pipeline.py): multi-round workflow · Coordinates planning, collection, gap-driven iteration, and result assembly. · `deepresearch/pipeline.py`
- [Plan generator](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/planner.py): LLM planning · Builds target profiles, subquestions, and queries. · `deepresearch/planner.py`
- [Gap evaluator](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/gaps.py): LLM evaluation · Identifies unresolved questions for later rounds. · `deepresearch/gaps.py`

### AI & Evidence Adapters

- [Web search](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/search.py): search adapter · `deepresearch/search.py`
- [Page reader](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/reader.py): content fetcher · Fetches and constrains page text when enabled. · `deepresearch/reader.py`
- [LLM provider interface](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/llm.py): provider abstraction · `deepresearch/llm.py`
- [Local cache](https://github.com/julio-balladares/deepresearch/blob/main/deepresearch/cache.py): persistent cache · Caches LLM, search, and page-read responses. · `deepresearch/cache.py`

### External Services

- **SerpApi**: search service · Accesses the selected web search engine.
- **Configured LLM provider**: AI service or Ollama · Cloud providers or local Ollama supply model responses.

## Connections

- Python package install → Package exports: installs
- Package exports → Dictionary router: exports routing
- Package exports → Research orchestrator: exports run API
- Dictionary router → Service façade: adapts dictionaries
- Service façade → Research orchestrator: invokes
- Research orchestrator → Research contracts: reads and returns contracts
- Research orchestrator → Runtime configuration: applies limits and policy
- Research orchestrator → Plan generator: creates plan
- Research orchestrator → Web search: executes queries
- Research orchestrator → Page reader: reads selected sources
- Research orchestrator → Gap evaluator: evaluates evidence gaps
- Plan generator → LLM provider interface: uses
- Gap evaluator → LLM provider interface: uses
- LLM provider interface → Configured LLM provider: provider calls
- Web search → SerpApi: search requests
- Research orchestrator → Local cache: reuses responses
- Web search → Local cache: caches results
- Page reader → Local cache: caches reads
- LLM provider interface → Local cache: caches responses
- Gap evaluator → Research orchestrator: drives next round
