Skip to main content

ai_agents/
lib.rs

1//! # AI Agents Framework
2//!
3//! **One YAML = Any Agent.** A Rust framework for building AI agents from a single YAML
4//! specification. No code required for common use cases.
5//!
6//! # Quick Start
7//!
8//! ### From YAML
9//!
10//! ```rust,ignore
11//! use ai_agents::{Agent, AgentBuilder};
12//!
13//! #[tokio::main]
14//! async fn main() -> ai_agents::Result<()> {
15//!     let agent = AgentBuilder::from_yaml_file("agent.yaml")?
16//!         .auto_configure_llms()?
17//!         .build()?;
18//!
19//!     let response = agent.chat("Hello!").await?;
20//!     println!("{}", response.content);
21//!     Ok(())
22//! }
23//! ```
24//!
25//! ### From Rust API
26//!
27//! ```rust,ignore
28//! use ai_agents::{Agent, AgentBuilder, UnifiedLLMProvider, ProviderType};
29//! use std::sync::Arc;
30//!
31//! #[tokio::main]
32//! async fn main() -> ai_agents::Result<()> {
33//!     let llm = UnifiedLLMProvider::from_env(ProviderType::OpenAI, "gpt-4.1-nano")?;
34//!
35//!     let agent = AgentBuilder::new()
36//!         .system_prompt("You are a helpful assistant.")
37//!         .llm(Arc::new(llm))
38//!         .build()?;
39//!
40//!     let response = agent.chat("Hello!").await?;
41//!     println!("{}", response.content);
42//!     Ok(())
43//! }
44//! ```
45//!
46//! # Modules
47//!
48//! | Module | Description |
49//! |--------|-------------|
50//! | [`agent`] | Agent builder, runtime, streaming, and response types |
51//! | [`llm`] | LLM providers and registry |
52//! | [`memory`] | Conversation memory with compression and token budgeting |
53//! | [`tools`] | Built-in tools and extensible tool registry |
54//! | [`state`] | Hierarchical state machine with LLM-evaluated transitions |
55//! | [`context`] | Dynamic context injection from multiple sources |
56//! | [`skill`] | Reusable workflows with LLM-based intent routing |
57//! | [`hitl`] | Human-in-the-loop approval system |
58//! | [`reasoning`] | Chain-of-thought, ReAct, plan-and-execute modes |
59//! | [`disambiguation`] | Intent ambiguity detection and clarification |
60//! | [`persistence`] | SQLite, Redis, and file storage backends |
61//! | [`process`] | Input/output processing pipeline |
62//! | [`recovery`] | Error recovery with retry and fallback strategies |
63//! | [`hooks`] | Lifecycle event hooks for logging, metrics, monitoring |
64//! | [`spec`] | YAML agent specification types |
65//! | [`template`] | Template loading with Jinja2 rendering and inheritance |
66//! | [`spawner`] | Dynamic agent spawning, registry, and inter-agent messaging |
67//!
68//! # Feature Flags
69//!
70//! | Flag | Description |
71//! |------|-------------|
72//! | `sqlite` | SQLite storage backend |
73//! | `redis-storage` | Redis storage backend |
74//! | `http-context` | HTTP context source for dynamic context injection |
75//! | `full-storage` | All storage backends (`sqlite` + `redis-storage`) |
76//! | `full` | All optional features enabled |
77
78pub mod agent {
79    pub use ai_agents_runtime::{
80        Agent, AgentBuilder, AgentInfo, AgentResponse, ParallelToolsConfig, RuntimeAgent,
81        StreamChunk, StreamingConfig, ToolCall,
82    };
83}
84
85pub mod context {
86    pub use ai_agents_context::{
87        BuiltinSource, ContextManager, ContextProvider, ContextSource, RefreshPolicy,
88        TemplateRenderer,
89    };
90}
91
92pub mod error {
93    pub use ai_agents_core::{AgentError, Result};
94}
95
96pub mod dot_path {
97    pub use ai_agents_core::{get_dot_path, get_dot_path_from_map, set_dot_path};
98}
99
100pub mod hitl {
101    pub use ai_agents_hitl::{
102        ApprovalCondition, ApprovalHandler, ApprovalMessage, ApprovalRequest, ApprovalResult,
103        ApprovalTrigger, AutoApproveHandler, CallbackHandler, HITLCheckResult, HITLConfig,
104        HITLEngine, LlmGenerateConfig, LocalizedHandler, MessageLanguageConfig,
105        MessageLanguageStrategy, MessageResolver, RejectAllHandler, StateApprovalConfig,
106        StateApprovalTrigger, TimeoutAction, ToolApprovalConfig, create_handler,
107        create_localized_handler, resolve_best_language, resolve_tool_message,
108    };
109}
110
111pub mod hooks {
112    pub use ai_agents_hooks::{AgentHooks, CompositeHooks, HookTimer, LoggingHooks, NoopHooks};
113}
114
115pub mod llm {
116    pub use ai_agents_core::{
117        ChatMessage, FinishReason, LLMCapability, LLMChunk, LLMConfig, LLMError, LLMFeature,
118        LLMProvider, LLMResponse, Role, TaskContext, TokenUsage, ToolSelection,
119    };
120    pub use ai_agents_llm::LLMRegistry;
121
122    pub mod providers {
123        pub use ai_agents_llm::providers::{ProviderBuilder, ProviderType, UnifiedLLMProvider};
124    }
125}
126
127pub mod memory {
128    use std::sync::Arc;
129
130    use ai_agents_core::LLMProvider;
131
132    pub use ai_agents_core::MemorySnapshot;
133    pub use ai_agents_memory::{
134        CompactingMemory, CompactingMemoryConfig, CompressResult, CompressionEvent,
135        ConversationContext, EvictionReason, FactExtractedEvent, InMemoryStore, LLMSummarizer,
136        Memory, MemoryBudgetEvent, MemoryBudgetState, MemoryCompressEvent, MemoryEvictEvent,
137        MemoryTokenBudget, NoopSummarizer, OverflowStrategy, Summarizer, TokenAllocation,
138        estimate_message_tokens, estimate_tokens,
139    };
140    pub use ai_agents_runtime::spec::MemoryConfig;
141
142    pub fn create_memory(memory_type: &str, max_messages: usize) -> Arc<dyn Memory> {
143        match memory_type {
144            "in-memory" => Arc::new(InMemoryStore::new(max_messages)),
145            "compacting" => {
146                let summarizer: Arc<dyn Summarizer> = Arc::new(NoopSummarizer);
147                Arc::new(CompactingMemory::with_default_config(summarizer))
148            }
149            _ => Arc::new(InMemoryStore::new(max_messages)),
150        }
151    }
152
153    pub fn create_memory_from_config(config: &MemoryConfig) -> Arc<dyn Memory> {
154        if config.is_compacting() {
155            let summarizer: Arc<dyn Summarizer> = Arc::new(NoopSummarizer);
156            let compacting_config = config.to_compacting_config();
157            Arc::new(CompactingMemory::new(summarizer, compacting_config))
158        } else {
159            Arc::new(InMemoryStore::new(config.max_messages))
160        }
161    }
162
163    pub fn create_memory_from_config_with_llm(
164        config: &MemoryConfig,
165        llm: Option<Arc<dyn LLMProvider>>,
166    ) -> Arc<dyn Memory> {
167        if config.is_compacting() {
168            let summarizer: Arc<dyn Summarizer> = match llm {
169                Some(provider) => Arc::new(LLMSummarizer::new(provider)),
170                None => Arc::new(NoopSummarizer),
171            };
172            let compacting_config = config.to_compacting_config();
173            Arc::new(CompactingMemory::new(summarizer, compacting_config))
174        } else {
175            Arc::new(InMemoryStore::new(config.max_messages))
176        }
177    }
178
179    pub fn create_compacting_memory(
180        summarizer: Arc<dyn Summarizer>,
181        config: CompactingMemoryConfig,
182    ) -> Arc<dyn Memory> {
183        Arc::new(CompactingMemory::new(summarizer, config))
184    }
185
186    pub fn create_compacting_memory_from_config(
187        summarizer: Arc<dyn Summarizer>,
188        config: &MemoryConfig,
189    ) -> Arc<dyn Memory> {
190        let compacting_config = config.to_compacting_config();
191        Arc::new(CompactingMemory::new(summarizer, compacting_config))
192    }
193}
194
195pub mod persistence {
196    use std::sync::Arc;
197
198    pub use ai_agents_core::{
199        AgentSnapshot, AgentStorage, MemorySnapshot, Result, SpawnedAgentEntry,
200    };
201    #[cfg(feature = "sqlite")]
202    pub use ai_agents_storage::SqliteStorage;
203    pub use ai_agents_storage::{
204        FileStorage, SessionInfo, SessionMetadata, SessionOrderBy, SessionQuery,
205    };
206    #[cfg(feature = "redis-storage")]
207    pub use ai_agents_storage::{RedisSessionMeta, RedisStorage};
208
209    pub async fn create_storage(
210        config: &crate::spec::StorageConfig,
211    ) -> Result<Option<Arc<dyn AgentStorage>>> {
212        let storage_config = match config {
213            crate::spec::StorageConfig::None => ai_agents_storage::StorageConfig::None,
214            crate::spec::StorageConfig::File(fc) => ai_agents_storage::StorageConfig::File {
215                path: fc.path.clone(),
216            },
217            crate::spec::StorageConfig::Sqlite(sc) => ai_agents_storage::StorageConfig::Sqlite {
218                path: sc.path.clone(),
219            },
220            crate::spec::StorageConfig::Redis(rc) => ai_agents_storage::StorageConfig::Redis {
221                url: rc.url.clone(),
222                prefix: rc.prefix.clone(),
223                ttl_seconds: rc.ttl_seconds,
224            },
225        };
226
227        ai_agents_storage::create_storage(&storage_config).await
228    }
229}
230
231pub mod process {
232    pub use ai_agents_process::{ProcessConfig, ProcessData, ProcessProcessor};
233}
234
235pub mod recovery {
236    pub use ai_agents_recovery::{
237        ByRoleFilter, ErrorRecoveryConfig, FilterConfig, KeepRecentFilter, MessageFilter,
238        RecoveryManager, SkipPatternFilter,
239    };
240}
241
242pub mod skill {
243    pub use ai_agents_skills::{
244        SkillContext, SkillDefinition, SkillExecutor, SkillLoader, SkillRef, SkillRouter,
245        SkillStep, StepResult,
246    };
247}
248
249pub mod spec {
250    pub use ai_agents_runtime::spec::{
251        AgentSpec, BuiltinProviderConfig, CliHitlMetadata, CliHitlStyle, CliMetadata,
252        CliPromptStyle, FileStorageConfig, LLMConfig, LLMSelector, MemoryConfig,
253        ProviderPolicyConfig, ProviderSecurityConfig, ProvidersConfig, RedisStorageConfig,
254        SpawnerConfig, SqliteStorageConfig, StorageConfig, StructuredToolEntry, ToolAliasesConfig,
255        ToolConfig, ToolEntry, ToolPolicyConfig, YamlProviderConfig, YamlToolConfig,
256    };
257}
258
259pub mod state {
260    pub use ai_agents_state::{
261        CompareOp, ContextExtractor, ContextMatcher, DelegateContextMode, GuardConditions,
262        GuardOnlyEvaluator, HandoffStateConfig, LLMTransitionEvaluator, PipelineStageEntry,
263        PipelineStateConfig, PromptMode, StateAction, StateConfig, StateDefinition, StateMachine,
264        StateMachineSnapshot, StateMatcher, StateTransitionEvent, TimeMatcher, ToolCondition,
265        ToolRef, Transition, TransitionContext, TransitionEvaluator, TransitionGuard,
266    };
267}
268
269pub mod template {
270    use std::collections::HashMap;
271    use std::path::PathBuf;
272
273    use ai_agents_template::TemplateLoader as InnerTemplateLoader;
274    pub use ai_agents_template::{TemplateInheritance, TemplateRenderer};
275
276    use crate::error::Result;
277    use crate::spec::AgentSpec;
278
279    pub struct TemplateLoader {
280        inner: InnerTemplateLoader,
281    }
282
283    impl TemplateLoader {
284        pub fn new() -> Self {
285            Self {
286                inner: InnerTemplateLoader::new(),
287            }
288        }
289
290        pub fn add_search_path(&mut self, path: impl Into<PathBuf>) -> &mut Self {
291            self.inner.add_search_path(path);
292            self
293        }
294
295        pub fn set_variable(
296            &mut self,
297            key: impl Into<String>,
298            value: impl Into<String>,
299        ) -> &mut Self {
300            self.inner.set_variable(key, value);
301            self
302        }
303
304        pub fn set_variables(&mut self, vars: HashMap<String, String>) -> &mut Self {
305            self.inner.set_variables(vars);
306            self
307        }
308
309        pub fn get_variable(&self, key: &str) -> Option<&str> {
310            self.inner.get_variable(key)
311        }
312
313        pub fn load_template(&self, name: &str) -> Result<String> {
314            self.inner.load_template(name)
315        }
316
317        pub fn template_exists(&self, name: &str) -> bool {
318            self.inner.template_exists(name)
319        }
320
321        pub fn search_paths(&self) -> &[PathBuf] {
322            self.inner.search_paths()
323        }
324
325        pub fn variables(&self) -> &HashMap<String, String> {
326            self.inner.variables()
327        }
328
329        pub fn load_and_parse(&self, template_name: &str) -> Result<AgentSpec> {
330            let renderer = TemplateRenderer::new();
331            let variables = self.variables();
332
333            let load_and_render = |name: &str| -> Result<String> {
334                let content = self.load_template(name)?;
335                renderer.render(&content, variables)
336            };
337
338            let rendered_root = load_and_render(template_name)?;
339            let processed = TemplateInheritance::process(&rendered_root, load_and_render)?;
340            let spec: AgentSpec = serde_yaml::from_str(&processed)?;
341            spec.validate()?;
342
343            Ok(spec)
344        }
345    }
346
347    impl Default for TemplateLoader {
348        fn default() -> Self {
349            Self::new()
350        }
351    }
352
353    impl AsRef<InnerTemplateLoader> for TemplateLoader {
354        fn as_ref(&self) -> &InnerTemplateLoader {
355            &self.inner
356        }
357    }
358
359    impl From<InnerTemplateLoader> for TemplateLoader {
360        fn from(inner: InnerTemplateLoader) -> Self {
361            Self { inner }
362        }
363    }
364}
365
366pub mod persona {
367    pub use ai_agents_persona::{
368        EvolutionConfig, PERSONA_CHANGE_METADATA_KEY, PersonaChange, PersonaConfig,
369        PersonaEvolveTool, PersonaGoals, PersonaIdentity, PersonaManager, PersonaRenderResult,
370        PersonaSecret, PersonaSnapshot, PersonaTemplateRef, PersonaTemplateRegistry, PersonaTraits,
371        SecretRevealCondition, VALID_EVOLVE_PATHS,
372    };
373}
374
375pub mod reasoning {
376    pub use ai_agents_reasoning::{
377        CriterionResult, EvaluationResult, Plan, PlanAction, PlanAvailableActions,
378        PlanReflectionConfig, PlanStatus, PlanStep, PlanningConfig, ReasoningConfig,
379        ReasoningMetadata, ReasoningMode, ReasoningOutput, ReflectionAttempt, ReflectionConfig,
380        ReflectionMetadata, ReflectionMode, StepFailureAction, StepStatus, StringOrList,
381    };
382}
383
384pub mod disambiguation {
385    pub use ai_agents_disambiguation::{
386        AmbiguityAspect, AmbiguityDetectionResult, AmbiguityDetector, AmbiguityType, CacheConfig,
387        ClarificationConfig, ClarificationGenerator, ClarificationOption, ClarificationParseResult,
388        ClarificationQuestion, ClarificationStyle, ContextConfig, DetectionConfig,
389        DisambiguationConfig, DisambiguationContext, DisambiguationManager, DisambiguationResult,
390        MaxAttemptsAction, SkillDisambiguationOverride, SkipCondition, StateDisambiguationOverride,
391    };
392}
393
394pub mod tool_security {
395    pub use ai_agents_tools::{
396        SecurityCheckResult, ToolPolicyConfig, ToolSecurityConfig, ToolSecurityEngine,
397    };
398}
399
400pub mod tools {
401    pub use ai_agents_core::{Tool, ToolInfo, ToolResult};
402    pub use ai_agents_tools::{
403        CalculatorTool, ConditionEvaluator, DateTimeTool, EchoTool, EvaluationContext, FileTool,
404        JsonTool, LLMGetter, MathTool, ProviderHealth, RandomTool, SimpleLLMGetter, TemplateTool,
405        TextTool, ToolAliases, ToolCallRecord, ToolContext, ToolDescriptor, ToolMetadata,
406        ToolProvider, ToolProviderError, ToolProviderType, ToolRegistry, TrustLevel,
407        create_builtin_registry,
408    };
409    pub use ai_agents_tools::{HttpTool, generate_schema};
410}
411
412/// MCP (Model Context Protocol) integration types.
413pub mod mcp {
414    pub use ai_agents_tools::mcp::{
415        MCPViewConfig, MCPViewTool, MCPWrapperConfig, MCPWrapperSecurity, MCPWrapperTool,
416        MCPWrapperTransport,
417    };
418}
419
420/// Dynamic agent spawning, registry, and inter-agent messaging.
421pub mod spawner {
422    pub use ai_agents_runtime::spawner::{
423        AgentRegistry, AgentSpawner, GenerateAgentTool, ListAgentsTool, NamespacedStorage,
424        RegistryHooks, RemoveAgentTool, ResolvedTemplate, SendMessageTool, SpawnedAgent,
425        SpawnedAgentInfo, auto_configure_spawner, configure_spawner_tools, resolve_templates,
426        spawner_from_config,
427    };
428}
429
430// Multi-agent orchestration patterns and tool wrappers.
431pub mod orchestration {
432    pub use ai_agents_runtime::orchestration::context::prepare_delegate_input;
433    pub use ai_agents_runtime::orchestration::tools::{
434        ConcurrentAskTool, GroupDiscussionTool, HandoffConversationTool, PipelineProcessTool,
435        RouteToAgentTool, configure_orchestration_tools,
436    };
437    pub use ai_agents_runtime::orchestration::types::{
438        AgentResult, ChatTurn, ConcurrentResult, GroupChatResult, HandoffEvent, HandoffResult,
439        PipelineResult, PipelineStage, RouteResult, RoutingMethod, StageOutput,
440    };
441    pub use ai_agents_runtime::orchestration::{concurrent, group_chat, handoff, pipeline, route};
442}
443
444// Top-level re-exports (legacy interface)
445pub use agent::{
446    Agent, AgentBuilder, AgentInfo, AgentResponse, ParallelToolsConfig, RuntimeAgent, StreamChunk,
447    StreamingConfig,
448};
449pub use error::{AgentError, Result};
450pub use memory::{
451    CompactingMemory, CompactingMemoryConfig, CompressResult, CompressionEvent,
452    ConversationContext, EvictionReason, FactExtractedEvent, InMemoryStore, LLMSummarizer, Memory,
453    MemoryBudgetEvent, MemoryBudgetState, MemoryCompressEvent, MemoryEvictEvent, MemoryTokenBudget,
454    NoopSummarizer, OverflowStrategy, Summarizer, TokenAllocation, create_memory,
455    create_memory_from_config, create_memory_from_config_with_llm, estimate_message_tokens,
456    estimate_tokens,
457};
458pub use skill::{SkillDefinition, SkillExecutor, SkillLoader, SkillRef, SkillRouter, SkillStep};
459pub use spec::{
460    AgentSpec, BuiltinProviderConfig, FileStorageConfig, LLMConfig, LLMSelector, MemoryConfig,
461    ProviderPolicyConfig, ProviderSecurityConfig, ProvidersConfig, RedisStorageConfig,
462    SqliteStorageConfig, StorageConfig, ToolAliasesConfig, ToolConfig,
463    ToolPolicyConfig as SpecToolPolicyConfig, YamlProviderConfig, YamlToolConfig,
464};
465pub use template::TemplateLoader;
466pub use tools::HttpTool;
467pub use tools::{
468    CalculatorTool, DateTimeTool, EchoTool, FileTool, JsonTool, MathTool, RandomTool, TemplateTool,
469    TextTool, Tool, ToolRegistry, ToolResult, create_builtin_registry,
470};
471
472pub use llm::providers::{ProviderType, ProviderType as LLMProviderType, UnifiedLLMProvider};
473pub use llm::{ChatMessage, LLMProvider, LLMRegistry, LLMResponse, Role};
474
475pub use process::{ProcessConfig, ProcessData, ProcessProcessor};
476pub use recovery::{
477    ByRoleFilter, ErrorRecoveryConfig, FilterConfig, KeepRecentFilter, MessageFilter,
478    RecoveryManager, SkipPatternFilter,
479};
480pub use tool_security::{
481    SecurityCheckResult, ToolPolicyConfig, ToolSecurityConfig, ToolSecurityEngine,
482};
483
484pub use context::{
485    BuiltinSource, ContextManager, ContextProvider, ContextSource, RefreshPolicy, TemplateRenderer,
486};
487#[cfg(feature = "sqlite")]
488pub use persistence::SqliteStorage;
489pub use persistence::{
490    AgentSnapshot, AgentStorage, FileStorage, MemorySnapshot, SessionInfo, SessionMetadata,
491    SessionOrderBy, SessionQuery, SpawnedAgentEntry, create_storage,
492};
493#[cfg(feature = "redis-storage")]
494pub use persistence::{RedisSessionMeta, RedisStorage};
495
496pub use state::{
497    CompareOp, ContextExtractor, ContextMatcher, GuardConditions, GuardOnlyEvaluator,
498    LLMTransitionEvaluator, PromptMode, StateAction, StateConfig, StateDefinition, StateMachine,
499    StateMachineSnapshot, StateMatcher, StateTransitionEvent, TimeMatcher, ToolCondition, ToolRef,
500    Transition, TransitionContext, TransitionEvaluator, TransitionGuard,
501};
502pub use tools::{
503    ConditionEvaluator, EvaluationContext, LLMGetter, SimpleLLMGetter, ToolCallRecord,
504};
505
506pub use hooks::{AgentHooks, CompositeHooks, HookTimer, LoggingHooks, NoopHooks};
507
508pub use hitl::{
509    ApprovalCondition, ApprovalHandler, ApprovalMessage, ApprovalRequest, ApprovalResult,
510    ApprovalTrigger, AutoApproveHandler, HITLCheckResult, HITLConfig, HITLEngine,
511    LlmGenerateConfig, LocalizedHandler, MessageLanguageConfig, MessageLanguageStrategy,
512    MessageResolver, RejectAllHandler, StateApprovalConfig, StateApprovalTrigger, TimeoutAction,
513    ToolApprovalConfig, create_handler, create_localized_handler, resolve_best_language,
514    resolve_tool_message,
515};
516
517// Tool Provider System (v0.5.1 - Simplified)
518pub use tools::{
519    ProviderHealth, ToolAliases, ToolContext, ToolDescriptor, ToolMetadata, ToolProvider,
520    ToolProviderError, ToolProviderType, TrustLevel,
521};
522
523// Reasoning & Reflection (v0.5.3)
524pub use reasoning::{
525    CriterionResult, EvaluationResult, Plan, PlanAction, PlanAvailableActions,
526    PlanReflectionConfig, PlanStatus, PlanStep, PlanningConfig, ReasoningConfig, ReasoningMetadata,
527    ReasoningMode, ReasoningOutput, ReflectionAttempt, ReflectionConfig, ReflectionMetadata,
528    ReflectionMode, StepFailureAction, StepStatus, StringOrList,
529};
530
531// Intent Disambiguation (v0.5.4)
532pub use disambiguation::{
533    AmbiguityAspect, AmbiguityDetectionResult, AmbiguityDetector, AmbiguityType, CacheConfig,
534    ClarificationConfig, ClarificationGenerator, ClarificationOption, ClarificationParseResult,
535    ClarificationQuestion, ClarificationStyle, ContextConfig, DetectionConfig,
536    DisambiguationConfig, DisambiguationContext, DisambiguationManager, DisambiguationResult,
537    MaxAttemptsAction, SkillDisambiguationOverride, SkipCondition, StateDisambiguationOverride,
538};