Overview
The Agent API provides the core orchestration layer for IronClaw, managing:
- Message routing from channels
- Job scheduling and execution
- Tool invocation with safety
- Self-repair for stuck jobs
- Proactive heartbeat execution
- Routine-based scheduled and reactive jobs
- Turn-based session management with undo
- Context compaction for long conversations
Agent
The main agent struct that coordinates all components.
Constructor
pub fn new(
config: AgentConfig,
deps: AgentDeps,
channels: Arc<ChannelManager>,
heartbeat_config: Option<HeartbeatConfig>,
hygiene_config: Option<crate::config::HygieneConfig>,
routine_config: Option<RoutineConfig>,
context_manager: Option<Arc<ContextManager>>,
session_manager: Option<Arc<SessionManager>>,
) -> Self
Creates a new agent with the specified configuration and dependencies.
Agent configuration including max parallel jobs, repair settings, and session timeouts
Core dependencies including database, LLM provider, safety layer, and tool registry
channels
Arc<ChannelManager>
required
Channel manager for handling multiple input/output channels
Optional configuration for proactive heartbeat checks
Optional configuration for scheduled and event-driven routines
context_manager
Option<Arc<ContextManager>>
Optional pre-created context manager (creates new one if not provided)
session_manager
Option<Arc<SessionManager>>
Optional pre-created session manager (creates new one if not provided)
run
pub async fn run(self) -> Result<(), Error>
Runs the agent main loop. Starts all channels, spawns background tasks (self-repair, heartbeat, routines), and processes incoming messages until shutdown.
Returns: Result<(), Error> - Ok on clean shutdown, Error if startup fails
scheduler
pub fn scheduler(&self) -> Arc<Scheduler>
Get the scheduler for external wiring (e.g., CreateJobTool).
Returns: Shared reference to the scheduler
AgentDeps
Core dependencies for the agent, bundling shared components to reduce argument count.
Fields
store
Option<Arc<dyn Database>>
Optional database for persistence
Primary LLM provider for agent responses
cheap_llm
Option<Arc<dyn LlmProvider>>
Optional cheap/fast LLM for lightweight tasks (heartbeat, routing, evaluation). Falls back to main LLM if None.
Safety layer for content filtering and policy enforcement
Registry of available tools
Optional workspace for persistent memory
extension_manager
Option<Arc<ExtensionManager>>
Optional extension manager for WASM and MCP tools
skill_registry
Option<Arc<RwLock<SkillRegistry>>>
Optional skill registry for prompt-level skills
Hook registry for intercepting inbound/outbound messages
Cost enforcement guardrails (daily budget, hourly rate limits)
Session Management
Session
Manages conversation state and turn history for a user.
pub struct Session {
pub user_id: String,
pub threads: HashMap<String, Thread>,
}
Thread
Represents a conversation thread with turn-based history.
pub struct Thread {
pub id: String,
pub turns: Vec<Turn>,
pub state: ThreadState,
pub pending_auth: Option<PendingAuth>,
}
Turn
A single turn in a conversation (user input + agent response).
pub struct Turn {
pub id: Uuid,
pub user_input: String,
pub agent_response: String,
pub created_at: DateTime<Utc>,
pub state: TurnState,
}
Context Compaction
The agent automatically compacts conversation context when it exceeds thresholds.
ContextMonitor
src/agent/context_monitor.rs
pub struct ContextMonitor {
strategy: CompactionStrategy,
}
Monitors context usage and triggers compaction when needed.
CompactionStrategy
src/agent/context_monitor.rs
pub enum CompactionStrategy {
/// Never compact, just fail when limit reached
Never,
/// Compact when approaching limit (recommended)
Automatic { warning_threshold: usize, max_threshold: usize },
/// Always compact after every turn (aggressive)
Always,
}
Self-Repair
The agent includes self-repair capabilities for stuck jobs and broken tools.
SelfRepair Trait
#[async_trait]
pub trait SelfRepair: Send + Sync {
async fn detect_stuck_jobs(&self) -> Vec<StuckJob>;
async fn repair_stuck_job(&self, job: &StuckJob) -> Result<RepairResult, Error>;
async fn detect_broken_tools(&self) -> Vec<BrokenTool>;
async fn repair_broken_tool(&self, tool: &BrokenTool) -> Result<RepairResult, Error>;
}
RepairResult
pub enum RepairResult {
Success { message: String },
Failed { message: String },
ManualRequired { message: String },
Retry { message: String },
}
Example
use ironclaw::agent::{Agent, AgentDeps};
use ironclaw::config::AgentConfig;
use std::sync::Arc;
// Create dependencies
let deps = AgentDeps {
store: Some(db),
llm: Arc::new(llm_provider),
cheap_llm: None,
safety: Arc::new(safety_layer),
tools: Arc::new(tool_registry),
workspace: Some(Arc::new(workspace)),
extension_manager: None,
skill_registry: None,
skill_catalog: None,
skills_config: Default::default(),
hooks: Arc::new(hook_registry),
cost_guard: Arc::new(cost_guard),
sse_tx: None,
};
// Create agent
let agent = Agent::new(
AgentConfig::default(),
deps,
channel_manager,
None, // heartbeat config
None, // hygiene config
None, // routine config
None, // context manager
None, // session manager
);
// Run agent (blocks until shutdown)
agent.run().await?;