Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion deepgym/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Unreleased
## 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.
- **QA gate:** multi-turn and computer-use envs with a `reference_actions.json` are checked: the reference replays at full marks every time, and agents that quit at once (`empty_fails`), use every action (`busy_fails`) or act at random (`random_fails`) must earn nothing. The computer-use built-ins ship their reference episodes (one per variant) and run on `--mode daytona`. Negative controls (empty, stub, idle agents) fail on any reward, not just full marks; attacks define the env's real entry point; reports list the checks that `ran`. `difficulty` is reported, never gated: it gives mean and spread of rewards and flags `too_easy`, `too_hard` and `no_variance` (partial rewards count as variance), retries 429s, timeouts and 5xx with backoff, and is inconclusive rather than aborting when the endpoint stays down. Missing verdicts never pass: incomplete black-box scans are `inconclusive` and never saved as ROBUST, an audit that judged nothing has no risk rating (`status` says why), and RL exploit discovery reports suspected exploits with their signs from every round instead of a genuineness verdict. The exploit DB keys results by benchmark, verifier and attack mode (legacy tables are rebuilt in place), reuses one only for the same verifier contents and attack setup, and summaries filter by benchmark and mode. Reports and approvals are written atomically, and attack payloads carry JSON test values as valid Python. Built-ins: `data_pipeline` and `web_path_traversal_toy` no longer pay for an empty answer, and `anagram_check`, `palindrome_check` and `valid_parentheses` score balanced recall on real booleans, so a constant answer earns nothing. Breaking: `ExploitDB.get` needs `benchmark=`, `DiscoveryReport` replaces `is_genuine_solution`/`exploit_discovered` with `suspected_exploits`/`exploit_suspected`, and `VerifierAuditReport.risk_score`/`risk_level` are None when inconclusive.
Expand Down
6 changes: 3 additions & 3 deletions deepgym/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ build-backend = "hatchling.build"

[project]
name = "deepgym"
version = "0.4.2"
description = "RL training environments with verifiable rewards for coding agents"
version = "0.5.0"
description = "RL training environments with verifiable rewards for coding and computer-use agents"
readme = "README.md"
license = {text = "PolyForm-Noncommercial-1.0.0"}
requires-python = ">=3.10"
Expand Down Expand Up @@ -45,7 +45,7 @@ all = ["daytona>=0.223", "modal>=1.6", "e2b>=2.55", "fastapi>=0.100", "uvicorn[s
[project.urls]
Homepage = "https://deepgym.io"
Repository = "https://github.com/DeepGym/deepgym"
Documentation = "https://github.com/DeepGym/deepgym#readme"
Documentation = "https://deepgym.io/docs"
Issues = "https://github.com/DeepGym/deepgym/issues"

[project.scripts]
Expand Down
2 changes: 1 addition & 1 deletion deepgym/src/deepgym/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""DeepGym — Managed RL training and evaluation infrastructure."""

__version__ = '0.4.2'
__version__ = '0.5.0'

from deepgym.async_core import AsyncDeepGym
from deepgym.benchmark_envs import (
Expand Down
Loading