agents_runtime/agent/
api.rs

1//! Public API functions that mirror the Python SDK exactly
2//!
3//! This module provides the main entry points for creating Deep Agents,
4//! matching the Python `create_deep_agent()` and `async_create_deep_agent()` functions.
5
6use super::builder::ConfigurableAgentBuilder;
7use super::config::{CreateDeepAgentParams, DeepAgentConfig};
8use super::runtime::DeepAgent;
9use crate::providers::{OpenAiChatModel, OpenAiConfig};
10use agents_core::llm::LanguageModel;
11use std::sync::Arc;
12
13/// Returns the default language model configured
14/// Uses OpenAI GPT-4o-mini for cost-effective operation.
15/// This model provides excellent performance at a fraction of the cost compared to larger models.
16///
17/// Cost comparison:
18/// - GPT-4o-mini: $0.15/1M input tokens, $0.60/1M output tokens
19/// - Claude Sonnet 4: $3.00/1M input tokens, $15.00/1M output tokens
20///
21///   = ~95% cost savings!
22pub fn get_default_model() -> anyhow::Result<Arc<dyn LanguageModel>> {
23    let config = OpenAiConfig {
24        api_key: std::env::var("OPENAI_API_KEY")
25            .map_err(|_| anyhow::anyhow!("OPENAI_API_KEY environment variable is required"))?,
26        model: "gpt-4o-mini".to_string(),
27        api_url: None,
28        custom_headers: Vec::new(),
29    };
30    let model: Arc<dyn LanguageModel> = Arc::new(OpenAiChatModel::new(config)?);
31    Ok(model)
32}
33
34/// Create a deep agent - matches Python create_deep_agent() API exactly
35///
36/// This is the main entry point that mirrors the Python SDK:
37/// ```python
38/// agent = create_deep_agent(
39///     tools=[internet_search],
40///     instructions="You are an expert researcher...",
41///     model=model,
42///     subagents=subagents,
43///     checkpointer=checkpointer,
44///     tool_configs=tool_configs
45/// )
46/// ```
47pub fn create_deep_agent(params: CreateDeepAgentParams) -> anyhow::Result<DeepAgent> {
48    let CreateDeepAgentParams {
49        tools,
50        instructions,
51        middleware,
52        model,
53        subagents,
54        context_schema,
55        checkpointer,
56        tool_configs,
57    } = params;
58
59    if context_schema.is_some() {
60        tracing::warn!(
61            "context_schema parameter for create_deep_agent is not yet supported in Rust SDK"
62        );
63    }
64
65    if !middleware.is_empty() {
66        tracing::warn!("middleware parameter for create_deep_agent is not yet supported in Rust SDK ({} entries)", middleware.len());
67    }
68
69    let mut builder = ConfigurableAgentBuilder::new(instructions);
70
71    let model = match model {
72        Some(model) => model,
73        None => get_default_model()?,
74    };
75    builder = builder.with_model(model);
76
77    if !tools.is_empty() {
78        builder = builder.with_tools(tools);
79    }
80
81    if !subagents.is_empty() {
82        builder = builder.with_subagent_config(subagents);
83    }
84
85    if let Some(checkpointer) = checkpointer {
86        builder = builder.with_checkpointer(checkpointer);
87    }
88
89    if !tool_configs.is_empty() {
90        for (tool, policy) in tool_configs {
91            builder = builder.with_tool_interrupt(tool, policy);
92        }
93    }
94
95    builder.build()
96}
97
98/// Async constructor alias to mirror the Python API surface.
99///
100/// The underlying runtime already executes every tool and planner call asynchronously,
101/// so this currently delegates to `create_deep_agent`.
102///
103/// Mirrors Python's `async_create_deep_agent()` function.
104pub fn create_async_deep_agent(params: CreateDeepAgentParams) -> anyhow::Result<DeepAgent> {
105    create_deep_agent(params)
106}
107
108/// Internal function used by the builder - creates agent from config
109pub(crate) fn create_deep_agent_from_config(config: DeepAgentConfig) -> DeepAgent {
110    super::runtime::create_deep_agent_from_config(config)
111}
112
113/// Internal async alias used by the builder
114pub(crate) fn create_async_deep_agent_from_config(config: DeepAgentConfig) -> DeepAgent {
115    super::runtime::create_deep_agent_from_config(config)
116}