Metadata-Version: 2.4
Name: bolero-ai
Version: 0.1.7.post1
Summary: Bolero — a governed autonomous-research platform: the exploration harness, the Bolero Code SDK, and the World viewer in one distribution
Author: Northwestern-CSSI
License-Expression: MIT
Project-URL: Homepage, https://github.com/Northwestern-CSSI/Bolero
Project-URL: Repository, https://github.com/Northwestern-CSSI/Bolero
Project-URL: Issues, https://github.com/Northwestern-CSSI/Bolero/issues
Keywords: bolero,autonomous-research,agent,llm,scientific-discovery
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: <3.12,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: code
Requires-Dist: hydra-core<1.4,>=1.3; extra == "code"
Requires-Dist: jinja2<4,>=3.1; extra == "code"
Requires-Dist: omegaconf<3,>=2.3; extra == "code"
Requires-Dist: pydantic<3,>=2.9; extra == "code"
Requires-Dist: PyYAML<7,>=6; extra == "code"
Provides-Extra: harness
Requires-Dist: bolero-ai[code]; extra == "harness"
Requires-Dist: httpx~=0.28.1; extra == "harness"
Requires-Dist: hydra-core~=1.3; extra == "harness"
Requires-Dist: kuzu~=0.11; extra == "harness"
Requires-Dist: markdown-it-py~=4.2.0; extra == "harness"
Requires-Dist: networkit~=11.1; extra == "harness"
Requires-Dist: networkx~=3.4; extra == "harness"
Requires-Dist: numpy~=2.1; extra == "harness"
Requires-Dist: omegaconf~=2.3; extra == "harness"
Requires-Dist: pydantic~=2.9.0; extra == "harness"
Requires-Dist: python-frontmatter~=1.3.0; extra == "harness"
Requires-Dist: PyYAML~=6.0.3; extra == "harness"
Requires-Dist: rich~=15.0; extra == "harness"
Requires-Dist: scipy~=1.14; extra == "harness"
Requires-Dist: textual~=8.2; extra == "harness"
Provides-Extra: world
Provides-Extra: offline
Requires-Dist: bolero-ai-runtime==0.1.7.post1; extra == "offline"
Provides-Extra: all
Requires-Dist: bolero-ai[code,harness,world]; extra == "all"
Dynamic: license-file

<div align="center">

# Bolero

**The governed autonomous-research platform — from empirical evidence to human-owned, peer-reviewable scientific claims.**

<a href="https://pypi.org/project/bolero-ai/"><img src="https://img.shields.io/pypi/v/bolero-ai?label=PyPI" alt="PyPI version"></a>
<a href="https://pypi.org/project/bolero-ai/"><img src="https://img.shields.io/pypi/dm/bolero-ai" alt="PyPI downloads"></a>
<img src="https://img.shields.io/badge/python-3.11-blue" alt="Python 3.11">
<img src="https://img.shields.io/badge/platform-linux-lightgrey" alt="Linux">
<a href="https://github.com/Northwestern-CSSI/Bolero/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a>

[PyPI](https://pypi.org/project/bolero-ai/) ·
[Quickstart](#quickstart) ·
[Operator guide](https://github.com/Northwestern-CSSI/Bolero/blob/main/bolero-harness/README.md) ·
[Agent runtime](https://github.com/Northwestern-CSSI/Bolero/blob/main/bolero-code/README.md) ·
[Model serving](https://github.com/Northwestern-CSSI/Bolero/blob/main/envs/llm/SERVING.md)

</div>

Bolero runs complete research campaigns: autonomous agents propose research
questions, execute governed analyses against a real dataset and literature
corpus, integrate what they learn into an explicit knowledge graph, and write
the result up as a manuscript that stands to independent review. Every
scientific action happens inside a sealed container under typed contracts,
so the evidence trail behind every claim is inspectable end to end. This
repository contains the whole platform: the exploration harness, the Bolero
Code agent runtime, the World viewer, and the environment kits used by
sealed scientific runs.

## Highlights

- **Sealed execution** — every agent call runs in a container with exactly
  one writable workspace; the dataset, the literature corpus, and the
  knowledge store are read-only mounts, and the model is reached through a
  harness-provided socket, not the open network.
- **Typed contracts, not vibes** — every artifact an agent leaves behind is
  validated against pydantic contracts by in-container stop gates and again
  by the host before it can advance the campaign.
- **An explicit World** — what the campaign knows lives in an epistemic
  graph of Atoms (evidence-backed claims with typed, weighted bonds) and
  Molecules (publication storylines over them), browsable live in the
  bundled viewer.
- **All-or-nothing knowledge integration** — each exploration loop commits
  its findings to the World as one validated transaction; a failed wave
  leaves the canonical store untouched.
- **Human-owned publication** — sending a storyline to the publication lane
  is the operator's readiness decision; an independent in-lane review gates
  the manuscript, and a request for new evidence hands control back to the
  operator instead of papering over it.
- **Reproducible by construction** — frozen campaign configuration, a Git
  history inside every session, and (under Singularity or Apptainer) a
  runtime image resolved once at campaign birth to its content digest and
  never changed mid-run; Docker resolves references at each call, so pin a
  dated tag or digest there yourself.

## How it works

```mermaid
flowchart LR
    subgraph s1["Stage 1 — exploration, one loop per pass"]
        A["allocation"] --> P["proposals"] --> T["tournament"]
        T --> L["plan → execute → review<br/>(parallel lanes)"]
        L --> W["world integration"]
    end
    W -->|one transaction per loop| WORLD[("the World<br/>Atoms + Molecules")]
    WORLD --> A
    WORLD --> B
    subgraph s2["Stage 2 — publication, operator-triggered"]
        B["blueprint"] --> D["draft"] --> R["independent review"]
    end
    R --> M["manuscript"]
```

**Stage 1 — exploration.** Each loop allocates frontier regions to parallel
proposers, holds a tournament over their candidate research questions, and
runs one plan → execute → review lane per accepted proposal against the
governed dataset. Accepted results are minted into Atoms, and one
world-integration wave restructures the Molecule layer over them — applied
to the World as a single all-or-nothing transaction before the next loop
begins.

**Stage 2 — publication.** For one operator-selected Molecule, the lane
turns the storyline into a blueprint, drafts the manuscript with its
figures, and submits it to an independent review stage that either accepts,
directs bounded in-place repairs, or ends the run asking the operator for
new evidence.

## Quickstart

### Prerequisites

- Linux on x86_64 with Conda and Git ≥ 2.28 (a campaign session records
  its history in its own Git repository, created with `git init -b`)
- Node.js 22.x for host-side interactive use of Bolero Code (the shipped
  router addon is built for that line; sealed calls use the image's own Node)
- Singularity, Apptainer, or Docker
- CPUs for the configured parallelism: the packaged default
  (`campaign.max_parallelism=8`, two governed threads per call) requires 16
  available logical CPUs at launch; on a smaller machine lower
  `campaign.max_parallelism` on the launch command
- an already-deployed OpenAI-compatible model endpoint serving the model
  the harness is configured for — the packaged default is
  `qwen3.8-flash-next` at `http://127.0.0.1:30000`
  (`bolero-harness/bolero/conf/llm/default.yaml`). This README assumes that
  deployment (SGLang in production) is already up; the serving recipes live
  in [`envs/llm/`](https://github.com/Northwestern-CSSI/Bolero/blob/main/envs/llm/SERVING.md). If the endpoint runs on another
  machine, expose it to this one through an SSH tunnel.

### Install

Bolero is one Python distribution, `bolero-ai`, carrying three import
packages — the exploration harness (`bolero`), the Bolero Code SDK
(`bolero_code_sdk`), and the World viewer (`bolero_world`) — plus one
non-Python runtime bundle that the harness provisions itself. The wheel
always ships all of the code; the extras are dependency groups: `[harness]`
the Stage-1 driver's stack, `[code]` the SDK's, `[world]` nothing (the
viewer is standard library only), `[offline]` the runtime bundle as a PyPI
distribution, `[all]` the union of the three functional groups. Python 3.11
on Linux is required
(`requires-python = ">=3.11,<3.12"`: the `kuzu` and `networkit` wheels the
World graph depends on ship for 3.11). Create an environment carrying that
interpreter plus the host-side gate binaries the publication drivers shell
out to (`pdftotext`, `pandoc`; `tectonic` rides along for parity with
the baked runtime), and install from PyPI:

```bash
conda create -n bolero -c conda-forge python=3.11 pip poppler poppler-data pandoc tectonic
conda activate bolero
pip install "bolero-ai[all]==0.1.7.post1"
```

(From a checkout, `conda env create -f environment.yml` builds the same
environment, and `pip install -e '.[harness]'` installs the tree
editably.)

(Production installs use `[all]`; a bare `pip install bolero-ai` ships all
of the code but none of the third-party stacks, so pick at least the groups
you will run.)

Provision the Bolero Code runtime — the compiled CLI, its pinned
claude-code-router, the launcher and the container wrappers — into
`~/.local/share/bolero-code`, then run the
prerequisite diagnostic — interpreter, packages, `bolero-code`, container
engine, image reference, endpoint reachability:

```bash
bolero-harness setup
export PATH="$HOME/.local/bin:$PATH"   # where setup links bolero-code
bolero-harness doctor
```

### Hosts that reach PyPI and not GitHub

`setup` downloads the runtime bundle from the matching GitHub Release. A
host without GitHub takes the same bundle through PyPI instead, and gets
the repository itself the same way:

```bash
pip install "bolero-ai[all,offline]==0.1.7.post1"
bolero-harness setup      # reads the bundle from the installed distribution
bolero-harness download   # writes the repository into the current directory
```

`download` unpacks the source tree the release wheel carries — the same
tree a clone would give, minus its Git history — and works on a bare
`pip install bolero-ai`. What pip cannot carry is the runtime container
image: it is ~13 GB, lives at `ghcr.io`, and must reach such a host by
other means, addressed with `runtime_images.<engine>=/absolute/path.sif`.

The runtime container image is not installed. Under Singularity or
Apptainer, at every campaign's birth the driver pulls
`oras://ghcr.io/northwestern-cssi/bolero-runtime:sif-latest` once into
`~/.cache/bolero/images/` under its SHA-256 and freezes that file for the
session, so the newest published image starts each new campaign and no
running campaign ever changes image; a local SIF path is frozen as the real
file behind its symlinks. Docker references are resolved by the engine at
each call — pin one yourself by naming a dated tag or digest
(`runtime_images.docker=ghcr.io/northwestern-cssi/bolero-runtime:<date>`).

### Run the Palmer Penguins demo

Scaffold the complete demo — dataset, literature corpus, seed molecules,
configuration, and launcher — and start the exploration campaign:

```bash
bolero-harness demo penguins && cd penguins
bash bolero-explore.sh
```

The script checks the Bolero Code runtime, detects the available container
engine, and launches the campaign. First use pulls the runtime image from
ghcr.io. On a terminal it opens the live TUI.
`Ctrl-C` closes only the TUI; the campaign continues in its detached
driver. Reattach from the demo directory, and serve the session's current
World from another terminal, with:

```bash
bolero-harness status
conda activate bolero && bolero-harness world   # http://127.0.0.1:3000/
```

Stage 2 — publication — is a separate, operator-triggered lane, and sending
a Molecule to it is the readiness decision: the driver stamps it
`draft: true` and runs the in-place blueprint → manuscript →
independent-review lane on the World in hand — it never re-enters
exploration. It also takes the session's exclusive driver lock, so it runs
after exploration ends: wait for the stop target, or stop the driver from
the TUI (the space gesture, behind a confirm). When exploration has built a
storyline worth writing, pick its id in the World viewer and run from the
`penguins/` directory:

```bash
bolero-harness publish \
  --session outputs/<YYYY-MM-DD>/penguins-demo \
  --molecule molecule-NNNNNN
```

`--mode` defaults to the session's frozen mode, `bolero-harness status`
attaches to it like the exploration run, and a reviewer request for new
evidence ends the run with exit code 2 for the operator to act on.

## The CLI at a glance

Everything operational stands behind one umbrella command:

| Command | Does |
|---|---|
| `bolero-harness init [dir]` | scaffold a project directory: resources, configuration, seed templates |
| `bolero-harness demo [dir]` | scaffold the ready-to-run Palmer Penguins demo |
| `bolero-harness explore …` | launch a new exploration campaign |
| `bolero-harness explore -r <session>` | resume a session from its last accepted commit |
| `bolero-harness publish --session <session> --molecule <id>` | run the publication lane for one Molecule |
| `bolero-harness status [session]` | attach the campaign TUI (plain text off a TTY) |
| `bolero-harness world [session]` | serve the World viewer web page |
| `bolero-harness setup` | provision the Bolero Code runtime bundle |
| `bolero-harness doctor` | prerequisite and configuration diagnostic |

`bolero-explore` and `bolero-publish` remain direct entry points for the
two stage drivers, and every campaign tunable is a Hydra override on the
launch command. Every sealed stage call also records a resumable agent
session inside its campaign directory: from that directory, `bolero -r`
lists and continues those sessions in their original container environment,
and `bolero -r <stage-label> -p "question"` asks a one-shot follow-up
(see [`bolero-code/README.md`](https://github.com/Northwestern-CSSI/Bolero/blob/main/bolero-code/README.md#resuming-agent-sessions--r), "Resuming agent
sessions").

## Repository layout

| Path | Purpose |
|---|---|
| [`bolero-harness/`](https://github.com/Northwestern-CSSI/Bolero/tree/main/bolero-harness) | exploration driver, typed stage contracts, TUI, and demo |
| [`bolero-code/`](https://github.com/Northwestern-CSSI/Bolero/tree/main/bolero-code) | agent CLI, router, SDK, and sealed-container launcher |
| [`bolero-world/`](https://github.com/Northwestern-CSSI/Bolero/tree/main/bolero-world) | local World graph viewer |
| [`envs/`](https://github.com/Northwestern-CSSI/Bolero/tree/main/envs) | scientific runtime-image and model-serving environment kits |

## Documentation

- [`bolero-harness/README.md`](https://github.com/Northwestern-CSSI/Bolero/blob/main/bolero-harness/README.md) — the operator
  guide: configuration, scenarios, campaign control, progress and resuming
- [`bolero-code/README.md`](https://github.com/Northwestern-CSSI/Bolero/blob/main/bolero-code/README.md) — the agent runtime:
  CLI, router, sealed sessions, and session resume
- [`envs/llm/SERVING.md`](https://github.com/Northwestern-CSSI/Bolero/blob/main/envs/llm/SERVING.md) — the model-serving recipes
  behind the endpoint prerequisite
- [`envs/container/`](https://github.com/Northwestern-CSSI/Bolero/tree/main/envs/container) — how the scientific runtime image
  is built and published

## License

[MIT](https://github.com/Northwestern-CSSI/Bolero/blob/main/LICENSE) © Northwestern-CSSI
