> ## Documentation Index
> Fetch the complete documentation index at: https://docs.freesolo.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments

> What a Freesolo environment is, and how to scaffold your first one.

An [**environment**](/environment-model) is the task: the data your model sees and the reward, a
numeric score your code assigns to each model output. Flash loads environments
through the Freesolo environment SDK. Author one locally, publish it to
Freesolo's managed Environments Hub, and reference it in config by its Freesolo
environment id.

```toml theme={null}
[environment]
id = "your-org/your-env"
```

## Scaffold one

```bash theme={null}
flash env setup
```

This scaffolds a starter project in the current directory: `environment.py`, a
tiny `dataset/train.jsonl`, three configs (`configs/sft.toml` for SFT,
`configs/rl.toml` for GRPO, and `configs/opd.toml` for OPD), and a `TRAINING.md`
playbook for the coding agent you point at the project. The starter `load_environment()` returns a Freesolo
`EnvironmentSingleTurn` with a sample dataset and reward.

On an interactive terminal, `flash env setup` first runs a short survey: whether
the model handles your task in a single turn or a bounded multi-turn episode, and
whether to train with reasoning. Answer up front with `--single-turn` /
`--multi-turn` and `--reasoning` / `--no-reasoning`, or pass `-y` to take the
defaults (single-turn, no reasoning); non-interactive runs (no TTY or CI) always
take the defaults. `--multi-turn` scaffolds a runnable `EnvironmentMultiTurn`
starter with the episode hooks wired end-to-end instead of the single-turn class,
and `--reasoning` sets `thinking = true` in the generated configs.

```python environment.py theme={null}
import json
from pathlib import Path

from freesolo.datasets import TaskExample
from freesolo.environments import EnvironmentSingleTurn, RewardResult

DEFAULT_DATASET_PATH = Path(__file__).parent / "dataset" / "train.jsonl"


def load_jsonl(path):
    with Path(path).open() as f:
        return [json.loads(line) for line in f if line.strip()]


class StarterEnv(EnvironmentSingleTurn):
    dataset = load_jsonl(DEFAULT_DATASET_PATH)

    def build_prompt_messages(self, example: TaskExample, prompt_text: str):
        return [{"role": "user", "content": example.input}]

    def score_response(self, example: TaskExample, response_text: str) -> RewardResult:
        expected = str(example.output or "").strip()
        score = 1.0 if expected and expected in response_text else 0.0
        return RewardResult(score=score, threshold=1.0)


def load_environment(dataset_path: str | None = None, **kwargs) -> StarterEnv:
    env = StarterEnv()
    if dataset_path:
        env.dataset = load_jsonl(dataset_path)
    return env
```

Replace the dataset and reward with your task:

* [**Dataset**](/guides/datasets): the prompts (and any gold answers) your model trains and is
  evaluated on.
* **Reward**: `score_response` returns a `RewardResult`. GRPO optimizes that
  score; SFT trains directly on your dataset answers instead; OPD distills a
  teacher's token-level grading of the model's own completions. See [how Flash
  works](/how-flash-works).

For multi-turn tasks (conversations, tool use, agents), use `EnvironmentMultiTurn`
and implement the episode hooks. See [Multi-turn environments](/guides/environments/multi-turn) below.

## Use the SDK

Your environment code imports from the `freesolo` package. **The managed flow
needs no local install.** Training workers already have the SDK when they import
your published environment. Install it locally only to run or test
`environment.py` yourself. Local `flash train --cost` uses the configured SFT
`max_examples` and does not import the environment:

```bash theme={null}
uv pip install freesolo
```

## Next steps

<CardGroup cols={2}>
  <Card title="Package & publish" icon="box" href="/guides/environments/package">
    Structure the folder and push it to the Hub.
  </Card>

  <Card title="Single-turn environments" icon="flask" href="/guides/environments/single-turn">
    Write the dataset, prompts, and reward.
  </Card>
</CardGroup>
