Metadata-Version: 2.5
Name: helioai-agent
Version: 0.2.0
Summary: AI agent for heliophysics and space plasma data analysis
Project-URL: Homepage, https://github.com/erdoganfurkan/HelioAI
Project-URL: Repository, https://github.com/erdoganfurkan/HelioAI
Project-URL: Issues, https://github.com/erdoganfurkan/HelioAI/issues
Author-email: Furkan Erdogan <furkan.erdogan.pro@gmail.com>
License: MIT
License-File: LICENSE
Keywords: AI agent,MCP,heliophysics,plasma,space physics
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Astronomy
Requires-Python: >=3.12
Requires-Dist: astropy>=6.0
Requires-Dist: chromadb>=0.5
Requires-Dist: fastapi>=0.115
Requires-Dist: geopack>=1.0.11
Requires-Dist: google-genai>=0.8
Requires-Dist: httpx>=0.27
Requires-Dist: ipykernel>=6.0
Requires-Dist: ipython>=8.27
Requires-Dist: ipywidgets>=8.0
Requires-Dist: matplotlib>=3.10
Requires-Dist: mcp<2,>=1.0
Requires-Dist: nbformat>=5.0
Requires-Dist: numpy>=2.1
Requires-Dist: openai>=1.30
Requires-Dist: pillow>=10
Requires-Dist: plasmapy>=2024.5
Requires-Dist: python-dotenv>=1.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rank-bm25>=0.2
Requires-Dist: scipy>=1.15
Requires-Dist: sentence-transformers>=3.0
Requires-Dist: speasy>=1.4
Requires-Dist: structlog>=24.0
Requires-Dist: uvicorn[standard]>=0.30
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
Provides-Extra: solarmach
Requires-Dist: solarmach>=0.5; extra == 'solarmach'
Description-Content-Type: text/markdown

# HelioAI

**AI agent for heliophysics and space plasma data analysis.**

Ask questions in natural language — HelioAI finds the right parameter across 70+ missions, downloads it, runs the analysis, and produces reproducible plots and notebooks.

[![CI](https://github.com/erdoganfurkan/HelioAI/actions/workflows/ci.yml/badge.svg)](https://github.com/erdoganfurkan/HelioAI/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/erdoganfurkan/HelioAI/branch/main/graph/badge.svg)](https://codecov.io/gh/erdoganfurkan/HelioAI)
[![PyPI](https://img.shields.io/pypi/v/helioai-agent)](https://pypi.org/project/helioai-agent/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.12%20%7C%203.13%20%7C%203.14-blue)](pyproject.toml)

---

## What it does

```
You:      "IP shock in WIND data, January 2005 — compute θ_Bn"

HelioAI:  → resolves param IDs for B, Vp, Np across 83k speasy products
          → downloads the time series via speasy (AMDA / CDAWeb / CSA)
          → runs shock detection + coplanarity theorem in a sandboxed Python env
          → returns a plot, the θ_Bn value, and a reproducible .ipynb notebook
```

No API key required for data access. No manual parameter hunting.

---

## Features

- **Hybrid RAG** — semantic (MiniLM) + lexical (BM25) search over 83k parameters, fused by Reciprocal Rank Fusion. Finds both vague descriptions *and* exact codes (`BGSEc`, `FGM`, `igrf_8sec_gse`).
- **Event catalogs & timetables** — access 217 curated AMDA catalogs (ICMEs, bow-shock crossings, reconnection events, substorms, …). Download a parameter across every event in one call — the foundation for superposed epoch analysis and statistical surveys.
- **PlasmaPy tools** — plasma β, gyrofrequency, Debye length, Alfvén speed, inertial length, power spectrum — ready-made for the agent.
- **Sandboxed Python** — the agent writes and runs analysis code under bubblewrap isolation on Linux (see SECURITY.md). All scripts are saved for reproducibility.
- **6 specialised skills** — `parameter_hunter`, `data_analyst`, `plasma_physicist`, `librarian`, `plotting`, `helioai_helper` — loaded as markdown, zero coupling to the agent loop.
- **Derived recipes** — 9 reusable scientific scripts, each with a cited reference: θ_Bn, Walén test, MVAB, Rankine-Hugoniot jump conditions, pressure balance, pitch angle distribution, superposed epoch, SEP onset (Poisson-CUSUM), Parker spiral connectivity.
- **Literature search** — `find_papers` queries NASA ADS for papers relevant to an event or parameter; a dedicated `librarian` sub-agent handles multi-round literature searches without derailing the main analysis.
- **Fill value masking** — `clean()` helper in the sandbox automatically masks CDF fill values (`|x| ≥ 1e30`, `±inf`) before any plot or analysis.
- **Data quality checks** — every `get_timeseries` download is scanned (deterministically, no LLM) for missing/fill values, data gaps, and 5σ outliers; the agent flags them only when they matter, so you know what you're working with *before* analysis.
- **Plan preview** — for a multi-step request the agent first lays out a short structured plan (the steps and the tool/method each will use), then executes — transparent, no black box.
- **Standalone notebook export** — any session exports as a self-contained `.ipynb`: `load_data()` calls are rewritten to direct `spz.get_data(...)`, sandbox-only helpers are stripped, and a *Methods & data acknowledgements* cell lists the recipes and references used — every cell re-runs in a plain Jupyter kernel.
- **Multiple interfaces** — interactive CLI, Jupyter magic, Web UI (FastAPI + SSE + activity dock), MCP server (Claude Desktop / `claude` CLI).
- **User profile** — inject your preferred missions, domain, and plot style once; the agent adapts to you.
- **Heliophysics scope guardrail** — the agent stays on-topic; a dev token unlocks unrestricted mode for development.

---

## Installation

```bash
pip install helioai-agent
```

Or from source with [uv](https://docs.astral.sh/uv/):

```bash
git clone https://github.com/erdoganfurkan/HelioAI.git
cd HelioAI
uv sync
```

**First run — build the parameter index** (one-time, ~10 min, 83k products):

```bash
helioai index
```

This downloads the speasy catalogue and indexes it into a local ChromaDB. It lands in
`<repo>/data/` when running from a clone, and in `~/.local/share/helioai/` when installed
from PyPI — override either with `HELIOAI_DATA_DIR`.

---

## Configuration

Copy `.env.example` to `.env` and set at least one LLM provider key:

```ini
# LLM provider (groq | gemini | azure | opencode | ollama)
HELIOAI_LLM_PROVIDER=groq

GROQ_API_KEY=your_key_here
GEMINI_API_KEY=your_key_here

# Azure OpenAI (if using azure)
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=...
AZURE_OPENAI_DEPLOYMENT=gpt-4o

# OpenCode Zen (if using opencode) — however you reach it (Go plan, BYOK), no default model
OPENCODE_API_KEY=...
HELIOAI_OPENCODE_MODEL=...

# Ollama (if using ollama — no API key needed)
HELIOAI_OLLAMA_URL=http://localhost:11434
HELIOAI_OLLAMA_MODEL=qwen2.5:14b-instruct
```

| Provider | Model | Notes |
|---|---|---|
| `groq` | `llama-3.3-70b-versatile` | Free tier, fast — **recommended to start** |
| `gemini` | `gemini-2.5-flash` | Better reasoning, generous free quota |
| `azure` | configurable | Enterprise deployments |
| `opencode` | configurable | OpenCode's Zen gateway, OpenAI-compatible |
| `ollama` | `qwen2.5:14b-instruct` | Fully local, no API key |

Any other OpenAI-compatible endpoint works too — providers are a `base_url` entry in
`helioai/core/llm/factory.py`, not a class.

---

## Usage

### Interactive CLI

```bash
helioai
```

```
helioai> solar wind density from ACE in January 2005
helioai> compare MMS and Cluster magnetic field during 2017-07-11 reconnection event
helioai> compute plasma beta in the magnetosheath — B=20nT, n=20cm-3, T=200eV
helioai> show me the IMF Bz for all ICMEs in the Richardson & Cane catalog between 2003 and 2005
helioai> superposed epoch analysis of MMS bow-shock crossings — proton density, 2017
```

One-shot mode:

```bash
helioai "IP shock detection in WIND/MFI data, 2005-01-16 to 2005-01-17"
```

### Jupyter

```python
%load_ext helioai.interfaces.jupyter_magic
```

```python
%%helioai
Download Bz from ACE for the 2003 Halloween storm and plot the storm sudden commencement.
```

Figures render inline. Export the session as a notebook:

```python
%helioai_export
```

### Web UI

```bash
helioai serve --web
# → http://localhost:7890
```

Three-panel layout: conversation · artifact viewer (plots, parameter cards) · code panel (generated scripts).

### Claude Desktop / MCP

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "helioai": {
      "command": "helioai-mcp"
    }
  }
}
```

Or run the HTTP MCP server:

```bash
helioai-mcp --http --port 8080
```

### Docker

```bash
docker compose -f docker/docker-compose.yml up -d
# → http://localhost:7890
```

Mount `./data` for persistent index and sessions. Set your LLM keys in `.env`.

---

## Data coverage

| Provider | Missions (examples) | Parameters |
|---|---|---|
| **AMDA** (CDPP) | Cluster, MMS, Solar Orbiter, WIND, ACE, Cassini, Helios, STEREO | ~12k |
| **CDAWeb** (NASA) | MMS, THEMIS, Van Allen Probes, Parker Solar Probe, Ulysses, Voyager | ~68k |
| **CSA** (ESA) | Cluster, Double Star, Solar Orbiter, Mars Express | ~1.9k |

In addition, **217 AMDA event catalogs and timetables** are accessible as first-class tools: ICMEs (Richardson & Cane — 341 events, ICME multi-catalog — 2003 events), bow-shock crossings (MMS 2797, THEMIS ~60k), magnetic reconnection EDR events (72), substorm onsets (2437), flux transfer events, MAVEN shock crossings (3837), and monthly MMS burst-mode timetables (2015–present).

Full parameter catalogue via `list_missions()` or `helioai "what missions are available"`.
Full catalog catalogue via `list_catalogs()` or `helioai "what event catalogs are available"`.

---

## Agent tools

### Data access

| Tool | Description |
|---|---|
| `search_parameters` | Hybrid RAG search — single query or batch `queries=[...]` |
| `get_timeseries` | Download a parameter via speasy (returns cadence, mission, components) |
| `list_missions` | Live catalogue of providers and missions |

### Event catalogs

| Tool | Description |
|---|---|
| `list_catalogs` | Browse 217 AMDA catalogs/timetables — filter by type and region keyword |
| `get_catalog` | Download and inspect a catalog: event count, columns, time-filtered sample |
| `get_events_timeseries` | Download a parameter across **every event** in a catalog (one speasy call) — core tool for superposed epoch analysis |

### Literature

| Tool | Description |
|---|---|
| `find_papers` | Search NASA ADS for papers relevant to an event, parameter, or method |

### Analysis

| Tool | Description |
|---|---|
| `run_python` | Sandboxed Python — speasy + plasmapy + numpy + matplotlib available |
| `plasma_beta` | β = nkT / (B²/2μ₀) |
| `gyrofrequency` | Ion/electron gyrofrequency for a given B |
| `debye_length` | Debye screening length |
| `alfven_speed` | Alfvén speed V_A = B / √(μ₀ρ) |
| `inertial_length` | Ion/electron inertial length |
| `power_spectrum` | Welch PSD on a time series |
| `list_recipes` | Catalogue of scientific Python recipes |
| `load_recipe` | Load a recipe source + reference (θ_Bn, Walén, MVAB, Rankine-Hugoniot, pressure balance, pitch angle dist, superposed epoch) |
| `task` | Delegate to a specialised sub-agent |

---

## Sub-agents

| Role | Purpose | Max turns |
|---|---|---|
| `parameter_hunter` | Resolve vague descriptions → speasy parameter IDs | 4 |
| `data_analyst` | Download, analyse, plot, multi-mission, event detection | 8 |
| `plasma_physicist` | PlasmaPy calculations, sanity checks by region | 4 |
| `librarian` | NASA ADS literature search, multi-round funnel | 4 |

---

## Architecture

```
helioai/
├── config.py                   env vars, provider settings, RAG config
├── core/
│   ├── agent_loop.py           async streaming agent (stream_chat)
│   ├── sub_agents.py           specialised sub-agents (parameter_hunter, …)
│   ├── tool_exec.py            shared tool execution logic
│   ├── session.py              SQLite conversation history
│   ├── skills_loader.py        markdown skill loader
│   ├── skills/                 5 × SKILL.md
│   └── llm/                    groq · gemini · azure · ollama + factory
├── tools/
│   ├── rag.py                  hybrid BM25+dense RAG (RRF fusion)
│   ├── speasy_tools.py         search_parameters, get_timeseries, list_missions
│   ├── plasmapy_tools.py       6 plasma physics functions
│   ├── sandbox.py              sandboxed Python execution
│   └── recipes.py              scientific recipe loader
├── interfaces/
│   ├── cli.py                  readline CLI
│   ├── jupyter_magic.py        IPython magic
│   └── web/                    FastAPI + SSE + vanilla JS UI
├── mcp_server.py               MCP stdio + HTTP streamable
├── export.py                   session → reproducible .ipynb
├── indexer.py                  speasy catalogue → ChromaDB
└── docker/                     Dockerfile + docker-compose.yml
```

---

## Development

```bash
uv sync --extra dev
uv run pytest                          # 627 tests, 77% coverage (no exclusions)
uv run ruff check helioai/ tests/      # lint
uv run ruff format helioai/ tests/     # format
```

Pre-commit hooks (ruff + trailing-whitespace):

```bash
pre-commit install
```

---

## Roadmap

- [x] CI/CD — GitHub Actions (lint + test matrix Python 3.11/3.12)
- [x] Docker — `helioai serve --web` in a container (`docker/`)
- [ ] JOSS paper
- [ ] PyPI release

---

## License

MIT — see [LICENSE](LICENSE).

---

## Related projects

- [speasy](https://github.com/SciQLop/speasy) — the data access layer powering HelioAI
- [PlasmaPy](https://github.com/PlasmaPy/PlasmaPy) — plasma physics calculations
- [PyHC](https://heliopython.org) — Python in Heliophysics Community
