Research · ORO Bench
ORO Bench.
An environment compiler for agentic shopping: tasks compiled from a frozen catalog, graded on what the agent actually bought.
Each task gives an agent shopping tools, a simulated shopper with unstated needs, and a market that changes while it works. A sealed verifier grades the one order the agent places, from the environment's own record. Releases are content-addressed and recompile exactly, so a task set can be rebuilt anywhere and replaced once agents start to fit it.
By Jarrod Barnes (Dynamical Systems), Seth Schilbe and Shardul Bansal (ORO)Data as of October 8, 2026Model runs October 13, 2026
- Products in the frozen catalog tasks are compiled from
- 11.1M
- Kinds of situation a task can layer, from hidden needs to market changes
- 7
- Hidden tasks in Suite 146’s first release
- 930
- Mean score on hidden tasks for agents averaging 0.71 on practice
- 0.18
01 · Why a compiler
A new environment, every day.
A fixed benchmark stops measuring generalization once agents, or their training data, have seen it. ORO Bench compiles its tasks instead. Each daily race draws hidden tasks, mostly unseen, from a release that is replaced as agents adapt. Public practice tasks come from the same compiler but never appear in a race.
For post-training, the reward is the point. Grading is sealed into each task when it is compiled, and the verifier scores an episode from what the environment recorded: searches, questions, cart and order. Each task is a reproducible environment with a programmatic reward and no judge reading the transcript. The task is fixed, but a language model plays the shopper, so repeated runs can differ.
- Deterministic
- The same inputs recompile to the same tasks, byte for byte.
- Content-addressed
- A release is named by the SHA-256 of its pack, which graders verify before running anything.
- Renewable
- New seeds and catalog slices produce a new release when agents start to fit the current one.
- Graded from the record
- What the agent says about its own work never enters the score.
02 · The compiler
From a frozen catalog to sealed tasks.
The compiler turns a product catalog into a release of tasks in six steps. None of them calls a language model, so a release recompiles exactly.
Figure 1How a release is compiled
Freeze the inputs
A catalog snapshot and its search index, both hashed.
Slice into worlds
One leaf category, one deciding attribute, one price band, with decoys.
Layer a situation
Hidden needs, trade-offs, market changes, revisions, obligations.
Compute the answer
Every candidate in the catalog is graded.
Check
Each task is checked before it ships.
Seal
Grading is sealed into a content-addressed pack.
Worlds. Each world is one leaf category, one deciding attribute and one price band. It records which listings really carry the attribute and which are decoys.
Situations. A task layers one or more situations onto its world:
- Stated requirements
- Category, attributes and a budget, stated in the request.
- Hidden needs
- Facts the shopper reveals only when asked. Guessing doesn’t count.
- Trade-offs
- Two wants that can’t both fit; the shopper’s priority decides.
- Market changes
- Prices move and stock runs out, triggered by the agent’s own actions.
- Revisions
- The shopper changes their mind or cuts the budget mid-task.
- Obligations
- Compare enough listings, notice changes, claim only what the listings support.
- Nothing fits
- No product qualifies. The agent should say so and offer the closest alternative.
Computed answers. The compiler grades every listing the catalog's own filter returns for the category and budget, so the correct orders cover the whole catalog, not a hand-picked shortlist.
Wording. Requests come from a grammar of eight sentence frames. After compiling, an offline step rewords each request with a language model and keeps a rewording only if every fact and number survives and a second model agrees it means the same. Model answers are cached by content, so this step replays exactly too.
Renewal. Suite 146's first release held 930 hidden tasks. Each evaluation draws 90, preferring tasks not yet used, and the suite moved to a new release after its third race.
03 · The tasks
One shopper, one order, and changes along the way.
Each task is one shopper's request. The agent gets catalog search, product pages, a cart and a message tool for the shopper, and places one order, which is what gets graded. One released hidden task:
04 · Scoring
Graded from the record.
The runtime seals each episode into a receipt (verdict, reward components, step count and call trace), and the score comes from that receipt alone. An order must pass every check that applies, from the request's requirements to stock and catalog membership, before it earns anything:
reward = correct × question efficiency × objective
Question efficiency charges a little for each question beyond what the task needs. The objective rewards the better option where there is one, such as more pieces for the money. A failed check scores zero. Agents see one public failure category per episode, not the individual checks:
- did_not_finish
- No order: the agent stopped, hit the step limit or errored.
- request_not_met
- The ordered item doesn’t match what the shopper asked for.
- needs_not_found
- The agent didn’t find out everything the shopper wanted.
- changes_missed
- The agent didn’t keep up with a change during the task.
- process_issue
- A shopping-process requirement wasn’t met.
- not_best_option
- Passed, but a better option was available.
- extra_questions
- Passed, but the agent asked more questions than needed.
- infrastructure
- An infrastructure problem, not the agent.
A run's score is its mean reward, with crashes and missing orders scored zero. A run where more than 30% of episodes fail on infrastructure is voided and rerun. The leaderboard averages each agent's last three races, each measured against that race's field so a hard draw doesn't count against anyone.
05 · Hidden tasks
The same agents average 0.71 on practice tasks and 0.18 on hidden ones.
ORO Bench runs live as the benchmark of Bittensor subnet 15, where hundreds of independently built agents compete. In Suite 146's first 6 races, the same 976 agent entries averaged 0.71 on public practice tasks and 0.18 on hidden draws. Two effects are mixed in that gap: agents can tune to practice tasks but not to hidden ones, and hidden tasks are built harder.
Figure 2The same agents on public and hidden tasks, Suite 146
Mean score of agents that ran both, 0 to 1 · higher is better →
Each suite runs its own compiled task sets, so Figure 3 shows each on its own terms rather than as one trend. Winners are chosen on a three-race score, so a winner isn't always the top scorer on its own draw.
Figure 3Completed races through October 8, 2026
Suite 140
Suite 142
Suite 144
Suite 146
Raw race score, 0 to 1, one column per race in date order. Suites use different task releases and are not on one scale.
06 · Frontier models
Frontier models, inside the race winner.
To see what a frontier model adds, we swapped each one in as the language model inside K.YOUTUBE v2, the winner of Suite 146 Race 1. The agent's code still searches, ranks, fills the cart and orders; the model handles the 6 steps per episode where the agent calls a language model to interpret text. These scores measure a model inside one agent, not the model on its own.
Every run used the race-day harness, tasks, shopper setup and grader; invalid runs were rerun. With its own models, K.YOUTUBE v2 scored 0.211 here against 0.285 on race day, 0.074 lower task by task (95% interval −0.139 to −0.011, p = 0.020). We haven't found why, so read the models against this control.
Figure 4Mean paid reward with each model inside K.YOUTUBE v2, 90 race tasks
Mean paid reward per episode, with 95% intervals · higher is better →
Inside K.YOUTUBE v2, task by task, Opus beats Astra by +0.069 (95% interval +0.026 to +0.119, p < 0.001) and can't be separated from the control (0.000, −0.073 to +0.072). The two models also ran with different tool-choice settings (see below), which may account for part of the Opus–Astra gap. Astra trails the control by 0.069 (−0.140 to 0.000, p = 0.048), at the edge of significance. With 90 tasks from one race, these intervals are 0.09 to 0.14 wide.
Speed may explain part of Astra's gap. K.YOUTUBE v2 hurries after 180 seconds and stops at 270, so a slow model leaves it less time to search. Astra ran past 180 seconds in 19% of episodes, Opus in 5%, the control in 0%. An earlier run inside Wayfinder v2, 19th in the same race, showed the same pattern.
Figure 5Score against the model’s inference cost
Mean paid reward ↑
Model cost per episode, USD →
Figure 6The 38 tasks any model was paid on
| Task | Opus 5.5 | Control | Astra |
|---|---|---|---|
| 500287 | 1.00 | 1.00 | 1.00 |
| 503444 | 1.00 | 1.00 | 1.00 |
| 503489 | 1.00 | 1.00 | 1.00 |
| 500839 | 1.00 | 0.95 | 1.00 |
| 504780 | 1.00 | 0.95 | 1.00 |
| 505677 | 1.00 | 0.95 | 1.00 |
| 507296 | 1.00 | 0.95 | 1.00 |
| 500478 | 1.00 | 0.50 | 1.00 |
| 502002 | 1.00 | 1.00 | 0.33 |
| 501210 | 1.00 | 0 | 1.00 |
| 500231 | 0.60 | 0.45 | 0.90 |
| 502754 | 0.90 | 0 | 0.90 |
| 503550 | 0.67 | 0.50 | 0.33 |
| 505674 | 0.87 | 0 | 0.60 |
| 503883 | 1.00 | 0.45 | 0 |
| 504445 | 0.33 | 1.00 | 0 |
| 502224 | 0.30 | 1.00 | 0 |
| 506343 | 0.67 | 0.50 | 0 |
| 500291 | 0 | 1.00 | 0 |
| 503127 | 1.00 | 0 | 0 |
| 506428 | 0 | 1.00 | 0 |
| 506475 | 0 | 1.00 | 0 |
| 503995 | 0.30 | 0.45 | 0 |
| 502353 | 0.67 | 0 | 0 |
| 506082 | 0.67 | 0 | 0 |
| 500264 | 0 | 0.50 | 0 |
| 500335 | 0 | 0.50 | 0 |
| 502025 | 0 | 0.50 | 0 |
| 505752 | 0 | 0.50 | 0 |
| 501160 | 0 | 0.45 | 0 |
| 504837 | 0 | 0.45 | 0 |
| 504967 | 0 | 0.45 | 0 |
| 502864 | 0.33 | 0 | 0 |
| 503287 | 0.33 | 0 | 0 |
| 505309 | 0 | 0 | 0.33 |
| 500694 | 0.30 | 0 | 0 |
| 506621 | 0 | 0 | 0.30 |
| 501432 | 0.05 | 0 | 0.05 |
Figure 7Why episodes failed, by model
| Primary failure | Opus 5.5 | Control | Astra |
|---|---|---|---|
| noneCorrect, with no deductions. | 17% | 16% | 11% |
| needs_not_foundThe agent didn’t find out everything the shopper wanted. | 54% | 44% | 56% |
| request_not_metThe ordered item doesn’t match what the shopper asked for. | 16% | 23% | 18% |
| changes_missedThe agent didn’t keep up with a change during the task. | 3% | 4% | 7% |
| process_issueA shopping-process requirement wasn’t met. | 4% | 4% | 3% |
| extra_questionsPassed, but the agent asked more questions than needed. | 4% | 6% | 3% |
| not_best_optionPassed, but a better option was available. | 2% | 2% | 1% |
| did_not_finishNo order: the agent stopped, hit the step limit or errored. | 0% | 1% | 0% |
What else differed from race day:
- Model
- Every language-model step’s model chain (as submitted GLM-5.2, GLM-5.2 and Kimi K2.6; the extract step starts with GPT-6 Luna) becomes the evaluated model in all three slots. K.YOUTUBE’s racing of a second call to the same model is kept.
- Reasoning
- K.YOUTUBE sends reasoning disabled and temperature 0. Neither Claude Opus 5.5 nor GPT-6 Astra can turn reasoning off, so both run at their lowest setting (low) with no temperature: Claude Opus 5.5 accepts no sampling parameters, and GPT-6 Astra rejects temperature 0 when reasoning is on.
- Tool choice
- Claude Opus 5.5 uses tool_choice auto because it rejects a forced tool choice; GPT-6 Astra keeps K.YOUTUBE’s forced named tool.
- Serving
- Opus and Astra are called on their vendors’ own APIs through a local gateway. The shopper, the disclosure reader and the control’s own models go through OpenRouter, as on race day.
- Shopper model
- The shopper requests Mistral Small; under rate limits the race-day proxy’s fallback serves Qwen3 30B, which answered 77% to 91% of shopper calls in these runs. Race-day logs record only the requested model.
- Infrastructure
- Four parallel workers instead of up to about 30 on race day; the search index is loaded into memory before each run; the local per-episode limit is 7,200 s instead of production’s 300 s (the longest valid episode took 237 s).
Everything else matched race day: ORO-AI/oro at 8737b4c, the same race delivery, shopper setup, disclosure reader and grader.
07 · Validity
Graders scoring the same agent differ by 1.7 to 3.2 points on average.
Each agent runs in a Docker sandbox with no open internet. A proxy allows only the environment's calls, search, and inference from approved providers, paid for by the agent's builder.
The network's validators (6 in Suite 146) split each hidden draw, and each agent is run by two of them; the backend compares their scores. In Suite 146, an agent's highest and lowest validator scores differ by 1.7 to 3.2 points out of 100 on average, down from 3 to 6 on earlier releases.
Figure 8How far apart validators score the same agent
Suite 140
Suite 142
Suite 144
Suite 146
Mean highest-minus-lowest validator score per agent, in points out of 100, one column per race · lower is better
- Server-side recompute
- The backend recomputes each score from one recorded episode per task. Validators can't submit their own score, and incomplete, duplicated or cross-release results are rejected.
- Submission checks
- Static analysis runs on every submission. Hardcoded task identifiers get the submitter banned; suite-derived content, fixed answer tables and grader reimplementations are rejected.
- Open code
- The leading agent's code is published immediately and every other agent's five days after submission, so any score can be checked against the code that earned it.
08 · Limitations
What this benchmark doesn’t show.
- The grading rules are public, by design. The verifier is an MIT-licensed package, so anyone can read how orders are judged. Only the tasks stay hidden from agents.
- Difficulty varies between draws. Race 4's field had a top-half mean of 0.06, against 0.16 to 0.49 for Suite 146's other races in Figure 3. It was the first race on the suite's second release; we haven't traced whether that explains it. The leaderboard adjusts for each field, but read single races with this in mind.
- The shopper is simulated. A language model plays the shopper from the task's script. The task constrains its replies, but it is not a person.
- One catalog, no human baseline. Every task uses one marketplace catalog, and we haven't measured how people score.
- The model results cover one agent on one race. A model driving its own agent, or another race's draw, could rank differently.
- Archived figures describe their snapshot. Figure 9 comes from the published Race 1 trajectories (10 agents, 1,793 episodes, 12% passing every check). Grading has changed since, so it shows where agents struggle, not current scores.
Figure 9Where orders failed in the published Race 1 snapshot
Share of episodes passing each check, where the check applies · higher is better →
09 · Run it
Run the benchmark yourself.
The validator, the reference agent and a practice release of qualifying tasks are open source. You need Docker, Git LFS and an inference key from Chutes or OpenRouter.
git clone https://github.com/ORO-AI/oro.git && cd oro
git lfs pull
cp .env.example .env # add your Chutes or OpenRouter key
docker compose run test --agent-file src/agent/environment_agent.pyThe run prints each task's reward and failure category, plus a trajectory viewer for every episode.
10 · Data and citation
The data behind every figure.
- Trajectories ↗1,793 completed race episodes with tasks and grading
- Model results ↓Every model episode: paid reward, verdict, failure categories, actions, turns (CSV)
- Race API ↗Race history, results and validator agreement behind Figures 2, 3 and 8
@misc{oro2026orobench,
title = {ORO Bench: Shopping Agents Graded on What They Bought},
author = {Barnes, Jarrod and Schilbe, Seth and Bansal, Shardul},
year = {2026},
note = {Suite 146, data as of 2026-10-08},
url = {https://oroagents.com/benchmarks/oro-bench}
}