Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cadenza

Connect your W&B experiments to AI agents for autonomous ML research loops.

Cadenza imports your Weights & Biases runs into an Evolutionary Database, organizing them into genotypes, islands, and elites. AI agents can then query this structured view to decide what to try next — closing the loop between experiment tracking and autonomous research.

  • CLI and Python SDK primiarily for agents, but also for humans
  • LLM-ready async client that returns structured context for autonomous research loops
  • Lightweight: only two dependencies (httpx, pydantic)

Install

pip install cadenza

Or with uv:

uv pip install cadenza

Requires Python 3.11+.

Quickstart

1. Authenticate

Log in with your API token (generate one at www.myluca.ai):

cadenza login --token evodb_sk_...

2. Import a W&B project

First, make sure your W&B credentials are configured:

cadenza config wandb.entity my-team
cadenza config wandb.api-key my-wandb-api-key

Then import a project:

cadenza import my-wandb-project

Check import status:

cadenza import list

Or add a single run incrementally:

cadenza add --run_id abc123def

3. Explore your data

# List all projects
cadenza projects

# Set a default project so you don't have to pass -p every time
cadenza config defaults.project my-wandb-project

# View the genotype (search space + behavioral dimensions)
cadenza genotype

# List islands (subpopulations)
cadenza islands

# View the elite archive (top-performing experiments across all islands)
cadenza elites

# Get a compact JSON snapshot for agent consumption
cadenza sample

Python SDK

The SDK exposes an async client for programmatic access — designed for AI agent integrations.

import asyncio
from cadenza import CadenzaClient

async def main():
    async with CadenzaClient(token="evodb_sk_...", user_id="...") as client:
        # List projects
        projects = await client.list_projects()
        for p in projects:
            print(p.name, p.slug)

        # Get the search space definition
        genotype = await client.get_genotype("my-project")
        for dim in genotype.behavioral_dimensions:
            print(f"  {dim.name}: {dim.description}")

        # Browse islands and their experiments
        islands = await client.list_islands("my-project")
        for island in islands:
            print(f"{island.island_name}: {island.phenotype_count} phenotypes")

        experiments = await client.list_island_experiments(
            "my-project", islands[0].island_name
        )

        # Get the elite archive
        elites = await client.list_elites("my-project")

        # Get a compact, LLM-ready context snapshot
        context = await client.sample("my-project", top_phenotypes=3)
        print(context.model_dump())  # JSON-serializable dict

asyncio.run(main())

Agent loop pattern

The sample method is the key integration point for autonomous research loops. It returns a compact snapshot of the evolutionary state — genotype, islands, and elite archive — that fits in an LLM context window:

from cadenza import CadenzaClient

async def agent_step(client: CadenzaClient, project: str):
    # 1. Get current evolutionary state
    context = await client.sample(project, top_phenotypes=5)

    # 2. Feed to your LLM / agent
    #    context.genotype  — search space definition
    #    context.islands   — subpopulation summaries
    #    context.elite_archive — best solutions found so far

    # 3. Agent decides next experiment based on context
    # 4. Run experiment, log to W&B
    # 5. Re-import and repeat

Importing W&B data programmatically

result = await client.start_wandb_import(
    entity="my-team",
    api_key="my-wandb-api-key",
    projects=["project-a", "project-b"],
    max_behavioral_dimensions=8,
    elite_archive_size=10,
    max_islands=20,
)
for job in result.imports:
    print(f"{job.project}: {job.status}")

# Check import status
imports = await client.list_imports(status_filter="running")

Adding a single W&B run

Use add_wandb_run to incrementally add individual runs to an existing project:

result = await client.add_wandb_run(
    project_name="my-project",
    entity="my-team",
    api_key="my-wandb-api-key",
    wandb_project="my-wandb-project",
    run_id="abc123def",
)
for job in result.imports:
    print(f"{job.project}: {job.status}")

CLI Reference

Authentication

Command Description
cadenza login [--token TOKEN] [--url URL] Authenticate with an API token
cadenza status Show current auth status
cadenza logout Remove stored credentials

Configuration

cadenza config                        # List all config values
cadenza config <key>                  # Get a value
cadenza config <key> <value>          # Set a value

Data queries

Command Description
cadenza projects List all accessible projects
cadenza genotype [-p PROJECT] Show active genotype and behavioral dimensions
cadenza islands [-p PROJECT] List islands and population stats
cadenza experiments -i ISLAND [-p PROJECT] [--page N] List experiments in an island
cadenza elites [-p PROJECT] Show the elite archive
cadenza sample [-p PROJECT] [--top-phenotypes N] Generate LLM-ready JSON context

Import

Command Description
cadenza import <wandb-project> Start importing a W&B project
cadenza import list List active import jobs
cadenza add --run_id RUN_ID [-p PROJECT] [--wandb-project NAME] Add a single W&B run to an existing project

Utilities

Command Description
cadenza schema Output full command schema as machine-readable JSON

All data query commands accept -p/--project to specify the project. Set a default with cadenza config defaults.project <name> to omit it.

Configuration reference

Cadenza stores configuration in ~/.cadenza/config.toml. Manage it with cadenza config:

Key Type Description
wandb.entity string W&B team or username for imports
wandb.api-key string W&B API key for imports
defaults.project string Default project for all -p flags
sampling.p-explore float Exploration probability for sampling
sampling.p-exploit float Exploitation probability for sampling
evodb.max-dimensions int Max behavioral dimensions during import
evodb.elite-archive-size int Elite archive size during import
evodb.max-islands int Max islands created during import

Concepts

Cadenza organizes ML experiment data using evolutionary algorithm concepts:

  • Genotype — Defines the search space and behavioral dimensions for a project
  • Islands — Subpopulations of experiments, each exploring a different region of the search space
  • Phenotypes/Experiments — Individual ML runs with their metrics and behavioral coordinates
  • Elites — The top-performing experiments across all islands (the elite archive)
  • Sample — A compact JSON snapshot of the evolutionary state, designed for LLM consumption

License

Apache 2.0 — see LICENSE for details.

About

CLI tool that makes it easy to connect raw ML experiments data to AI Agents for autonomous research loops.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages