AgentConfig Trait
The AgentConfig trait defines the core configuration interface for agents built with agent-air. Every agent must implement this trait to specify its configuration file location, default system prompt, logging prefix, and display name.
Trait Definition
pub trait AgentConfig {
/// Path to the configuration file
fn config_path(&self) -> &str;
/// The default system prompt for this agent
fn default_system_prompt(&self) -> &str;
/// The log file prefix for this agent
fn log_prefix(&self) -> &str;
/// Agent name for display and logging
fn name(&self) -> &str;
}
The trait requires four methods, each returning a string slice. All methods take &self, allowing implementations to store configuration values in struct fields if needed.
Method Reference
config_path
fn config_path(&self) -> &str
Returns the path to the agent’s configuration file. Paths starting with ~/ are expanded to the user’s home directory.
Example values:
"~/.myagent/config.yaml"- hidden directory in home"~/.config/myagent/config.yaml"- XDG-style location
The configuration file uses YAML format and defines LLM provider settings. If the file does not exist or is empty, the framework falls back to environment variables.
default_system_prompt
fn default_system_prompt(&self) -> &str
Returns the default system prompt sent to the LLM at the start of each session. This prompt establishes the agent’s persona and behavior guidelines.
The system prompt is applied to all configured providers and defines how the agent responds to user input.
log_prefix
fn log_prefix(&self) -> &str
Returns a prefix used for log file naming. The framework creates log files using this prefix to distinguish logs from different agents.
Example: A log prefix of "myagent" produces log files like myagent_2024-01-15.log.
name
fn name(&self) -> &str
Returns a human-readable name for the agent. This name appears in:
- Startup log messages
- Error messages
- TUI title bar (when using the TUI)
Basic Implementation
The simplest implementation uses a unit struct with constant values:
use agent_air::agent::AgentConfig;
struct MyAgentConfig;
impl AgentConfig for MyAgentConfig {
fn config_path(&self) -> &str {
"~/.myagent/config.yaml"
}
fn default_system_prompt(&self) -> &str {
"You are a helpful coding assistant. Answer questions clearly and concisely."
}
fn log_prefix(&self) -> &str {
"myagent"
}
fn name(&self) -> &str {
"MyAgent"
}
}
Configurable Implementation
For agents that need runtime configuration, store values in struct fields:
use agent_air::agent::AgentConfig;
struct FlexibleConfig {
config_path: String,
system_prompt: String,
log_prefix: String,
name: String,
}
impl FlexibleConfig {
pub fn new(name: &str) -> Self {
let slug = name.to_lowercase().replace(' ', "_");
Self {
config_path: format!("~/.{}/config.yaml", slug),
system_prompt: format!("You are {}. Be helpful and precise.", name),
log_prefix: slug.clone(),
name: name.to_string(),
}
}
}
impl AgentConfig for FlexibleConfig {
fn config_path(&self) -> &str {
&self.config_path
}
fn default_system_prompt(&self) -> &str {
&self.system_prompt
}
fn log_prefix(&self) -> &str {
&self.log_prefix
}
fn name(&self) -> &str {
&self.name
}
}
Using AgentConfig with AgentAir
Pass your configuration to AgentAir::new() to initialize the agent:
use agent_air::agent::{AgentConfig, AgentAir};
struct MyConfig;
impl AgentConfig for MyConfig {
fn config_path(&self) -> &str { "~/.myagent/config.yaml" }
fn default_system_prompt(&self) -> &str { "You are a helpful assistant." }
fn log_prefix(&self) -> &str { "myagent" }
fn name(&self) -> &str { "MyAgent" }
}
fn main() -> std::io::Result<()> {
let config = MyConfig;
let agent = AgentAir::new(&config)?;
// Continue with agent setup...
Ok(())
}
Configuration Loading
When AgentAir::new() is called, the framework loads LLM provider configuration in this order:
- YAML config file: Attempts to load from the path returned by
config_path() - Environment variables: Falls back to API key environment variables if the config file is missing or empty
See Provider Configuration for supported providers and environment variables.
Config File Format
The configuration file uses YAML format:
providers:
- provider: anthropic
api_key: sk-ant-...
model: claude-sonnet-4-20250514
- provider: groq
api_key: gsk_...
model: llama-3.3-70b-versatile
default_provider: anthropic
The system prompt from default_system_prompt() is applied to all providers. See Provider Configuration for the complete list of supported providers.
Error Handling
Configuration errors are represented by ConfigError:
| Error | Description |
|---|---|
NoHomeDirectory | The user’s home directory could not be determined |
ReadError | The config file exists but could not be read |
ParseError | The config file contains invalid YAML |
UnknownProvider | A provider name is not recognized |
Startup Behavior
Missing configuration does not prevent startup. If no providers are configured, the agent initializes but cannot make LLM requests. A warning is logged directing users to set environment variables or create a config file.
Checking Configuration
To verify configuration before starting:
use agent_air::agent::{AgentConfig, AgentAir, load_config};
fn main() -> std::io::Result<()> {
let config = MyConfig;
let registry = load_config(&config);
if registry.is_empty() {
eprintln!("Error: No LLM providers configured.");
eprintln!("Set an API key environment variable or create {}", config.config_path());
std::process::exit(1);
}
let agent = AgentAir::new(&config)?;
Ok(())
}
SimpleConfig
For quick setup, use the built-in SimpleConfig struct:
use agent_air::agent::SimpleConfig;
let config = SimpleConfig::new(
"MyAgent",
"~/.myagent/config.yaml",
"You are a helpful assistant."
);
This provides the same functionality as a custom implementation without defining a new struct.
