Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a162fc7
feat: import OSWorld LibreOffice tasks as computer-use environments
Aling33 Oct 13, 2026
b3a62a0
fix(osworld): bound the office readers, follow the docx main-part rel…
abhishekgahlot2 Oct 14, 2026
dcdf42b
fix(osworld): a rule that holds once an empty sheet is added is a gua…
abhishekgahlot2 Oct 14, 2026
0a5ca24
fix(osworld): run on a LibreOffice snapshot and fail setup when the d…
abhishekgahlot2 Oct 14, 2026
1c584fb
feat(osworld): ship a reference episode for every imported task
abhishekgahlot2 Oct 14, 2026
9786977
fix(osworld): write OSWorld's license and a NOTICE next to the genera…
abhishekgahlot2 Oct 14, 2026
c385c15
fix(check): computer-use folders need reference_actions.json, and no …
abhishekgahlot2 Oct 14, 2026
9dc521e
docs: OSWorld importer section and changelog entry
abhishekgahlot2 Oct 14, 2026
925df49
fix(osworld): a saved file the readers can't read is a judged 0, neve…
abhishekgahlot2 Oct 14, 2026
1d019a3
fix(osworld): judge the saved file in a time- and memory-bounded chil…
abhishekgahlot2 Oct 14, 2026
15ee318
fix(osworld): kill and reap the judging child whenever the parent sto…
abhishekgahlot2 Oct 14, 2026
6608a08
docs: describe the bounded OSWorld verifier
abhishekgahlot2 Oct 14, 2026
4992524
fix(osworld): read the workbook the package names, apply the 1904 epo…
abhishekgahlot2 Oct 14, 2026
a85f103
fix(osworld): tell dates, times and durations apart, and refuse workb…
abhishekgahlot2 Oct 14, 2026
3a87421
fix(osworld): classify formats as openpyxl does, refuse duplicate dec…
abhishekgahlot2 Oct 14, 2026
14e235c
fix(api): refuse a caller-chosen snapshot in session requests, as an …
abhishekgahlot2 Oct 14, 2026
bd0d6b0
fix(osworld): treat packages openpyxl or python-docx can't open as un…
abhishekgahlot2 Oct 14, 2026
c7953ab
fix(osworld): type numbers and columns as openpyxl and pandas do, and…
abhishekgahlot2 Oct 14, 2026
d4b9812
fix(osworld): a cell naming a missing shared string makes the workboo…
abhishekgahlot2 Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions deepgym/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- **OSWorld computer-use tasks:** `scripts/import_osworld.py` imports 16 of OSWorld's (Apache-2.0) LibreOffice Calc and Writer tasks as computer-use environments, each with a reference episode, and writes OSWorld's license and a NOTICE next to them. They boot the Daytona snapshot `deepgym-osworld-libreoffice` (`--build-snapshot` creates it), since Daytona's default image has no LibreOffice; `metadata.json` takes a `snapshot`. The verifier scores the saved file with the task's own `compare_table` rules (ported into the shared `_checks.py`, standard library only) or its reference text, never a screenshot. Rules the starting file already holds, or holds once an empty sheet is added, are guards, so an untouched file or a blank sheet scores 0; a saved file the readers can't read (missing, corrupt, not a regular file, too large) scores 0, and reading and scoring run in a time- and memory-limited child whose failure also scores 0, so nothing in the file can crash or stall the verifier. `deepgym check` asks a computer-use folder for `reference_actions.json` instead of `reference_solution.*`, and is inconclusive on one off Daytona.

## 0.5.0 (2026-10-14)

- **Sessions: no verdict only for failures that are ours for certain.** Once the agent has acted, a failure is its judged 0 (`policy_sandbox_failure`) unless it is ours for certain: a network, provider or auth failure (HTTP 401 and 403 now count as infrastructure in `is_infrastructure_failure`), a verifier that couldn't run (its upload or launch failed) or timed out before it read the agent's output, an interrupt, or E2B or Modal retiring the sandbox at the end of its one-hour lifetime (new `SandboxExpiredError`, before a `SandboxDiedError`) unless the agent's own actions took at least half the session's time. A failure the rule can't read is the agent's 0. The rule is `deepgym.session.failure_result`, which verl's `deepgym_agent` loop and Harbor's agent phase also use; before, a 401 uploading verifier code or a verl final verifier that timed out before reading anything scored 0, and a Harbor agent that replaced its work directory with a link, grew it past the archive cap, made packing outrun its deadline, killed its sandbox or spent most of the provider lifetime in its script got no verdict; in Harbor any failure once the agent's script has started is now its 0 unless it is ours for certain. Session verifiers now get the consulted mark single runs use, embedded in the verifier's own script rather than on a command line: a step or final verifier that times out after reading the agent's output (a FIFO it left, say) is a judged 0 with `solution_timeout` (for a step, its reward, and the episode goes on), and so is a verifier that is killed, or gives no verdict, after reading it (`solution_error`), unless the agent's code failed to launch. Each verifier also prints a start line first, so a timeout whose output the provider lost is a judged 0 rather than passing for one that never read anything. Listing the agent's folder, or starting a program in it or on one of its files, now counts as reading its output, and the mark is written to the stdout file itself, so capturing `sys.stdout` can't hide it, and cut from what the verifier printed exactly, so a line it fell inside reads whole. Daytona enforces command deadlines in the sandbox, so a timed-out command keeps what it printed. A FIFO the agent leaves where the harness writes is refused at once instead of hanging the write, the local backend shows output that isn't UTF-8 instead of ending the episode, and E2B, Daytona and Docker/Apple uploads to a stopped sandbox raise `SandboxDiedError`. `deepgym_solution.run_solution` prints the consulted mark before it releases the solution, so a solution that dies the moment it starts can't pass for one that never ran.
Expand Down
4 changes: 2 additions & 2 deletions deepgym/docs/api-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ request per output; they don't call `/v1/run/batch` or `/v1/eval`.
Registering an environment takes the same fields as an inline run. An invalid environment
is a 422 before anything is queued. Environments sent to the run, batch, job and
environment endpoints have no `image` or `snapshot` field, and one sent anyway is
dropped. A session request whose inline environment sets an `image` gets 422; a
`snapshot` is accepted.
dropped. A session request whose inline environment sets an `image` or a `snapshot`
gets 422.

## Limits

Expand Down
36 changes: 34 additions & 2 deletions deepgym/docs/environments/importers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

This page covers the public benchmarks DeepGym can load or import: the code benchmarks
(HumanEval, MBPP, EvalPlus, BigCodeBench), repo-level patch tasks (SWE-bench Pro, MiMo),
shell tasks (Terminal-Bench 2.0 and any Harbor dataset), CyberGym, mixing benchmarks
behind one reward function, and sharing environments on the Hugging Face Hub.
shell tasks (Terminal-Bench 2.0 and any Harbor dataset), CyberGym, OSWorld desktop
tasks, mixing benchmarks behind one reward function, and sharing environments on the
Hugging Face Hub.

## Code benchmarks

Expand Down Expand Up @@ -283,6 +284,37 @@ TRL, verl or OpenRLHF. Keep training and evaluation splits separate, use a sandb
untrusted completions, and don't train on metadata-only scores. See
[CyberBench](../cyberbench.md) for the full workflow and diagnostic numbers.

## OSWorld desktop tasks

`scripts/import_osworld.py` imports 16 LibreOffice Calc and Writer tasks from
[OSWorld](https://github.com/xlang-ai/OSWorld) (Apache-2.0) as
[computer-use](computer-use.md) environments. The agent gets the task's file open in
Calc or Writer and saves it with Ctrl+S. The verifier scores the saved file with the
task's own `compare_table` rules or reference text, never the screen.

The desktop needs LibreOffice, which Daytona's default image doesn't have, so the
environments boot the Daytona snapshot `deepgym-osworld-libreoffice`. Create it once
per Daytona account, then import:

```bash
python scripts/import_osworld.py --build-snapshot # needs DAYTONA_API_KEY
python scripts/import_osworld.py # writes ~/.deepgym/environments/osworld/
deepgym qa --mode daytona ~/.deepgym/environments/osworld/<task id>
```

- A rule the starting file already holds, or holds once an empty sheet is added, is a
guard rather than progress, so saving the untouched file or adding a blank sheet
earns nothing. OSWorld's evaluator is all-or-nothing; here a task with several rules
pays the share it got right.
- Whatever is at the result path, the verifier gives a verdict: a file it can't read
(missing, corrupt, not a regular file, or past the size limits) scores 0, and a rule
it can't evaluate fails every rule. Reading and scoring run in a child process with
a 20 s and 1 GiB limit; a child that fails or overruns scores 0, never a timeout.
- Each task ships a reference episode, `reference_actions.json`, that `deepgym qa`
replays.
- The output folder keeps OSWorld's `LICENSE` and a `NOTICE` that lists what was
changed.

## Mix benchmarks behind one reward function

```python
Expand Down
2 changes: 1 addition & 1 deletion deepgym/docs/environments/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ DELETE /v1/sessions/{id}
```

- `environment` can also be an inline `MultiTurnEnvironment` spec; the API refuses one
that sets an `image` (a `snapshot` is accepted).
that sets an `image` or a `snapshot`.
- At most 100 sessions run at once (429 above). Sessions idle for 30 minutes are closed
by a sweep that runs every 60 seconds, and the server tries to close every session on
shutdown.
Expand Down
Loading
Loading