Once the research pipeline has finished collecting and scoring sources,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/IconDean/research-agent/llms.txt
Use this file to discover all available pages before exploring further.
ReportGenerator takes over the final synthesis stage. It feeds all accumulated content from a ResearchContext into Gemini using a structured SYNTHESIS_PROMPT, producing a coherent, cited markdown report. The generator runs at temperature=0.3 to keep synthesis deterministic and factually grounded. This page also covers the generate_content_with_retry utility that handles model fallback and retry logic for all Gemini calls, along with the text utility functions used throughout the pipeline.
ReportGenerator
generate_report()
SYNTHESIS_PROMPT, supplies the full fetched source content and source metadata from context, and calls Gemini at temperature=0.3. It is called automatically by AgentRunner.research() at the end of the pipeline, but can also be invoked directly when you want to regenerate or customize the report after modifying the context.
The original research question. Included in the synthesis prompt so
Gemini focuses the report on answering it directly.
The fully-populated
ResearchContext from the completed research session.
The method reads context.sources_fetched, context.source_metadata,
context.established_facts, and context.gaps to assemble the synthesis
input.An initialized
google.generativeai client. Typically AgentRunner.client,
which is configured with the API key provided at construction time.The Gemini model name to use for synthesis, e.g.
"gemini-2.0-flash".
This value is maintained by AgentRunner and may have been updated by
model fallback during the search phases.str — A complete markdown report. The report typically includes an executive summary, thematic sections with inline citations, a discussion of knowledge gaps, and a numbered sources list.
Raises: RuntimeError if Gemini returns no candidates or if the response content is empty.
Synthesis runs at
temperature=0.3 to reduce hallucination risk and produce
stable, reproducible reports. If you call generate_report multiple times
on the same context, you can expect very similar (though not byte-identical)
output each time.Usage Example
AgentRunner.research():
generate_content_with_retry
AgentRunner and ReportGenerator. It handles per-model retries with exponential backoff and automatic fallback through the model hierarchy when a model is unavailable or rate-limited. Understanding this function is useful when diagnosing latency issues or building custom Gemini integrations with the same resilience guarantees.
Model Selection
model_candidates(), which checks the GEMINI_MODEL environment variable first. If set, that model is tried first, followed by the standard fallback list.
Retry Behavior
| Setting | Value |
|---|---|
| Max retries per model | 3 |
| Retryable HTTP status codes | 429, 500, 502, 503, 504 |
| Base delay | 2.0 seconds |
| Delay formula | BASE_DELAY_SEC × (2 ** attempt) → 2 s, 4 s, 8 s |
An initialized
google.generativeai client.The
contents argument forwarded to client.models.generate_content().
Accepts any value the Gemini Python SDK accepts (string, list of parts, etc.).The generation config forwarded to
client.models.generate_content(),
typically a genai.GenerateContentConfig instance.Optional progress callback. May fire informational events during model
switching.
If provided, this model is tried first before the standard candidate list,
allowing callers to resume from a model that worked in a previous call.
tuple[Any, str] — A (response, model_name_used) tuple, where response is the raw Gemini API response object and model_name_used is the model string that successfully responded.
Raises: The last caught exception if all models and retries are exhausted.
Text Utilities
Theutils module provides helper functions for text normalization used throughout the pipeline. Import them individually as needed.
clean_text()
\x00–\x08 and \x0b and similar, while preserving standard whitespace like spaces, tabs, and newlines.
The raw text to clean.
str — The cleaned string with normalized whitespace and no control characters.
truncate()
text to at most max_chars characters, cutting at a word boundary to avoid splitting mid-word. The cut point is the last space found after the 80% mark of max_chars. Appends "…" to indicate truncation.
The text to truncate.
Maximum character count. Defaults to
3000 (matching MAX_PAGE_CHARS
in tools.py). Pass a smaller value for tighter summaries.str — The (possibly truncated) string. If len(text) <= max_chars, the original string is returned unchanged.
format_citations()
A list of source dicts, each with at minimum a
title (str) and url
(str) key. Compatible with the output of ResearchContext.get_all_sources().str — A numbered markdown list where each line is N. [Title](url). Returns the string "_No sources collected._" if the input list is empty.