Skip to content

Agents

An agent is anything that drives a RepoEnv to done.

from repogym import Agent, Submit

class MyAgent(Agent):
    name = "my-agent"

    def solve(self, env, obs):
        while not obs.done:
            action = my_model(obs.text)   # returns an Action or a dict
            obs = env.step(action)
        return obs

Agent.run(env) resets the environment, calls solve, and auto-submits if the agent returned without submitting.

Built-in agents

Spec (CLI --agent) Class What it does
golden GoldenAgent applies the task's solution and submits; the upper bound
noop NoopAgent submits immediately; the lower bound (must score 0)
ScriptedAgent(actions) replays a fixed action list (tests, trajectory replay)
FunctionAgent(fn) wraps fn(env, obs) -> obs
shell:<command> ShellAgent runs an external CLI in the workspace, then submits
claude[:model] ClaudeAgent Anthropic Messages API tool loop
pkg.module:ClassName your class imported and instantiated with no arguments

External CLIs with ShellAgent

The command runs with the workspace as the current directory. {prompt} is replaced by the shell-quoted problem statement (the same text the environment shows), and these variables are set:

Variable Value
REPOGYM_TASK_ID task id
REPOGYM_PROBLEM full initial observation
REPOGYM_WORKSPACE absolute workspace path
repogym run tasks --agent "shell:claude -p {prompt} --allowedTools Edit,Write,Bash"
repogym run tasks --agent "shell:aider --message {prompt} --yes --no-git"
repogym run tasks --agent "shell:codex exec {prompt}"
repogym run tasks --agent "shell:python my_agent.py"

The CLI's combined stdout/stderr is stored as a single external step in the trajectory. Unlike the environment's run action, ShellAgent inherits your full environment (API keys included) so the external tool can authenticate.

ClaudeAgent

python -m pip install "repogym[anthropic] @ git+https://github.com/shi1720/repogym.git"
export ANTHROPIC_API_KEY=...
repogym run tasks --agent claude --record trajectories
repogym run tasks --agent claude:claude-sonnet-5
from repogym.agents.claude import ClaudeAgent
agent = ClaudeAgent(model="claude-opus-5", max_turns=40, effort="high")

The agent exposes the environment's actions as tools (read_file, write_file, edit_file, run_command, run_tests, list_files, submit), uses adaptive thinking, caches the system prompt, and returns malformed tool calls to the model as is_error results. Token usage is accumulated on agent.usage.

Running many episodes

from repogym import load_tasks, run_suite

results = run_suite(load_tasks("tasks"), lambda: MyAgent(), workers=4,
                    record_dir="trajectories")
for r in results:
    print(r.task_id, r.score, r.passed, r.steps, r.error)

run_suite calls the factory once per task so stateful agents never share conversation state. Exceptions inside an agent are captured in RunResult.error rather than aborting the suite.