Skip to content

Custom Tasks and Scoring

rogue-arena-inspect launch runs a ready-made example task. To change the agent, its prompt, or its tools, write your own Inspect task. This page covers the parts specific to Rogue Arena. The package README has the full reference.

The example tasks ship inside the package: eval_example.py, team_example.py, team.yaml, and the eval-example.eval.yaml run config. To find them, run:

Terminal window
python -c "import importlib.resources as r; print(r.files('inspect_rogue_arena') / 'examples')"

Copy one out, edit it, and run it with --task:

Terminal window
rogue-arena-inspect launch --eval <id> --task my_task.py --model <provider>/<model>

Give the task the Rogue Arena sandbox and scorer:

from inspect_ai import Task, task
from inspect_ai.agent import react
from inspect_ai.dataset import Sample
from inspect_ai.util import SandboxEnvironmentSpec
from inspect_rogue_arena import RogueArenaSandboxConfig, rogue_arena_hops, rogue_bash
@task
def my_eval() -> Task:
return Task(
dataset=[Sample(input="...your objective...", target="scored by Rogue Arena")],
solver=react(tools=[rogue_bash()]),
scorer=rogue_arena_hops(),
sandbox=SandboxEnvironmentSpec(
"rogue-arena", RogueArenaSandboxConfig(eval="<id>")
),
)

rogue_bash() is the shell tool the examples use. It tells the model its default timeout and runs long commands in the background, so a slow command finishes and a brief network error doesn’t end the run.

Each sample in the dataset gets its own trial, on its own copy of the range.

Set these in RogueArenaSandboxConfig, or with the environment variable. Settings in the task win over environment variables.

SettingEnvironment variableDefaultWhat it does
evalROGUE_ARENA_EVALrequiredThe eval ID, or a name that matches exactly one eval.
concurrencyROGUE_ARENA_CONCURRENCY2The most trials running at once. Each one holds a deployment slot.
max_trialsROGUE_ARENA_MAX_TRIALS10000The most trials the run can start. Set it to at least samples × epochs, plus retries.
max_runtime_secondsROGUE_ARENA_MAX_RUNTIME_SECONDS3600Each trial’s time limit, counted from the claim, including build time. From 60 to 86400.
max_wait_secondsROGUE_ARENA_MAX_WAIT_SECONDS900How long a trial may take to become ready.

If you set concurrency in a task, pass the same number to inspect eval as --max-sandboxes. The README lists the remaining settings.

The scorer closes the trial and reads the score Rogue Arena returns. It never checks a hop itself.

  • Value: hops passed divided by total hops, counted under the eval’s scoring mode. The answer reads like 2/4 hops.
  • Metadata: trial_id, hops_passed, hops_total, reached_step, scoring_mode, outcome, terminal_reason, timed_out and per_hop.

per_hop.passed is each hop’s raw check result, not whether the hop counted. In sequential mode, a hop after the first failed step doesn’t count even if its check passed. Use hops_passed and reached_step for the count.

How the trial endedResult
The agent finished or gave upScored.
It ran out of timeScored normally, with timed_out: true.
An infrastructure error, a cancel, or no scoreNot scored. The sample errors and stays out of the average.

By default, Inspect stops the whole run on the first sample error. To keep going, pass --no-fail-on-error, or a threshold such as --fail-on-error 0.1. --retry-on-error N starts a fresh trial for each retry, so leave room in max_trials.

RogueArenaClient covers the whole eval API, for scripts that don’t use Inspect:

import asyncio
from inspect_rogue_arena import RogueArenaClient
async def show_evals() -> None:
client = RogueArenaClient.from_env()
for entry in await client.list_evals():
print(entry.environment_id, entry.name, entry.hop_count, entry.scoring_mode.value)
asyncio.run(show_evals())

It reads ROGUE_ARENA_BASE_URL and ROGUE_ARENA_TOKEN from the environment. The README lists every method.