contract.yaml sits at the top of an agent’s directory. To write one step by step, see
Package an agent.
Fields
Valkyrie ignores keys it doesn’t recognize, so a misspelled field has no effect.
Order of a task
For each task, Valkyrie:- Copies the agent directory into the sandbox at
/bundle/AGENT_NAME/, whereAGENT_NAMEis the agent’s name in your library. - Runs
install_cmdfrom that directory, before or after the benchmark sets the task up, as the benchmark chooses. - Runs
run_cmdfrom the benchmark’s working directory, with placeholders filled in and secrets set as environment variables. - Saves
final_outputandoutput_artifacts, even when the agent fails. - Has the benchmark grade the sandbox.
The install_cmd field
- Runs with
sh -cin/bundle/AGENT_NAME/, with a 10-minute limit. - A failed installation is tried up to three more times, then once more in a new sandbox, before the task fails.
- Uploading leaves out
.git,.venv,venv, and__pycache__directories, and every file whose name contains.env,.git,venv,.pyc,.pyo,.pyd,.so,.dll,.dylib,.egg-info, or.DS_Store. Symbolic links are refused.
Placeholders
Valkyrie fills these inrun_cmd:
Values go in as they are, without shell quoting, so quote any that can contain spaces. A
placeholder with no value, such as a parameter with no default that the run didn’t set,
stays in the command as written.
Parameters
Parameters are values a run passes to the agent.--model sets the model parameter,
declared under defaults. -k NAME VALUE sets parameters declared under kwargs.
- A run that leaves out a required parameter fails to start, naming the parameter.
-kwith a name the contract doesn’t declare is ignored.- A
dictparameter can’t be set with-k, so give it adefault.
Secrets
secrets maps each environment variable to a secret reference that valkyrie secret set
printed:
contract.yaml
- Valkyrie reads each secret when it creates the task’s sandbox. Secret values are never saved with the run.
-s ENV_VAR SECRETonvalkyrie run startadds or replaces a mapping for that run.- When a secret’s value is a JSON object, each variable gets the key with its own name, so one secret can hold several keys.
The install_egress field
What the agent can reach while it installs:
- IPv6 addresses aren’t supported. On Daytona, one list can’t mix hostnames with CIDR ranges.
- The benchmark sets what the agent can reach while it runs, and what setup and grading can reach.
egress_allowlist, an earlier field that some contracts still set, adds hosts to the benchmark’s run allowlist, or becomes the run allowlist when the benchmark sets none.- Hosts behind a shared content delivery network (CDN) can make an allowlist broader than the names in it.
Output files
final_output is saved as agent_output.tar.gz in the task’s folder, if the path exists
when the agent finishes. While the task is active, its files can also be read live from the
sandbox, including any written during grading, so don’t treat the path as private.
output_artifacts entries take one of two forms:
sourceis an absolute path. It can include{task_id}and a glob under a directory, such as/logs/*.json. A glob saves its first match in sorted order.- Every entry is required unless it sets
required: false. A required artifact that is missing or can’t be saved fails the task. An optional one is skipped and logged. - A task can declare at most 10 artifacts, of at most 250 MiB each and 250 MiB together.
- Entries are saved under
benchmarks/RUN_ID/TASK_ID/at theirpath, whereRUN_IDandTASK_IDare the run’s and task’s IDs.
Error reports
Whenrun_cmd exits with a nonzero code, the task fails with
Agent command failed with exit code N. A line written to the file named by
VALKYRIE_ERROR_PATH is added to that error.
- Write one line in the form
Type: message, such asAgentError: model returned no patch. - A report longer than 2048 bytes is dropped.
- Valkyrie replaces the values of the contract’s secrets with
[REDACTED]. It can’t recognize other sensitive data, so don’t write prompts or model output. - Exit code 137, when the operating system stops the agent, isn’t an agent failure. The benchmark still grades the task.
The turns field
Some benchmarks start the agent more than once per task, for example to continue a
conversation, and can run several copies, called slots, side by side. Other benchmarks
ignore turns.
contract.yaml
{problem_statement_path}is each turn’s input.{slot_dir}is a directory private to the slot. When slots run side by side,run_cmdmust use{slot_dir}, and so mustfinal_outputif it’s set.{container_name}is the value ofcontainer_namefor the current slot.

