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

# Environments

> Long-running ORS servers with automatic scaling

An environment on OpenReward is a long-running server that implements the **[Open Reward Standard (ORS)](https://openrewardstandard.io)** for agent environments.

When an environment is created on OpenReward, a workspace is provisioned and an API endpoint provided.

Environments provide:

* **Tasks** - tasks are the core problems to be solved, including the initial prompts
* **Tools** - tools are the actions an agent can take in the environment
* **Splits** - splits organise tasks into groups, e.g. for training and evaluation
* **Statefulness** - agent actions in a session can affect state
* **Tool Results** - including tool feedback, rewards and termination signals

Agents connect to environments via sessions, which are stateful connections.

ORS environments can be run anywhere. OpenReward hosts them and provides managed infrastructure, for example autoscaling based on demand.

## Environment Lifecycle

### 1. Creation

Create environments through the [OpenReward website](https://openreward.ai):

```text theme={null}
1. In header of the website, click the + button
   ↓
2. Click "New environment"
   ↓
3. Enter name and description
   ↓
4. Set visibility (public/private)
   ↓
5. Environment created with workspace
```

### 2. Deployment

Once you have created your environment, you can deploy your [ORS](https://openrewardstandard.io) server code to it.

First, you will need to develop your environment locally. You can read the [local development guide](/deployment/local-development) for more details on how to develop your environment server locally.

Once you are ready to deploy, you should undertake the following steps:

```text theme={null}
1. Upload your code to a GitHub repository, along with a Dockerimage
   ↓
2. Connect the GitHub repository to your environment
   ↓
3. OpenReward automatically builds and deploys whenever you push to main
   ↓
4. Environment server starts accepting sessions
```

See [the GitHub integration guide](/deployment/github-integration) for more details.

### 3. Running

Once deployed, agents can connect to your environment:

**Agent interaction:**

```python theme={null}
from openreward import AsyncOpenReward

client = AsyncOpenReward(api_key="your-api-key")

# Get environment
environment = client.environments.get(name="username/my-environment")

# List available tasks
tasks = await environment.list_tasks(split="train")

# Or fetch a single task by index
task = await environment.get_task(split="train", index=0)

# Or get a range of tasks by index (supports negative indices and None)
# Task ordering is consistent across calls, so ranges are safe to partition
tasks = await environment.get_task_range(split="train", start=0, stop=10)

# Create session
async with environment.session(task=tasks[0]) as session:
    # Get task prompt
    prompt = await session.get_prompt()

    # Call tools
    result = await session.call_tool("bash", {"command": "ls"})

    # Environment returns results directly
    print(result)
```

### 4. Automatic Scaling

Environments automatically scale based on concurrent sessions. Autoscaling settings are configurable when making the environment and can be changed in the environment settings page.

**Benefits:**

* Pay only for active usage
* No manual scaling needed
* Always ready when agents connect

### 5. Updates

Pushing to the connected GitHub repository will automatically build and deploy a new version of the environment.

**Via GitHub (automatic):**

```text theme={null}
1. Push new code to GitHub
   ↓
2. OpenReward detects changes
   ↓
3. Builds new version
   ↓
4. Deploys the new version of the environment server
```

## Sessions

A **session** is a durable, stateful connection between an agent and your environment:

* **Unique**: Each session has a unique ID, this is internally used to make sure you're connecting to the correct environment server.
* **Stateful**: Environment can maintain state between tool calls
* **Time-limited**: Sessions expire after inactivity or when the session is deleted.
* **Sticky**: Session stays connected to the same server instance

### Using Sessions

When creating a session, you can pass a task object directly or reference a task by its split and index:

```python theme={null}
# Using a task object
async with environment.session(task=tasks[0]) as session:
    ...

# Using split and index
async with environment.session(split="train", index=0) as session:
    ...
```

Using split and index avoids fetching the full task list. See the [ways to access tasks](/environments/ways-to-access-tasks) guide for more detail.

**Python SDK:**

```python theme={null}
# Create session with context manager (automatic cleanup)
with environment.session(task=task) as session:
    # Get initial prompt
    prompt = session.get_prompt()

    # Call tools multiple times
    result1 = session.call_tool("read_file", {"path": "README.md"})
    result2 = session.call_tool("bash", {"command": "python test.py"})

    # Session automatically cleaned up on exit
```

**Session lifecycle:**

```text theme={null}
1. Agent creates session → Connected to environment
2. Agent calls tools → Results returned directly
3. Context manager exits → Session automatically cleaned up
```

Sessions are **episodes** in the reinforcement learning sense - they persist across multiple tool calls until the caller breaks out of the session.

In ORS, a tool result with `finished=True` signals that the episode is complete and the agent should end the session. It is the caller's responsibility to check the `finished` flag and break out of the loop accordingly.

### Tool Calling

In ORS, the only way agents interact with environments is by calling tools. This leverages existing function calling support from LLM providers, creating a natural action space for language model agents. It also enforces a clean boundary between agent and environment - environments make no assumptions about the agent interacting with them, which keeps them robust to changes in how agents are built.

**Example tool call:**

```python theme={null}
result = session.call_tool(
    tool_name="bash",
    input={"command": "ls -la"}
)

# Result returned directly from environment
print(result.blocks)       # Tool output (list of TextBlock/ImageBlock)
print(result.finished)     # Task completion status
print(result.reward)       # Performance feedback
```

**Tool results structure:**

* `blocks`: The tool's return value (list of TextBlock/ImageBlock)
* `metadata`: Optional metadata dictionary
* `finished`: Whether the task is complete
* `reward`: Numeric feedback signal

## Storage

### Cloud Storage Integration

Each environment includes cloud storage accessible at `/orwd_data/`:

**Usage in environment server:**

```python theme={null}
from pathlib import Path

# Storage mounted at /orwd_data/
storage = Path("/orwd_data")

# Read dataset
with open(storage / "datasets" / "train.csv") as f:
    data = f.read()

# Write results
with open(storage / "results" / "metrics.json", "w") as f:
    json.dump(metrics, f)
```

Data in `/orwd_data/` can also be made accessible to sandboxes, depending on how you configure the mount.

See [where environment data lives](/environments/where-environment-data-lives) for a conceptual overview, and [Storage & Buckets](/storage/buckets) for lower-level configuration.

## Next Steps

<CardGroup cols={2}>
  <Card title="Your First Environment" icon="rocket" href="/environments/your-first-environment">
    Build and deploy your first environment
  </Card>

  <Card title="Sandboxes" icon="cube" href="/concepts/sandboxes">
    Add isolated code execution to your environment
  </Card>

  <Card title="GitHub Deployment" icon="github" href="/deployment/github-integration">
    Set up automatic deployments from GitHub
  </Card>

  <Card title="Storage & Buckets" icon="database" href="/storage/buckets">
    Configure persistent storage for your environment
  </Card>
</CardGroup>
