Rewards & tools
This page answers two questions an RL or agent researcher actually has: what can the agent do inside an environment, and how do we score it? Tools are the actions; rewards are the signal.
Act, then score (click a node for source)
Tools — the action space
Every server ships the tools plugin, available on all images:
| Tool | Endpoint | What it does |
|---|---|---|
| Bash | POST /api/tools/bash | Run a bash script; returns bounded stdout/stderr and the exit code |
| Create file | POST /api/tools/file/create | Create a file with given content |
| Edit file | POST /api/tools/file/edit | Replace a 1-indexed, inclusive line range |
| Patch file | POST /api/tools/file/patch | Apply a unified diff |
| Upload chunk | POST /api/tools/file/upload | Write one base64 chunk of raw bytes at an offset |
| Download chunk | POST /api/tools/file/download | Read one base64 chunk of raw bytes from an offset |
The three text file tools are also exposed as MCP tools (create_file, edit_file,
patch_file) on the server's /mcp endpoint. With a JetBrains IDE plugin installed, an
inspect endpoint runs the full IntelliJ static-analysis pipeline, and mcp-steroid
exposes the IntelliJ Platform API (PSI, refactoring, debugger, VCS) as MCP tools. See the
tools reference.
The Bash tool retains 1 MiB by default for each of stdout and stderr, split between the
beginning and end of each stream. Callers can choose another positive byte limit or request
complete output with max_output_bytes=None. A short marker reports omitted bytes when a
stream is truncated; the marker itself is outside the per-stream limit. Output is still
drained until completion or the execution timeout, preventing subprocess pipe deadlocks.
The two chunk endpoints are the binary channel. The orchestrator stores and replays a
forwarded request as JSON text, so raw bytes cannot survive that round trip and base64 is what
does. The client wraps them in upload_file / upload_bytes / download_file /
download_bytes, which chunk the payload for you — use these rather than base64 through the
bash tool, which is bounded by the size of a single shell script and puts the payload in the
command log.
result = await server.execute_bash("python -m pytest -q")
await server.patch_file("/home/devuser/project/main.py", patch="--- ...")
await server.upload_file("./fixtures/repo.tar.gz", "/home/devuser/repo.tar.gz")
Rewards — the evaluation signal
Three reward kinds turn the environment's state into a number an RL loop can train on. Each runs a script inside the sandbox and returns a structured result.
| Reward | Call | Result |
|---|---|---|
| Compilation | server.compilation_reward(compilation_script=...) | .success (bool) |
| Setup | server.setup_reward(setup_check_script=...) | .success (bool) |
| Test | server.test_reward(test_script=...) | .passed, .failed, .output |
result = await server.test_reward(test_script="cd /project && python -m pytest -q")
score = result.passed / (result.passed + result.failed)
Because the orchestrator persists every forwarded request and response, rewards can also be recomputed offline from stored runs — making evaluation reproducible.
How an episode uses both
A typical RL episode: start_server with reuse_strategy=RESET → the agent acts via
tools → call a reward → release the server for reuse. The full sequence is on the
data flow page.
View source
- Tool service & file ops →
tools/src/idegym/tools/ - Reward checkers →
rewards/src/idegym/rewards/ - Full reference → Tools docs · Client rewards