await agent(run), where the run is the live handle for one task: its prompt, its connection to the
environment, and the trace it fills.
Because an environment only exposes capabilities, the agent isn’t baked in - use a built-in agent for a
standard model, or bring your own harness for a custom
loop.
Built-in agents
The SDK ships one agent per major provider, reached two ways:create_agent(model)- the preferred path. It selects the matching provider agent for a model id and routes every call through the HUD gateway.- a provider agent directly (e.g.
ClaudeAgent(ClaudeConfig(...))) - the same class constructed yourself, for full config control or to call the provider with your own key instead of the gateway.
settings.hud_gateway_url, default
https://inference.beta.hud.ai) that fronts every provider behind your single HUD_API_KEY, so you
switch between Claude, GPT, and Gemini by name alone, with unified tracing. create_agent accepts any id
the gateway knows (claude-..., gpt-..., gemini-...); extra kwargs pass through to the agent’s
config.
Built-in agents are catalog-driven: each run they read the environment’s manifest, open the
capabilities they support, build the matching provider tools, and loop against run.prompt_messages.
Declaring a capability on the environment is enough; you never wire tools.
Provider agents
Each model maps to a provider agent - the class that speaks that provider’s API. Construct one directly to set its full config or use your own provider key:
Each config lives in
hud.agents.types. OpenAIChatAgent speaks the OpenAI Chat Completions API, so it
points at any compatible server (vLLM, a local model) via base_url; ClaudeSDKAgent runs the claude
CLI over an ssh capability, against the env’s filesystem. Every knob (model, max_steps,
system_prompt, citations_enabled, stop_on) lives on the config; __call__(run)
takes only the run.
create_agent
create_agent function resolves model to a gateway agent type and returns that provider agent
wired to the gateway. Extra kwargs forward to the matched provider config (the *Config for the
resolved type), with model and a gateway model_client filled in. Passing completion_kwargs only
works when model resolves to OpenAIChatAgent, since completion_kwargs lives only on
OpenAIChatConfig.
A model id maps to one of four gateway agent types (AgentType), each a provider agent:
For a provider key instead of the gateway, or for
ClaudeSDKAgent (not a gateway type), construct the
provider agent directly.
Agent
Every agent implements theAgent base class (hud.agents.base): one abstract method,
__call__(run: Run) -> None. An agent drives the live Run to completion,
filling run.trace in place; the graded answer is run.trace.content. An agent is stateless per run -
everything comes from run - so one instance drives many concurrent rollouts.
Running an agent
Run a task with an agent two ways. Programmatically, pass the agent toTask.run or Taskset.run
with a runtime:
hud eval takes a task source and an agent name (claude, openai, gemini,
openai_compatible); see running an eval for the walkthrough and the
CLI reference for the full flag set.
Bring your own harness
Any loop or framework can be an agent: subclassAgent, drive the environment off the run, and write
the final answer to run.trace.content (what gets graded). Since this is outside the standard workflow,
the seam, the Run object you work with, the step types you record, and worked examples live in
Extending HUD.
To run an agent end to end see running an eval; for where each rollout runs
see runtimes, and for the Run an agent fills see
types.