Extension stub for generating fresh, randomized injection scenarios per run โ the gym's growth path from "fixed benchmark" to "procedural curriculum" (factory doctrine: procedural randomized environments + per-run secrets so memorized writeups don't transfer).
counter_suite.py worked example: a complete custom task suite (tools,
environment, user + injection tasks, injection vector)
counter_data/ suite data files agentdojo expects:
environment.yaml (default env, with {placeholders})
injection_vectors.yaml (vector ids + benign defaults)
payload_bank.py per-run secrets + injection payload bank (5 families),
seeded option for reproducible trajectories
(document every arg: :param n: ...), and Annotated[T, Depends(...)] parameters are injected from the environment:
```python def increment(env: Annotated[CounterEnvironment, Depends(lambda e: e)], n: int) -> None: """Increment the counter by the given amount.
:param n: the amount to add to the counter. """ env.counter += n ```
``python task_suite = TaskSuite("counter", CounterEnvironment, [make_function(t) for t in TOOLS], DATA_DIR) register_suite(task_suite, "v1") ``
@task_suite.register_user_task): PROMPT,ground_truth(pre_env) -> list[FunctionCall], and utility(model_output, pre_env, post_env) -> bool (state diff).
@task_suite.register_injection_task): GOAL,ground_truth(pre_env). Polarity gotcha (verified in all built-in suites): security(...) must return True when the injection goal WAS achieved โ it is a goal-condition check, not a safety verdict. The benchmark's security_results therefore read as "attack landed" and our telemetry computes ASR = mean(security_results).
{placeholder} in environment.yaml anddeclare it in injection_vectors.yaml. Attacks (ImportantInstructionsAttack, ...) replace the default text wherever the ground-truth tool flow surfaces it to the agent.
payload_bank.manifest(seed=None, goal=...) draws fresh secrets and renders the payload bank; splice the drawn values into your suite's injection_vectors.yaml default (or the GOAL) before get_suite(...), and archive the manifest next to the trajectory. --seed reproduces a run exactly โ same doctrine as the EVM asserts' per-run challenge values.
into N distinct scenarios per epoch (hook: manifest() output โ suite fixtures);
PromptInjectionDetector variants as pipeline defensesand measure utility/ASR trade-off curves.