Clinical-genomics agent: ask natural-language questions over a local VCF and get literature-grounded answers.
Project description
aiva-agent
A standalone clinical-genomics agent. Ask natural-language questions about a local pre-annotated VCF, gather variant annotations, search literature, find clinical trials, prioritize genes from HPO phenotypes, and run ACMG/AMP variant classification — using any OpenAI-compatible provider (OpenAI, Anthropic, xAI Grok, Together, Fireworks, OpenRouter, etc.).
export LLM_MODEL=gpt-5.5
export LLM_BASE_URL=https://api.openai.com/v1
export LLM_API_KEY=sk-...
export AIVA_API_KEY=aiva_... #request by emailing tarun@mamidi.ai
aiva_agent --vcf data/test.vcf.gz \
--prompt "3yo female with developmental regression, hand stereotypies, and acquired microcephaly. Find candidate variants and propose the most likely diagnosis with supporting evidence."
Contents
What it does
The agent runs locally over a pre-annotated tabix-indexed VCF and orchestrates a curated set of tools to answer questions about variants, retrieve supporting literature, surface clinical trials, prioritize candidate genes from phenotype terms, and run ACMG/AMP variant classification. Tools are exposed under the following names and can be selectively turned off via --disable:
| Tool | What it does |
|---|---|
vcf |
Queries over your tabix-indexed .vcf.gz file. |
annotate |
Variant annotation. Supports human and plant species. |
literature |
PubMed / PMC search with gene / disease / variant / chemical entity annotations. |
trials |
Clinical-trials search by condition, intervention, gene/variant, phase, recruiting status; full-detail retrieval by NCT ID. |
rank_genes |
Rank candidate genes for a list of HPO phenotype terms. Can use negative terms to exclude genes. |
web |
Web search and clean content extraction from any URL. |
classify |
ACMG/AMP 2015 (germline) and AMP/ASCO/CAP 2017 (somatic) classification and returns a JSON classification. |
bash |
Run shell commands in your working directory. Lets the agent peek at any file the other tools don't cover (CSV, TSV, Excel, JSON, parquet, plain text), ask read-level questions about BAM/CRAM alignments for variant validation / phase / SV evidence (paths declared with --bam), and use whatever tools your environment has on PATH. Scope with --workdir or AIVA_WORKDIR; defaults to the current directory. |
manage_todos |
Plan and track multi-step work within a single run. The agent creates a todo list up front, marks items in progress as it starts each one, and completes them as it goes. State is per-run (not persisted across sessions). |
Prerequisites
- Python 3.12+ with
pip ≥ 24(forpip install). - htslib tools (
bgzip,tabix) only needed for preparing VCFs (brew install htslibon macOS). - Linux: glibc ≥ 2.28 (Ubuntu ≥ 20.04, RHEL/Rocky ≥ 8, Debian ≥ 10) for the
vcftool. Older hosts can use the container image — see Running on HPC. - Internet connectivity — For HPC/cloud/remote environments/jobs, ensure outbound HTTPS to your LLM provider and to the public APIs the agent queries (NCBI E-utilities, ClinicalTrials.gov, DuckDuckGo, etc.). Behind a corporate proxy, set
HTTPS_PROXY/HTTP_PROXY/NO_PROXY(Python clients honor these automatically); for MITM proxies, also setREQUESTS_CA_BUNDLEto your org's root cert. Only the localvcftool runs without network.
Quickstart
1. Install (pick one)
pip — fastest if you have Python 3.12+ on a modern Linux/macOS host:
pip install aiva-agent
Docker — works anywhere a container runs (Docker, Podman, Apptainer/Singularity). Useful when your host can't install Python or has older glibc (see Running on HPC):
docker pull mhspl/aiva-agent:latest
Python import — call from a notebook or script (see Notebook usage):
from aiva_agent import aiva_agent
2. Configure
Set three env vars for your model provider. Drop them in a .env file in your working directory and the agent loads them automatically:
LLM_MODEL=gpt-5.5
LLM_BASE_URL=https://api.openai.com/v1
LLM_API_KEY=sk-...
AIVA_API_KEY=aiva_... #request by emailing tarun@mamidi.ai
For one-off shells you can export the same variables instead. The agent works with any OpenAI-compatible endpoint. For the full list of env vars and CLI flags, see Full configuration.
An aivaportal API key is required. Set AIVA_API_KEY by emailing tarun@mamidi.ai. aiva-agent validates it every run; an unset, invalid, expired, or revoked key blocks both the CLI and the web UI.
Some tools need their own key. web_search needs WEB_API_KEY — a Firecrawl key (free tier ≈1,000 page fetches/month). Without it, the web tool auto-disables on startup with a stderr warning and the rest of the agent runs normally (the vcf tool behaves the same way when no --vcf/AIVA_VCF is set). See Full configuration for every optional key.
Security note: prefer .env or export LLM_API_KEY=... over --api-key sk-... so the secret doesn't leak into shell history or ps.
3. Run
Prepare a tabix-indexed VCF (only once per file):
bgzip -k path/to/sample.vcf
tabix -p vcf path/to/sample.vcf.gz
Tip: prefer a pre-annotated VCF. If you've already run your VCF through a variant-effect annotator (VEP, SnpEff, ANNOVAR, …), the agent can read those annotations directly from the file. Pre-annotation is recommended for variant prioritization and classification.
Then ask a question:
aiva_agent --vcf path/to/sample.vcf.gz \
--prompt "List pathogenic variants"
Same invocation with Docker (bind-mount the VCF directory):
docker run --rm --env-file .env -v "$PWD/data:/work" \
mhspl/aiva-agent:latest \
--vcf /work/sample.vcf.gz --prompt "List pathogenic variants"
The same image also serves the browser UI — see Web UI → With Docker.
Full configuration
You can drive everything via flags or env vars. Precedence: CLI flag > shell export > .env value.
| Variable | CLI flag | Purpose | Default |
|---|---|---|---|
LLM_MODEL |
--model |
Model ID for the provider (e.g. gpt-5.5, claude-opus-4-7). |
— |
LLM_BASE_URL |
--base-url |
Provider's OpenAI-compatible base URL. | — |
LLM_API_KEY |
--api-key |
Provider API key. | — |
AIVA_API_KEY |
— | Required. aiva API key (aiva_...). Validated every run; unset/invalid/expired/revoked blocks the CLI and web UI. |
— |
AIVA_VCF |
--vcf |
Default VCF path or alias=path,... spec. |
unset (vcf tool auto-disables) |
AIVA_BAM |
--bam |
Default BAM/CRAM path or alias=path,... spec. Read-level queries go through the bash tool, so keep bash enabled if you want to ask BAM questions. Requires a .bai/.csi/.crai index next to each file. |
unset |
AIVA_WORKDIR |
--workdir |
Working directory for the bash tool. | current directory at invocation |
AIVA_DISABLE |
--disable |
Comma-separated tools to disable. | unset (all tools on) |
AIVA_MAX_TURNS |
— | Max agent turns per run. | 25 |
AIVA_FORCE |
--force |
Overwrite -o destination without passing --force. Accepts 1/true/yes/on. |
unset |
AIVA_SESSION_ID |
--session-id |
Conversation session ID; persist history across runs in <workdir>/.aiva/sessions.db. |
new UUID per run |
AIVA_STREAM |
--stream |
Force streaming on (1/true/yes/on) or off (0/false/no/off). Also honored by the notebook/script entrypoint; default is off there since Jupyter has no TTY. |
auto (on if stdout is a TTY and --output is unset) |
AIVA_STREAM_TOOL_OUTPUT |
— | When streaming, also dump each tool's output to stderr (debug aid). Honored in notebook mode too whenever streaming is on. Accepts 1/true/yes/on. |
unset (off) |
AIVA_STREAM_TOOL_OUTPUT_MAX |
— | Cap on chars per tool output when the dump above is on. Honored in notebook mode too. 0 means unlimited. |
2000 |
WEB_API_KEY |
— | Key for the web_search tool (web search + URL/PDF scrape). See .env.example for sign-up details. Without the key, the web tool auto-disables on startup (warning to stderr) — same pattern as AIVA_VCF. |
unset (web tool auto-disables) |
AIVA_HOST |
--host |
Web UI only (aiva_agent_serve): interface to bind. Set to 0.0.0.0 to reach the server from outside its host/container. |
127.0.0.1 |
AIVA_PORT |
--port |
Web UI only (aiva_agent_serve): port to bind. |
8765 |
Copy-paste template to your .env file:
# aiva-agent uses any OpenAI-compatible LLM provider.
# Model ID exactly as the provider expects.
# Examples: gpt-5.5, claude-opus-4-7, grok-2, meta-llama/Llama-3.1-70B-Instruct
LLM_MODEL=gpt-5.5
# Provider base URL — examples:
# OpenAI: https://api.openai.com/v1
# Anthropic: https://api.anthropic.com/v1
# xAI Grok: https://api.x.ai/v1
# OpenRouter: https://openrouter.ai/api/v1
# Together: https://api.together.xyz/v1
# Fireworks: https://api.fireworks.ai/inference/v1
# DeepSeek: https://api.deepseek.com/v1
# Groq: https://api.groq.com/openai/v1
LLM_BASE_URL=https://api.openai.com/v1
# API key for the chosen provider. Keep the real .env OUT of source control.
LLM_API_KEY=your-provider-api-key
# Required: aiva-agent validates this before every run.
# Request by email to tarun@mamidi.ai
AIVA_API_KEY=aiva-api-key
# Optional: default VCF spec. Two forms:
# single: AIVA_VCF=data/sample.vcf.gz
# multi: AIVA_VCF=proband=p.vcf.gz,father=f.vcf.gz,mother=m.vcf.gz
# For trios/cohorts, prefer a joint-called multisample VCF (single path) when you have one.
# --vcf overrides this per-run; pass --disable vcf to skip the tool entirely.
# AIVA_VCF=data/sample.vcf.gz
# Optional: default BAM/CRAM spec. Same syntax as AIVA_VCF:
# single: AIVA_BAM=data/sample.bam
# multi: AIVA_BAM=tumor=t.bam,normal=n.bam
# Each BAM must have a `.bai`/`.csi`/`.crai` index next to it for region queries.
# Read-level queries go through the bash tool, so keep bash enabled if you
# want to ask BAM questions. --bam overrides this per-run.
# AIVA_BAM=data/sample.bam
# Optional: working directory for the bash tool. The agent's shell commands run
# inside this directory, so scope it to the folder containing the side files
# (CSVs, panels, notes) you want it to read. --workdir overrides per-run; pass
# --disable bash to drop the tool entirely.
# AIVA_WORKDIR=./data
# Optional: comma-separated tools to disable by default.
# Choices: vcf, annotate, literature, trials, rank_genes, web, classify, bash, manage_todos
# --disable on the CLI replaces (does not merge with) this value.
# AIVA_DISABLE=vcf #single-tool disable
# AIVA_DISABLE=web,annotate #multi-tool disable
# Optional: max agent turns per run. Default 25.
# AIVA_MAX_TURNS=40
# Required for the `web_search` tool (web search + URL/PDF scrape).
# Backed by Firecrawl — sign up at https://www.firecrawl.dev to get a key.
# Free tier covers 1,000 page fetches/month, no credit card required.
# Without this, the web tool auto-disables on startup (with a stderr
# warning) — like the vcf tool when AIVA_VCF is unset.
# Optional: always overwrite --output destination without --force. Useful in
# CI / scripted pipelines where re-runs are expected. Accepts 1/true/yes/on.
# AIVA_FORCE=1
# Optional: conversation session ID. Reuse the same value across `aiva` runs to
# continue a conversation; history is stored in <workdir>/.aiva/sessions.db (local
# sqlite database, no server) so each workdir gets its own session namespace. If
# unset, each run gets a fresh UUID and is effectively stateless.
# AIVA_SESSION_ID=my-case-2026-05
# Optional: stream the agent's response live as it runs tools and replies,
# instead of waiting for the full answer. Also toggled by the --stream CLI flag.
# Defaults on in a terminal, off when piping or using --output.
# Accepts 1/true/yes/on or 0/false/no/off.
# AIVA_STREAM=1
# Optional: when streaming, also dump each tool's output after the
# `[tool] done` marker. Off by default since outputs can be very large
# (multi-MB JSON). Accepts 1/true/yes/on. Useful for debugging tool behavior.
# AIVA_STREAM_TOOL_OUTPUT=1
# Optional: cap on chars per tool output when AIVA_STREAM_TOOL_OUTPUT is on.
# Default 2000. Set to 0 for unlimited (warning: may flood your terminal).
# AIVA_STREAM_TOOL_OUTPUT_MAX=2000
CLI-only flags (per-invocation, no env equivalent):
| Flag | Purpose |
|---|---|
--prompt TEXT / --prompt-file PATH |
The question to ask. One of these is required. --prompt - reads from stdin. |
-o OUTPUT |
Write the agent's final answer to a file instead of stdout. |
Examples
For an end-to-end walkthrough in a notebook, see the example analysis on Colab:
CLI one-liners:
# All tools are on by default — pass --disable vcf for prompts that don't need
# a local VCF, or set AIVA_DISABLE / AIVA_VCF in .env to make it permanent.
# Variant annotation
aiva_agent --disable vcf --model gpt-5.5 \
--prompt "Annotate rs113488022. Report ClinVar significance and population AF."
# Literature search
aiva_agent --disable vcf --model gpt-5.5 \
--prompt "Find 3 recent papers on TP53 R175H in lung cancer."
# Clinical trials
aiva_agent --disable vcf --model gpt-5.5 \
--prompt "Find phase 2 recruiting BRAF V600E melanoma trials."
# HPO -> genes
aiva_agent --disable vcf --model gpt-5.5 \
--prompt "Rank candidate genes for HP:0001250 + HP:0001263."
# Web search + scrape (requires WEB_API_KEY; handles PDFs)
aiva_agent --disable vcf --model gpt-5.5 \
--prompt "Find and scrape the latest NCCN melanoma guideline summary."
# ACMG/AMP classification — `classify` subcommand prints JSON (rs113488022 = BRAF V600E)
aiva_agent classify --type amp --assembly GRCh38 \
--rsid rs113488022 --phenotype melanoma
# VCF query + literature (vcf tool turns on automatically once a path is provided)
aiva_agent --vcf data/test.vcf.gz --model gpt-5.5 \
--prompt "Find any TP53 variants and pull supporting literature."
Web UI
A local browser chat for the same agent — useful when you want to drag-and-drop VCFs, browse multiple chats side-by-side, and read structured tabular results inline instead of as TSV in a terminal. Everything still runs on your machine; no data leaves the host.
Install
The web UI ships behind an optional extra so the terminal CLI stays lean. Add it on top of the base install:
pip install 'aiva-agent[web]'
Run
Point the server at the directory that holds your VCFs / BAMs:
aiva_agent_serve --workdir ./data
Open http://127.0.0.1:8765 in a browser. Then + New chat → pick one or more VCF (and optional BAM) files from --workdir, give it a name, and ask questions.
Make sure to set AIVA_WORKDIR environment variable to the directory that holds your VCFs / BAMs.
With Docker. The published image ships the [web] extra, so the server is available by overriding the entrypoint. Bind 0.0.0.0 so the container is reachable from the host, publish the port, and let your .env supply the model credentials:
docker run --rm --env-file .env -p 8765:8765 -v "$PWD/data:/work" \
-e AIVA_HOST=0.0.0.0 \
--entrypoint aiva_agent_serve \
mhspl/aiva-agent:latest --workdir /work
Then open http://127.0.0.1:8765. The default entrypoint stays the CLI, so the same image runs either mode — see Quickstart → Run for the CLI form.
What's different from the CLI
- Per-workdir history. Conversation history lives at
<workdir>/.aiva/sessions.db(instead of~/.aiva/sessions.db), so switching workdirs gives you a clean session namespace and you can keep one history per dataset. - Multi-session. Each chat is its own session with its own VCF/BAM bindings — useful for keeping cases separate.
Notebook usage
Set env vars in one cell, call aiva_agent(...) in the next; calls within the same kernel automatically share a session, so follow-up questions remember the prior turn.
# cell 1
import os
os.environ["LLM_API_KEY"] = "sk-..."
os.environ["LLM_BASE_URL"] = "https://api.openai.com/v1"
os.environ["LLM_MODEL"] = "gpt-5.5"
os.environ["AIVA_VCF"] = "data/sample.vcf.gz"
# cell 2
from aiva_agent import aiva_agent
print(aiva_agent("List 3 likely-pathogenic variants from vcf."))
print(aiva_agent("Of those, which is in a recessive disease gene?")) # remembers
To start a fresh conversation mid-notebook, call reset_session(). To pin a specific ID (e.g. resume across kernel restarts), set AIVA_SESSION_ID in env or pass session_id="my-case" to aiva_agent. Per-call kwargs vcf=, disable=, model=, base_url=, api_key= override the corresponding env vars.
Classify a single variant (for embedding / integrations)
To run just ACMG/AMP classification on one variant — without the conversational agent — call classify(...). It returns the classification as a dict, so other tools can consume it directly.
import asyncio
from aiva_agent import classify
result = asyncio.run(classify(
{"hgvs": "NM_004333.6:c.1799T>A"}, # or {"rsid": ...} or {"chrom","pos","ref","alt"}
classification_type="acmg", # "acmg" (germline) or "amp" (somatic)
assembly="GRCh38", # "GRCh37" or "GRCh38"
phenotype_terms="melanoma", # optional: disease / HPO context
description="42yo, family history of breast cancer", # optional: sample/patient context
additional_context="de novo, confirmed by trio sequencing; heterozygous", # optional
model="gpt-5.5", # optional, falls back to LLM_MODEL
base_url="https://api.openai.com/v1", # optional, falls back to LLM_BASE_URL
api_key="sk-...", # optional, falls back to LLM_API_KEY
))
print(result["classification"], result.get("criteria_met"))
| Parameter | Required | Description |
|---|---|---|
variant |
yes | The variant as {"hgvs": ...}, {"rsid": ...}, or {"chrom","pos","ref","alt"}. |
classification_type |
yes | "acmg" (germline, ACMG/AMP 2015) or "amp" (somatic, AMP/ASCO/CAP 2017). |
assembly |
yes | "GRCh37" or "GRCh38". |
phenotype_terms |
no | Disease / phenotype context, e.g. "melanoma", "hereditary breast cancer". |
description |
no | Free-text sample/patient context. |
additional_context |
no | Verified clinical context (de novo status, zygosity, segregation, family history). Criteria are applied strictly to what's stated here. |
model / base_url / api_key |
no | Override the LLM_MODEL / LLM_BASE_URL / LLM_API_KEY env vars. |
workdir |
no | Scopes the classifier's bash tool (defaults to the current working directory). The classifier gets the same tool palette here as inside the agent — including shell access for evidence gathering — so pass a path to sandbox it. |
The result is schema-validated via the Agents SDK's structured output (output_type), so it's always a well-formed dict: for acmg it contains classification, confidence, acmg_score, criteria_met, evidence_summary (an entry per ACMG criterion), classification_rationale, and sources; for amp it contains classification, confidence, criteria_met, evidence_summary, therapeutic_summary, diagnostic_summary, prognostic_summary, and sources. (Structured output requires a provider that supports OpenAI json_schema response format.)
The same is available from the command line via the classify subcommand, which prints the JSON result to stdout:
aiva_agent classify --type acmg --assembly GRCh38 \
--hgvs "NM_004333.6:c.1799T>A" --phenotype melanoma
Specify the variant with --hgvs, --rsid, or all of --chrom/--pos/--ref/--alt. Optional flags mirror the Python kwargs: --description, --context (verified clinical context; maps to additional_context), --workdir (scopes the classifier's bash tool), and --model/--base-url/--api-key (fall back to the LLM_* env vars).
Running on HPC / older glibc
If your host has glibc < 2.28 (typical on CentOS/RHEL 7-era HPC nodes), a native library used by the vcf tool won't load and the tool will refuse to start with a hint to use the container image instead. The image (mhspl/aiva-agent:latest) ships with the right binaries pre-baked. Apptainer/Singularity can pull it directly:
apptainer pull aiva-agent.sif docker://mhspl/aiva-agent:latest
apptainer exec --bind "$PWD:/work" aiva-agent.sif \
aiva_agent --vcf /work/sample.vcf.gz --prompt "..."
Submit the job on a node that satisfies the Outbound HTTPS prerequisite — the container doesn't change network requirements.
License
aiva-agent is licensed under the PolyForm Noncommercial License 1.0.0.
- Free for noncommercial use — personal use, academic research, education, and use by charitable, public-research, public-health, and government institutions.
- Commercial use requires a separate license. Contact tarun@mamidi.ai for commercial licensing terms.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiva_agent-0.3.19.tar.gz.
File metadata
- Download URL: aiva_agent-0.3.19.tar.gz
- Upload date:
- Size: 205.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4f8980ddb8972cbb9c626e42a054fa44f48e0850fa5f2890ee5405c278e9c84
|
|
| MD5 |
a68947a38ff77b4feb7bc536547e9e77
|
|
| BLAKE2b-256 |
9777415e0e5622b25da0d6adcafb2a285eb175dec5d113c6f13a5317e8c700b0
|
Provenance
The following attestation bundles were made for aiva_agent-0.3.19.tar.gz:
Publisher:
publish.yml on MHSPL/aiva-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aiva_agent-0.3.19.tar.gz -
Subject digest:
a4f8980ddb8972cbb9c626e42a054fa44f48e0850fa5f2890ee5405c278e9c84 - Sigstore transparency entry: 2031354370
- Sigstore integration time:
-
Permalink:
MHSPL/aiva-agent@2b56de85c756f8146940f60175c6ab6214782255 -
Branch / Tag:
refs/tags/v0.3.19 - Owner: https://github.com/MHSPL
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b56de85c756f8146940f60175c6ab6214782255 -
Trigger Event:
release
-
Statement type:
File details
Details for the file aiva_agent-0.3.19-py3-none-any.whl.
File metadata
- Download URL: aiva_agent-0.3.19-py3-none-any.whl
- Upload date:
- Size: 197.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8e824847a7e6ef0cf322edf272e82a7c8975916cca2fc327db77b4fd46f4499
|
|
| MD5 |
ee66d9bc6d3cd70b7f03c1cf72e32ce0
|
|
| BLAKE2b-256 |
7c67ad36571d89e6851bc853afff57805a7fe4eb617a95058418dcd7abc9905c
|
Provenance
The following attestation bundles were made for aiva_agent-0.3.19-py3-none-any.whl:
Publisher:
publish.yml on MHSPL/aiva-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aiva_agent-0.3.19-py3-none-any.whl -
Subject digest:
d8e824847a7e6ef0cf322edf272e82a7c8975916cca2fc327db77b4fd46f4499 - Sigstore transparency entry: 2031354467
- Sigstore integration time:
-
Permalink:
MHSPL/aiva-agent@2b56de85c756f8146940f60175c6ab6214782255 -
Branch / Tag:
refs/tags/v0.3.19 - Owner: https://github.com/MHSPL
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b56de85c756f8146940f60175c6ab6214782255 -
Trigger Event:
release
-
Statement type: