UDI Agent: LLM-powered data visualization orchestration library
Project description
UDIAgent
LLM-powered data visualization orchestration library for the Universal Discovery Interface (UDI).
UDIAgent orchestrates LLM calls to generate data visualization specs from natural language queries. It can be used as a standalone Python library or deployed as a FastAPI microservice.
Installation
# Core library only
pip install udiagent
# With the reference FastAPI server
pip install udiagent[server]
# With LangFuse observability
pip install udiagent[langfuse]
# With benchmarking tools
pip install udiagent[benchmark]
# Everything
pip install udiagent[all]
For local development with uv:
uv sync --extra server --extra langfuse --extra test # server + dev
Library Usage
from udiagent import UDIAgent, Orchestrator
# Initialize the agent with explicit configuration (no environment variables)
agent = UDIAgent(
gpt_model_name="gpt-5.4",
openai_api_key="sk-...",
)
# Create an orchestrator
orch = Orchestrator(agent)
# Run a query
result = orch.run(
messages=[{"role": "user", "content": "Show me a bar chart of donors by sex"}],
data_schema='{"resources": [...]}',
data_domains='[{"entity": "donors", "field": "sex", ...}]',
)
# result.tool_calls — list of tool call dicts (e.g. RenderVisualization, FilterData)
# result.orchestrator_choice — "render-visualization", "both", "explain", etc.
Key Classes
| Class | Description |
|---|---|
UDIAgent |
OpenAI client wrapper |
Orchestrator |
Routes user requests to visualization, filter, explanation, and clarification handlers |
OrchestratorResult |
Dataclass with tool_calls and orchestrator_choice |
Utility Functions
| Function | Description |
|---|---|
load_grammar() |
Load the UDI Grammar JSON schema (bundled with the package) |
load_skills() |
Load skill prompt templates (bundled with the package) |
render_template() |
Substitute {{key}} placeholders in a skill instruction template |
generate_vis_spec() |
Generate a visualization spec using the skills pipeline |
simplify_data_domains() |
Simplify data domains JSON into compact LLM-friendly text |
parse_schema_from_dict() |
Parse a data schema dict into structured format |
Server Usage
The udiagent.server subpackage provides a reference FastAPI application that wraps the library as a configurable microservice. It reads configuration from environment variables.
Running the Server for Local Development
# Development
uv run fastapi dev src/udiagent/server/app.py --port 8007
# Production
uv run fastapi run src/udiagent/server/app.py --port 8007
Server Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
OPENAI_API_KEY |
No | — | OpenAI API key. If not set, must be provided per-request via X-OpenAI-Key header. |
GPT_MODEL_NAME |
No | gpt-5.4 |
OpenAI model for orchestration |
JWT_SECRET_KEY |
Yes* | — | JWT signing key (*not required if INSECURE_DEV_MODE=1) |
JWT_ALGORITHM |
No | HS256 |
JWT algorithm |
INSECURE_DEV_MODE |
No | 0 |
Set to 1 to skip JWT verification (development only) |
LANGFUSE_SECRET_KEY |
No | — | LangFuse observability secret key |
LANGFUSE_PUBLIC_KEY |
No | — | LangFuse observability public key |
LANGFUSE_BASE_URL |
No | — | LangFuse instance URL |
Server Endpoints
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | API status and info |
/v1/yac/completions |
POST | Main orchestrator — routes user requests to tools |
/v1/yac/benchmark |
POST | Benchmark variant with optional orchestrator override |
/v1/yac/examples |
GET | Example prompts from data/example_prompts.json |
/v1/yac/structured_functions |
GET | Structured function registry |
/v1/yac/benchmark_analysis |
GET | Latest benchmark analysis results |
Docker
docker build -t udiagent .
docker run -p 80:80 --env-file .env udiagent
Architecture
Orchestration Flow
User query
→ Orchestrator.run()
→ GPT with ORCHESTRATOR_TOOLS (5 tools: CreateVisualization, FilterData,
FreeTextExplain, ClarifyVariable, Rebuff)
→ Dispatch each tool call to its handler
→ Return OrchestratorResult(tool_calls, orchestrator_choice)
Visualization Generation
Executes a two-step markdown skill plan via generate_vis_spec (vis_generate.py):
- generate — LLM produces a UDI Grammar spec from the request, schema, and few-shot examples
- validate — JSON schema check with a bounded repair-retry loop
Skills live in src/udiagent/data/skills/*.md (YAML frontmatter + prompt body).
Design Principles
- Stateless — All context travels in message history; no server-side session state
- Skills as Markdown — Prompt templates live in
.mdfiles with YAML frontmatter - Per-request key override — Supports both default and per-request OpenAI API keys
Regenerating Template Visualizations and Tool Definitions
The vis pipeline uses two generated artifacts:
src/udiagent/data/skills/template_visualizations.json— template visualization specssrc/udiagent/generated_vis_tools.py— typed OpenAI function-calling tool definitions
To regenerate both in one step:
uv pip install -e ".[codegen]"
uv run python scripts/regenerate_vis_tools.py
By default this uses data/data_domains/hubmap_data_schema.json as the schema. To use a different schema:
uv run python scripts/regenerate_vis_tools.py --schema data/data_domains/SenNet_domains.json
Benchmarking
Step 0: Start the API server
uv run fastapi dev src/udiagent/server/app.py --port 8007 &
Step 1: Run tiny benchmark (1 example)
uv run python -m udiagent.benchmark.runner --no-orchestrator --path ./data/benchmark_dqvis/tiny.jsonl
Step 2: Run small benchmark (100 examples)
uv run python -m udiagent.benchmark.runner --no-orchestrator --path ./data/benchmark_dqvis/small.jsonl --workers 5
Resume a failed run:
uv run python -m udiagent.benchmark.runner --path ./data/benchmark_dqvis/small.jsonl --workers 5 --resume ./out/<TIMESTAMP>/benchmark_results.json
License
MIT
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 udiagent-0.2.1.tar.gz.
File metadata
- Download URL: udiagent-0.2.1.tar.gz
- Upload date:
- Size: 28.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8093e0d5c5748904f91a96c24241be0d76a1bd97cdbb8577533bd20810097120
|
|
| MD5 |
1b1a7df9185b63200192b9c32b137622
|
|
| BLAKE2b-256 |
7a633140f947bdb0389deb2002492e4c064636034d949af4579bb9a701a490e7
|
Provenance
The following attestation bundles were made for udiagent-0.2.1.tar.gz:
Publisher:
publish.yaml on hms-dbmi/UDIAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
udiagent-0.2.1.tar.gz -
Subject digest:
8093e0d5c5748904f91a96c24241be0d76a1bd97cdbb8577533bd20810097120 - Sigstore transparency entry: 1343089998
- Sigstore integration time:
-
Permalink:
hms-dbmi/UDIAgent@8d0e75e7c9d65c6880132241a8ef04ef8d320fd1 -
Branch / Tag:
refs/tags/0.2.1 - Owner: https://github.com/hms-dbmi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@8d0e75e7c9d65c6880132241a8ef04ef8d320fd1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file udiagent-0.2.1-py3-none-any.whl.
File metadata
- Download URL: udiagent-0.2.1-py3-none-any.whl
- Upload date:
- Size: 78.8 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 |
3977536204295d7956e7c5af3d65c57758f39475c5696e5c916cdcea7ddec6a4
|
|
| MD5 |
768215d8178a7722bdddb09ae0625863
|
|
| BLAKE2b-256 |
3dc8ffc6082bcaedc47dd16d218d7b9566b92deba507f25598c128bd2d3c3022
|
Provenance
The following attestation bundles were made for udiagent-0.2.1-py3-none-any.whl:
Publisher:
publish.yaml on hms-dbmi/UDIAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
udiagent-0.2.1-py3-none-any.whl -
Subject digest:
3977536204295d7956e7c5af3d65c57758f39475c5696e5c916cdcea7ddec6a4 - Sigstore transparency entry: 1343090015
- Sigstore integration time:
-
Permalink:
hms-dbmi/UDIAgent@8d0e75e7c9d65c6880132241a8ef04ef8d320fd1 -
Branch / Tag:
refs/tags/0.2.1 - Owner: https://github.com/hms-dbmi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@8d0e75e7c9d65c6880132241a8ef04ef8d320fd1 -
Trigger Event:
release
-
Statement type: