Skip to main content

adk_rust/
lib.rs

1//! # Agent Development Kit (ADK) for Rust
2//!
3//! [![Crates.io](https://img.shields.io/crates/v/adk-rust.svg)](https://crates.io/crates/adk-rust)
4//! [![Documentation](https://docs.rs/adk-rust/badge.svg)](https://docs.rs/adk-rust)
5//! [![License](https://img.shields.io/crates/l/adk-rust.svg)](https://github.com/zavora-ai/adk-rust/blob/main/LICENSE)
6//!
7//! A flexible and modular framework for developing and deploying AI agents in Rust.
8//! While optimized for Gemini and the Google ecosystem, ADK is model-agnostic,
9//! deployment-agnostic, and compatible with other frameworks.
10//!
11//! ## Quick Start
12//!
13//! Create your first AI agent in minutes:
14//!
15//! ```ignore
16//! use adk_rust::prelude::*;
17//! use adk_rust::Launcher;
18//! use std::sync::Arc;
19//!
20//! #[tokio::main]
21//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//!     let api_key = std::env::var("GOOGLE_API_KEY")?;
23//!     let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
24//!
25//!     let agent = LlmAgentBuilder::new("assistant")
26//!         .description("A helpful AI assistant")
27//!         .instruction("You are a friendly assistant. Answer questions concisely.")
28//!         .model(Arc::new(model))
29//!         .build()?;
30//!
31//!     // Run in interactive console mode
32//!     Launcher::new(Arc::new(agent)).run().await?;
33//!     Ok(())
34//! }
35//! ```
36//!
37//! ## Installation
38//!
39//! Add to your `Cargo.toml`:
40//!
41//! ```toml
42//! [dependencies]
43//! adk-rust = "0.6.0"
44//! tokio = { version = "1.40", features = ["full"] }
45//! dotenvy = "0.15"  # For loading .env files
46//! ```
47//!
48//! ### Feature Presets
49//!
50//! ```toml
51//! # Standard (default) — agents, models, tools, sessions, runner, guardrails, auth
52//! adk-rust = "0.6.0"
53//!
54//! # Full — standard + all stable specialist crates (graph, realtime, browser, eval, rag)
55//! # Does NOT include experimental crates (code, sandbox, audio) — use `labs` for those
56//! adk-rust = { version = "0.6.0", features = ["full"] }
57//!
58//! # Labs — standard + experimental crates (code, sandbox, audio)
59//! adk-rust = { version = "0.6.0", features = ["labs"] }
60//!
61//! # Full + Labs — everything including experimental crates
62//! adk-rust = { version = "0.6.0", features = ["full", "labs"] }
63//!
64//! # Minimal — just agents + Gemini + runner (fastest build)
65//! adk-rust = { version = "0.6.0", default-features = false, features = ["minimal"] }
66//!
67//! # Custom — pick exactly what you need
68//! adk-rust = { version = "0.6.0", default-features = false, features = [
69//!     "agents", "gemini", "tools", "sessions", "openai", "openrouter"
70//! ] }
71//! ```
72//!
73//! ## Agent Types
74//!
75//! ADK-Rust provides several agent types for different use cases:
76//!
77//! ### LlmAgent - AI-Powered Reasoning
78//!
79//! The core agent type that uses Large Language Models for intelligent reasoning:
80//!
81//! ```no_run
82//! use adk_rust::prelude::*;
83//! use std::sync::Arc;
84//!
85//! # async fn example() -> Result<()> {
86//! let api_key = std::env::var("GOOGLE_API_KEY").map_err(|e| AdkError::config(e.to_string()))?;
87//! let model = GeminiModel::new(&api_key, "gemini-2.5-flash")?;
88//!
89//! let agent = LlmAgentBuilder::new("researcher")
90//!     .description("Research assistant with web search")
91//!     .instruction("Search for information and provide detailed summaries.")
92//!     .model(Arc::new(model))
93//!     .tool(Arc::new(GoogleSearchTool::new()))  // Add tools
94//!     .build()?;
95//! # Ok(())
96//! # }
97//! ```
98//!
99//! ### Workflow Agents - Deterministic Pipelines
100//!
101//! For predictable, multi-step workflows:
102//!
103//! ```no_run
104//! use adk_rust::prelude::*;
105//! use std::sync::Arc;
106//!
107//! # async fn example() -> Result<()> {
108//! # let researcher: Arc<dyn Agent> = todo!();
109//! # let writer: Arc<dyn Agent> = todo!();
110//! # let reviewer: Arc<dyn Agent> = todo!();
111//! // Sequential: Execute agents in order
112//! let pipeline = SequentialAgent::new(
113//!     "content_pipeline",
114//!     vec![researcher, writer, reviewer]
115//! );
116//!
117//! // Parallel: Execute agents concurrently
118//! # let analyst1: Arc<dyn Agent> = todo!();
119//! # let analyst2: Arc<dyn Agent> = todo!();
120//! let parallel = ParallelAgent::new(
121//!     "multi_analysis",
122//!     vec![analyst1, analyst2]
123//! );
124//!
125//! // Loop: Iterate until condition met
126//! # let refiner: Arc<dyn Agent> = todo!();
127//! let loop_agent = LoopAgent::new("iterative_refiner", vec![refiner])
128//!     .with_max_iterations(5);
129//! # Ok(())
130//! # }
131//! ```
132//!
133//! ### Multi-Agent Systems
134//!
135//! Build hierarchical agent systems with automatic delegation:
136//!
137//! ```no_run
138//! use adk_rust::prelude::*;
139//! use std::sync::Arc;
140//!
141//! # async fn example() -> Result<()> {
142//! # let model: Arc<dyn Llm> = todo!();
143//! # let code_agent: Arc<dyn Agent> = todo!();
144//! # let test_agent: Arc<dyn Agent> = todo!();
145//! let coordinator = LlmAgentBuilder::new("coordinator")
146//!     .description("Development team coordinator")
147//!     .instruction("Delegate coding tasks to specialists.")
148//!     .model(model)
149//!     .sub_agent(code_agent)   // Delegate to sub-agents
150//!     .sub_agent(test_agent)
151//!     .build()?;
152//! # Ok(())
153//! # }
154//! ```
155//!
156//! ## Tools
157//!
158//! Give your agents capabilities beyond conversation:
159//!
160//! ### Function Tools - Custom Operations
161//!
162//! Convert any async function into a tool:
163//!
164//! ```no_run
165//! use adk_rust::prelude::*;
166//! use adk_rust::serde_json::{json, Value};
167//! use std::sync::Arc;
168//!
169//! async fn get_weather(_ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
170//!     let city = args["city"].as_str().unwrap_or("Unknown");
171//!     // Your weather API call here
172//!     Ok(json!({
173//!         "temperature": 72.0,
174//!         "conditions": "Sunny",
175//!         "city": city
176//!     }))
177//! }
178//!
179//! # fn example() -> Result<()> {
180//! let weather_tool = FunctionTool::new(
181//!     "get_weather",
182//!     "Get current weather for a city",
183//!     get_weather,
184//! );
185//! # Ok(())
186//! # }
187//! ```
188//!
189//! ### Built-in Tools
190//!
191//! Ready-to-use tools included with ADK:
192//!
193//! - [`GoogleSearchTool`](tool::GoogleSearchTool) - Web search via Google
194//! - [`ExitLoopTool`](tool::ExitLoopTool) - Control loop termination
195//! - [`LoadArtifactsTool`](tool::LoadArtifactsTool) - Access stored artifacts
196//!
197//! ### MCP Tools - External Integrations
198//!
199//! Connect to Model Context Protocol servers using the `rmcp` crate:
200//!
201//! ```ignore
202//! use adk_rust::prelude::*;
203//! use adk_rust::tool::McpToolset;
204//! use rmcp::{ServiceExt, transport::TokioChildProcess};
205//! use tokio::process::Command;
206//!
207//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
208//! // Connect to an MCP server (e.g., filesystem, database)
209//! let client = ().serve(TokioChildProcess::new(
210//!     Command::new("npx")
211//!         .arg("-y")
212//!         .arg("@anthropic/mcp-server-filesystem")
213//!         .arg("/path/to/dir")
214//! )?).await?;
215//!
216//! let mcp_tools = McpToolset::new(client);
217//!
218//! // Add all MCP tools to your agent
219//! # let builder: LlmAgentBuilder = todo!();
220//! let agent = builder.toolset(Arc::new(mcp_tools)).build()?;
221//! # Ok(())
222//! # }
223//! ```
224//!
225//! ## Sessions & State
226//!
227//! Manage conversation context and working memory:
228//!
229//! ```no_run
230//! use adk_rust::prelude::*;
231//! use adk_rust::session::{SessionService, CreateRequest};
232//! use adk_rust::serde_json::json;
233//! use std::collections::HashMap;
234//!
235//! # async fn example() -> Result<()> {
236//! let session_service = InMemorySessionService::new();
237//!
238//! // Create a session
239//! let session = session_service.create(CreateRequest {
240//!     app_name: "my_app".to_string(),
241//!     user_id: "user_123".to_string(),
242//!     session_id: None,
243//!     state: HashMap::new(),
244//! }).await?;
245//!
246//! // Read state (State trait provides read access)
247//! let state = session.state();
248//! let config = state.get("app:config");  // Returns Option<Value>
249//! # Ok(())
250//! # }
251//! ```
252//!
253//! ## Callbacks
254//!
255//! Intercept and customize agent behavior:
256//!
257//! ```no_run
258//! use adk_rust::prelude::*;
259//! use std::sync::Arc;
260//!
261//! # async fn example() -> Result<()> {
262//! # let model: Arc<dyn Llm> = todo!();
263//! let agent = LlmAgentBuilder::new("monitored_agent")
264//!     .model(model)
265//!     // Modify or inspect model responses
266//!     .after_model_callback(Box::new(|_ctx, response| {
267//!         Box::pin(async move {
268//!             println!("Model responded");
269//!             Ok(Some(response)) // Return modified response or None to keep original
270//!         })
271//!     }))
272//!     // Track tool usage
273//!     .before_tool_callback(Box::new(|_ctx| {
274//!         Box::pin(async move {
275//!             println!("Tool about to be called");
276//!             Ok(None) // Continue execution
277//!         })
278//!     }))
279//!     .build()?;
280//! # Ok(())
281//! # }
282//! ```
283//!
284//! ## Artifacts
285//!
286//! Store and retrieve binary data (images, files, etc.):
287//!
288//! ```no_run
289//! use adk_rust::prelude::*;
290//! use adk_rust::artifact::{ArtifactService, SaveRequest, LoadRequest};
291//!
292//! # async fn example() -> Result<()> {
293//! let artifact_service = InMemoryArtifactService::new();
294//!
295//! // Save an artifact
296//! let response = artifact_service.save(SaveRequest {
297//!     app_name: "my_app".to_string(),
298//!     user_id: "user_123".to_string(),
299//!     session_id: "session_456".to_string(),
300//!     file_name: "sales_chart.png".to_string(),
301//!     part: Part::Text { text: "chart data".to_string() },
302//!     version: None,
303//! }).await?;
304//!
305//! // Load an artifact
306//! let loaded = artifact_service.load(LoadRequest {
307//!     app_name: "my_app".to_string(),
308//!     user_id: "user_123".to_string(),
309//!     session_id: "session_456".to_string(),
310//!     file_name: "sales_chart.png".to_string(),
311//!     version: None,
312//! }).await?;
313//! # Ok(())
314//! # }
315//! ```
316//!
317//! ## Deployment Options
318//!
319//! ### Console Mode (Interactive CLI)
320//!
321//! ```no_run
322//! use adk_rust::prelude::*;
323//! use adk_rust::Launcher;
324//! use std::sync::Arc;
325//!
326//! # async fn example() -> Result<()> {
327//! # let agent: Arc<dyn Agent> = todo!();
328//! // Interactive chat in terminal
329//! Launcher::new(agent).run().await?;
330//! # Ok(())
331//! # }
332//! ```
333//!
334//! ### Server Mode (REST API)
335//!
336//! ```bash
337//! # Run your agent as a web server
338//! cargo run -- serve --port 8080
339//! ```
340//!
341//! Provides endpoints:
342//! - `POST /chat` - Send messages
343//! - `GET /sessions` - List sessions
344//! - `GET /health` - Health check
345//!
346//! ### Agent-to-Agent (A2A) Protocol
347//!
348//! Expose your agent for inter-agent communication:
349//!
350//! ```no_run
351//! use adk_rust::server::{create_app_with_a2a, ServerConfig};
352//! use adk_rust::AgentLoader;
353//!
354//! # async fn example() -> adk_rust::Result<()> {
355//! # let agent_loader: std::sync::Arc<dyn AgentLoader> = todo!();
356//! # let session_service: std::sync::Arc<dyn adk_rust::session::SessionService> = todo!();
357//! // Create server with A2A protocol support
358//! let config = ServerConfig::new(agent_loader, session_service);
359//! let app = create_app_with_a2a(config, Some("http://localhost:8080"));
360//!
361//! // Run the server (requires axum dependency)
362//! // let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
363//! // axum::serve(listener, app).await?;
364//! # Ok(())
365//! # }
366//! ```
367//!
368//! ## Observability
369//!
370//! Built-in OpenTelemetry support for production monitoring:
371//!
372//! ```no_run
373//! use adk_rust::telemetry::{init_telemetry, init_with_otlp};
374//!
375//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
376//! // Basic telemetry with console logging
377//! init_telemetry("my-agent-service")?;
378//!
379//! // Or with OTLP export for distributed tracing
380//! // init_with_otlp("my-agent-service", "http://localhost:4317")?;
381//!
382//! // All agent operations now emit traces and metrics
383//! # Ok(())
384//! # }
385//! ```
386//!
387//! ## Architecture
388//!
389//! ADK-Rust uses a layered architecture for modularity:
390//!
391//! ```text
392//! ┌─────────────────────────────────────────────────────────────┐
393//! │                    Application Layer                        │
394//! │              Launcher • REST Server • A2A                   │
395//! ├─────────────────────────────────────────────────────────────┤
396//! │                      Runner Layer                           │
397//! │           Agent Execution • Event Streaming                 │
398//! ├─────────────────────────────────────────────────────────────┤
399//! │                      Agent Layer                            │
400//! │    LlmAgent • CustomAgent • Sequential • Parallel • Loop    │
401//! ├─────────────────────────────────────────────────────────────┤
402//! │                     Service Layer                           │
403//! │      Models • Tools • Sessions • Artifacts • Memory         │
404//! └─────────────────────────────────────────────────────────────┘
405//! ```
406//!
407//! ## Feature Flags
408//!
409//! | Feature | Description | Preset |
410//! |---------|-------------|--------|
411//! | `agents` | Agent implementations | standard |
412//! | `models` | Model integrations | standard |
413//! | `gemini` | Gemini model support | standard |
414//! | `tools` | Tool system | standard |
415//! | `skills` | Skill discovery | standard |
416//! | `sessions` | Session management | standard |
417//! | `artifacts` | Artifact storage | standard |
418//! | `memory` | Semantic memory | standard |
419//! | `runner` | Execution runtime | standard |
420//! | `telemetry` | OpenTelemetry | standard |
421//! | `guardrail` | Input/output validation | standard |
422//! | `auth` | Access control | standard |
423//! | `plugin` | Plugin system | standard |
424//! | `server` | HTTP server + A2A | standard |
425//! | `cli` | CLI launcher | standard |
426//! | `graph` | Graph workflows | full |
427//! | `browser` | Browser automation | full |
428//! | `eval` | Agent evaluation | full |
429//! | `realtime` | Voice/audio streaming | full |
430//! | `rag` | RAG pipeline | full |
431//! | `code` | Code execution | labs (experimental) |
432//! | `sandbox` | Sandboxed execution | labs (experimental) |
433//! | `audio` | Audio processing | labs (experimental) |
434//!
435//! ## Examples
436//!
437//! The [examples directory](https://github.com/zavora-ai/adk-rust/tree/main/examples)
438//! contains working examples for every feature:
439//!
440//! - **Agents**: LLM agent, workflow agents, multi-agent systems
441//! - **Tools**: Function tools, Google Search, MCP integration
442//! - **Sessions**: State management, conversation history
443//! - **Callbacks**: Logging, guardrails, caching
444//! - **Deployment**: Console, server, A2A protocol
445//!
446//! ## Related Crates
447//!
448//! ADK-Rust is composed of modular crates that can be used independently:
449//!
450//! - [`adk-core`](https://docs.rs/adk-core) - Core traits and types
451//! - [`adk-agent`](https://docs.rs/adk-agent) - Agent implementations
452//! - [`adk-model`](https://docs.rs/adk-model) - LLM integrations
453//! - [`adk-tool`](https://docs.rs/adk-tool) - Tool system
454//! - [`adk-session`](https://docs.rs/adk-session) - Session management
455//! - [`adk-artifact`](https://docs.rs/adk-artifact) - Artifact storage
456//! - [`adk-runner`](https://docs.rs/adk-runner) - Execution runtime
457//! - [`adk-server`](https://docs.rs/adk-server) - HTTP server
458//! - [`adk-telemetry`](https://docs.rs/adk-telemetry) - Observability
459
460#![warn(missing_docs)]
461#![cfg_attr(docsrs, feature(doc_cfg))]
462
463// ============================================================================
464// Core (always available)
465// ============================================================================
466
467/// Core traits and types.
468///
469/// Always available regardless of feature flags. Includes:
470/// - [`Agent`] - The fundamental trait for all agents
471/// - [`Tool`] / [`Toolset`] - For extending agents with capabilities
472/// - [`Session`] / [`State`] - For managing conversation context
473/// - [`Event`] - For streaming agent responses
474/// - [`AdkError`] / [`Result`] - Unified error handling
475pub use adk_core::*;
476
477// Re-export common dependencies for convenience
478pub use anyhow;
479pub use async_trait::async_trait;
480pub use futures;
481pub use serde;
482pub use serde_json;
483pub use tokio;
484
485// ============================================================================
486// Component Modules (feature-gated)
487// ============================================================================
488
489/// Agent implementations (LLM, Custom, Workflow agents).
490///
491/// Provides the core agent types:
492/// - [`LlmAgent`](agent::LlmAgent) - AI-powered agent using LLMs
493/// - [`CustomAgent`](agent::CustomAgent) - Implement custom agent logic
494/// - [`SequentialAgent`](agent::SequentialAgent) - Execute agents in sequence
495/// - [`ParallelAgent`](agent::ParallelAgent) - Execute agents concurrently
496/// - [`LoopAgent`](agent::LoopAgent) - Iterative execution until condition met
497///
498/// Available with feature: `agents`
499#[cfg(feature = "agents")]
500#[cfg_attr(docsrs, doc(cfg(feature = "agents")))]
501pub mod agent {
502    pub use adk_agent::*;
503}
504
505/// Model integrations (Gemini, etc.).
506///
507/// Provides LLM implementations:
508/// - [`GeminiModel`](model::GeminiModel) - Google's Gemini models
509///
510/// ADK is model-agnostic - implement the [`Llm`] trait for other providers.
511///
512/// Available with feature: `models`
513#[cfg(feature = "models")]
514#[cfg_attr(docsrs, doc(cfg(feature = "models")))]
515pub mod model {
516    pub use adk_model::*;
517}
518
519/// Tool system and built-in tools.
520///
521/// Give agents capabilities beyond conversation:
522/// - [`FunctionTool`](tool::FunctionTool) - Wrap async functions as tools
523/// - [`GoogleSearchTool`](tool::GoogleSearchTool) - Web search
524/// - [`ExitLoopTool`](tool::ExitLoopTool) - Control loop agents
525/// - [`McpToolset`](tool::McpToolset) - MCP server integration
526///
527/// Available with feature: `tools`
528#[cfg(feature = "tools")]
529#[cfg_attr(docsrs, doc(cfg(feature = "tools")))]
530pub mod tool {
531    pub use adk_tool::*;
532}
533
534/// AgentSkills parsing, indexing, and runtime injection helpers.
535///
536/// Provides:
537/// - Skill file discovery from `.skills/`
538/// - Frontmatter validation (`name`, `description`)
539/// - Lexical skill selection
540/// - Runner plugin helper for skill injection
541///
542/// Available with feature: `skills`
543#[cfg(feature = "skills")]
544#[cfg_attr(docsrs, doc(cfg(feature = "skills")))]
545pub mod skill {
546    pub use adk_skill::*;
547}
548
549/// Session management.
550///
551/// Manage conversation context and state:
552/// - [`InMemorySessionService`](session::InMemorySessionService) - In-memory sessions
553/// - Session creation, retrieval, and lifecycle
554/// - State management with scoped prefixes
555///
556/// Available with feature: `sessions`
557#[cfg(feature = "sessions")]
558#[cfg_attr(docsrs, doc(cfg(feature = "sessions")))]
559pub mod session {
560    pub use adk_session::*;
561}
562
563/// Artifact storage.
564///
565/// Store and retrieve binary data:
566/// - [`InMemoryArtifactService`](artifact::InMemoryArtifactService) - In-memory storage
567/// - Version tracking for artifacts
568/// - Namespace scoping
569///
570/// Available with feature: `artifacts`
571#[cfg(feature = "artifacts")]
572#[cfg_attr(docsrs, doc(cfg(feature = "artifacts")))]
573pub mod artifact {
574    pub use adk_artifact::*;
575}
576
577/// Memory system with semantic search.
578///
579/// Long-term memory for agents:
580/// - [`InMemoryMemoryService`](memory::InMemoryMemoryService) - In-memory storage
581/// - Semantic search capabilities
582/// - Memory retrieval and updates
583///
584/// Available with feature: `memory`
585#[cfg(feature = "memory")]
586#[cfg_attr(docsrs, doc(cfg(feature = "memory")))]
587pub mod memory {
588    pub use adk_memory::*;
589}
590
591/// Agent execution runtime.
592///
593/// The engine that manages agent execution:
594/// - [`Runner`](runner::Runner) - Executes agents with full context
595/// - [`RunnerConfig`](runner::RunnerConfig) - Configuration options
596/// - Event streaming and tool coordination
597///
598/// Available with feature: `runner`
599#[cfg(feature = "runner")]
600#[cfg_attr(docsrs, doc(cfg(feature = "runner")))]
601pub mod runner {
602    pub use adk_runner::*;
603}
604
605/// HTTP server (REST + A2A).
606///
607/// Deploy agents as web services:
608/// - REST API for chat interactions
609/// - A2A (Agent-to-Agent) protocol support
610/// - Web UI integration
611///
612/// Available with feature: `server`
613#[cfg(feature = "server")]
614#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
615pub mod server {
616    pub use adk_server::*;
617}
618
619/// Telemetry (OpenTelemetry integration).
620///
621/// Production observability:
622/// - Distributed tracing
623/// - Metrics collection
624/// - Log correlation
625///
626/// Available with feature: `telemetry`
627#[cfg(feature = "telemetry")]
628#[cfg_attr(docsrs, doc(cfg(feature = "telemetry")))]
629pub mod telemetry {
630    pub use adk_telemetry::*;
631}
632
633/// Graph-based workflow engine (LangGraph-inspired).
634///
635/// Build complex agent workflows with:
636/// - [`StateGraph`](graph::StateGraph) - Graph builder with nodes and edges
637/// - [`GraphAgent`](graph::GraphAgent) - ADK Agent integration
638/// - [`Checkpointer`](graph::Checkpointer) - Persistent state for human-in-the-loop
639/// - [`Router`](graph::Router) - Conditional edge routing helpers
640/// - Cycle support with recursion limits
641/// - Streaming execution modes
642///
643/// Available with feature: `graph`
644#[cfg(feature = "graph")]
645#[cfg_attr(docsrs, doc(cfg(feature = "graph")))]
646pub mod graph {
647    pub use adk_graph::*;
648}
649
650/// Code execution substrate (experimental — `labs` preset).
651///
652/// First-class code execution for agents, Studio, and generated projects:
653/// - [`CodeExecutor`](code::CodeExecutor) - Backend trait for execution
654/// - [`ExecutionRequest`](code::ExecutionRequest) - Typed execution request
655/// - [`ExecutionResult`](code::ExecutionResult) - Structured execution result
656/// - [`SandboxPolicy`](code::SandboxPolicy) - Sandbox capability model
657/// - [`Workspace`](code::Workspace) - Collaborative project context
658///
659/// Available with feature: `code`
660#[cfg(feature = "code")]
661#[cfg_attr(docsrs, doc(cfg(feature = "code")))]
662pub mod code {
663    pub use adk_code::*;
664}
665
666/// Isolated code execution runtime (experimental — `labs` preset).
667///
668/// Provides the [`SandboxBackend`](sandbox::SandboxBackend) trait and built-in backends:
669/// - [`ProcessBackend`](sandbox::ProcessBackend) - Subprocess execution with timeout and env isolation
670/// - `WasmBackend` - In-process WASM execution via wasmtime (requires `wasm` feature)
671/// - [`SandboxTool`](sandbox::SandboxTool) - Tool trait implementation for agent integration
672///
673/// Available with feature: `sandbox`
674#[cfg(feature = "sandbox")]
675#[cfg_attr(docsrs, doc(cfg(feature = "sandbox")))]
676pub mod sandbox {
677    pub use adk_sandbox::*;
678}
679
680/// CLI launcher for running agents.
681///
682/// Quick way to run agents in console or server mode:
683/// - [`Launcher`] - Main entry point for CLI apps
684///
685/// Available with feature: `cli`
686#[cfg(feature = "cli")]
687#[cfg_attr(docsrs, doc(cfg(feature = "cli")))]
688pub use adk_cli::Launcher;
689
690/// Real-time bidirectional streaming (voice, video).
691///
692/// Provides real-time audio/video streaming for voice-enabled agents:
693/// - [`RealtimeAgent`](realtime::RealtimeAgent) - Agent with voice capabilities
694/// - [`RealtimeRunner`](realtime::RealtimeRunner) - Session management and tool execution
695/// - Multiple providers: OpenAI Realtime, Gemini Live
696///
697/// Available with feature: `realtime`
698#[cfg(feature = "realtime")]
699#[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
700pub mod realtime {
701    pub use adk_realtime::*;
702}
703
704/// Browser automation (WebDriver).
705///
706/// Provides browser automation tools for agents:
707/// - [`BrowserSession`](browser::BrowserSession) - WebDriver session management
708/// - [`BrowserToolset`](browser::BrowserToolset) - Browser tools for agents
709///
710/// Available with feature: `browser`
711#[cfg(feature = "browser")]
712#[cfg_attr(docsrs, doc(cfg(feature = "browser")))]
713pub mod browser {
714    pub use adk_browser::*;
715}
716
717/// Agent evaluation framework.
718///
719/// Test and validate agent behavior:
720/// - [`Evaluator`](eval::Evaluator) - Run evaluation suites
721/// - [`EvaluationConfig`](eval::EvaluationConfig) - Configure evaluation parameters
722///
723/// Available with feature: `eval`
724#[cfg(feature = "eval")]
725#[cfg_attr(docsrs, doc(cfg(feature = "eval")))]
726pub mod eval {
727    pub use adk_eval::*;
728}
729
730/// Guardrails for safety and policy enforcement.
731///
732/// Validate agent inputs and outputs:
733/// - [`GuardrailSet`](guardrail::GuardrailSet) - Collection of guardrails
734/// - [`ContentFilter`](guardrail::ContentFilter) - Content safety filtering
735///
736/// Available with feature: `guardrail`
737#[cfg(feature = "guardrail")]
738#[cfg_attr(docsrs, doc(cfg(feature = "guardrail")))]
739pub mod guardrail {
740    pub use adk_guardrail::*;
741}
742
743/// Authentication and access control.
744///
745/// Manage agent permissions and identity:
746/// - [`Permission`](auth::Permission) - Permission definitions
747/// - [`AccessControl`](auth::AccessControl) - Access control enforcement
748///
749/// Available with feature: `auth`
750#[cfg(feature = "auth")]
751#[cfg_attr(docsrs, doc(cfg(feature = "auth")))]
752pub mod auth {
753    pub use adk_auth::*;
754}
755
756/// Agentic commerce and payment orchestration.
757///
758/// Provides protocol-neutral payment primitives and adapters for:
759/// - ACP stable `2026-01-30`
760/// - ACP experimental surfaces behind `acp-experimental`
761/// - AP2 `v0.1-alpha` as of `2026-03-22`
762///
763/// Available with feature: `payments`
764#[cfg(feature = "payments")]
765#[cfg_attr(docsrs, doc(cfg(feature = "payments")))]
766pub mod payment {
767    pub use adk_payments::*;
768}
769
770/// Plugin system for extending agent behavior.
771///
772/// Extensible callback architecture for agent lifecycle hooks:
773/// - Plugin registration and discovery
774/// - Before/after hooks for agent operations
775///
776/// Available with feature: `plugin`
777#[cfg(feature = "plugin")]
778#[cfg_attr(docsrs, doc(cfg(feature = "plugin")))]
779pub mod plugin {
780    pub use adk_plugin::*;
781}
782
783/// Audio processing pipeline (experimental — `labs` preset).
784///
785/// Provides audio capabilities for agents:
786/// - [`TtsProvider`](audio::TtsProvider) - Text-to-speech synthesis
787/// - [`SttProvider`](audio::SttProvider) - Speech-to-text transcription
788/// - [`AudioProcessor`](audio::AudioProcessor) - Audio effects processing
789/// - `AudioPipeline` - Composable audio pipelines
790/// - Cloud providers: ElevenLabs, OpenAI, Gemini, Cartesia, Deepgram, AssemblyAI
791/// - Local inference: MLX (Apple Silicon), ONNX Runtime
792///
793/// Available with feature: `audio`
794#[cfg(feature = "audio")]
795#[cfg_attr(docsrs, doc(cfg(feature = "audio")))]
796pub mod audio {
797    pub use adk_audio::*;
798}
799
800/// Retrieval-Augmented Generation (RAG) pipeline.
801///
802/// Modular RAG system with trait-based components:
803/// - [`RagPipeline`](rag::RagPipeline) - Orchestrates ingest and query workflows
804/// - [`RagTool`](rag::RagTool) - Agentic retrieval via `Tool` trait
805/// - [`InMemoryVectorStore`](rag::InMemoryVectorStore) - Zero-dependency vector store
806/// - Chunking strategies: fixed-size, recursive, markdown-aware
807/// - Feature-gated backends: Gemini, OpenAI, Qdrant, LanceDB, pgvector
808///
809/// Available with feature: `rag`
810#[cfg(feature = "rag")]
811#[cfg_attr(docsrs, doc(cfg(feature = "rag")))]
812pub mod rag {
813    pub use adk_rag::*;
814}
815
816/// Shared action node types for graph workflows.
817///
818/// Provides the type definitions for all 14 action node types:
819/// - Trigger nodes (manual, webhook, schedule, event)
820/// - Data nodes (HTTP, Set, Transform)
821/// - Control flow nodes (Switch, Loop, Merge, Wait)
822/// - Compute nodes (Code)
823/// - Infrastructure nodes (Database)
824/// - Communication nodes (Email, Notification, RSS, File)
825///
826/// Available with feature: `action`
827#[cfg(feature = "action")]
828#[cfg_attr(docsrs, doc(cfg(feature = "action")))]
829pub use adk_action;
830
831/// Anthropic API client types and HTTP client.
832///
833/// Direct access to the `adk-anthropic` crate for low-level Anthropic API usage:
834/// - [`Anthropic`](anthropic_client::Anthropic) - HTTP client struct
835/// - Wire types: `MessageCreateParams`, `Message`, `ContentBlock`, etc.
836/// - Streaming: `MessageStreamEvent`, `ContentBlockDelta`
837/// - Error handling: `Error` enum with typed variants
838///
839/// For high-level agent usage, prefer `adk-model`'s `AnthropicClient` instead.
840///
841/// Available with feature: `anthropic-client`
842#[cfg(feature = "anthropic-client")]
843#[cfg_attr(docsrs, doc(cfg(feature = "anthropic-client")))]
844pub mod anthropic_client {
845    pub use adk_anthropic::*;
846}
847
848// ============================================================================
849// v0.7.0 Competitive Parity Feature Re-exports (opt-in only)
850// ============================================================================
851
852// --- adk-server features ---
853
854/// YAML agent configuration loader and hot reload watcher.
855///
856/// Declaratively define agents in YAML files with hot reload support:
857/// - [`YamlAgentDefinition`](server::yaml_agent::YamlAgentDefinition) - YAML schema types
858/// - [`AgentConfigLoader`](server::yaml_agent::AgentConfigLoader) - Load and validate YAML agent files
859/// - [`HotReloadWatcher`](server::yaml_agent::HotReloadWatcher) - Watch for file changes and reload agents
860///
861/// Available with feature: `yaml-agent`
862#[cfg(feature = "yaml-agent")]
863#[cfg_attr(docsrs, doc(cfg(feature = "yaml-agent")))]
864pub mod yaml_agent {
865    pub use adk_server::yaml_agent::*;
866}
867
868/// Agent Registry REST API for agent discovery and management.
869///
870/// Register, discover, and manage agents through a REST API:
871/// - [`AgentCard`](server::registry::AgentCard) - Agent metadata
872/// - [`AgentRegistryStore`](server::registry::AgentRegistryStore) - Storage backend trait
873/// - [`InMemoryAgentRegistryStore`](server::registry::InMemoryAgentRegistryStore) - In-memory storage
874/// - [`registry_router`](server::registry::registry_router) - Axum router for registry endpoints
875///
876/// Available with feature: `agent-registry`
877#[cfg(feature = "agent-registry")]
878#[cfg_attr(docsrs, doc(cfg(feature = "agent-registry")))]
879pub mod registry {
880    pub use adk_server::registry::*;
881}
882
883// --- adk-tool features ---
884
885/// MCP sampling callback support.
886///
887/// Handle `sampling/createMessage` requests from MCP servers:
888/// - [`SamplingHandler`](tool::sampling::SamplingHandler) - Trait for handling sampling requests
889/// - [`LlmSamplingHandler`](tool::sampling::LlmSamplingHandler) - Default handler routing to agent's LLM
890/// - [`SamplingRequest`](tool::sampling::SamplingRequest) / [`SamplingResponse`](tool::sampling::SamplingResponse) - Wire types
891///
892/// Available with feature: `mcp-sampling`
893#[cfg(feature = "mcp-sampling")]
894#[cfg_attr(docsrs, doc(cfg(feature = "mcp-sampling")))]
895pub mod sampling {
896    pub use adk_tool::sampling::*;
897}
898
899/// Native Slack toolset for agent-driven Slack interactions.
900///
901/// Built-in Slack tools for agents:
902/// - [`SlackToolset`](tool::slack::SlackToolset) - Toolset implementing `adk_core::Toolset`
903/// - Tools: `slack_send_message`, `slack_read_channel`, `slack_add_reaction`, `slack_list_threads`
904///
905/// Available with feature: `slack`
906#[cfg(feature = "slack")]
907#[cfg_attr(docsrs, doc(cfg(feature = "slack")))]
908pub mod slack {
909    pub use adk_tool::slack::*;
910}
911
912/// Native BigQuery toolset for data-analysis agents.
913///
914/// Built-in BigQuery tools for agents:
915/// - [`BigQueryToolset`](tool::bigquery::BigQueryToolset) - Toolset implementing `adk_core::Toolset`
916/// - Tools: `bigquery_execute_sql`, `bigquery_get_table_schema`, `bigquery_list_datasets`, `bigquery_list_tables`
917///
918/// Available with feature: `bigquery`
919#[cfg(feature = "bigquery")]
920#[cfg_attr(docsrs, doc(cfg(feature = "bigquery")))]
921pub mod bigquery {
922    pub use adk_tool::bigquery::*;
923}
924
925/// Native Spanner toolset for Cloud Spanner interactions.
926///
927/// Built-in Spanner tools for agents:
928/// - [`SpannerToolset`](tool::spanner::SpannerToolset) - Toolset implementing `adk_core::Toolset`
929/// - Tools: `spanner_execute_sql`, `spanner_get_table_schema`, `spanner_list_tables`
930///
931/// Available with feature: `spanner`
932#[cfg(feature = "spanner")]
933#[cfg_attr(docsrs, doc(cfg(feature = "spanner")))]
934pub mod spanner {
935    pub use adk_tool::spanner::*;
936}
937
938// --- adk-eval features ---
939
940/// User personas for evaluation.
941///
942/// Define simulated user personas for realistic multi-turn test conversations:
943/// - [`PersonaProfile`](eval::personas::PersonaProfile) - Persona definition
944/// - [`UserSimulator`](eval::personas::UserSimulator) - Generate persona-driven messages
945/// - [`PersonaRegistry`](eval::personas::PersonaRegistry) - Load personas from directory
946///
947/// Available with feature: `personas`
948#[cfg(feature = "personas")]
949#[cfg_attr(docsrs, doc(cfg(feature = "personas")))]
950pub mod personas {
951    pub use adk_eval::personas::*;
952}
953
954// --- adk-realtime features ---
955
956/// Video avatar configuration for realtime sessions.
957///
958/// Attach a video avatar to realtime voice agents:
959/// - [`AvatarConfig`](realtime::avatar::AvatarConfig) - Avatar source, lip-sync, and rendering settings
960/// - [`LipSyncConfig`](realtime::avatar::LipSyncConfig) - Lip-sync configuration
961/// - [`RenderingConfig`](realtime::avatar::RenderingConfig) - Rendering parameters
962///
963/// Available with feature: `video-avatar`
964#[cfg(feature = "video-avatar")]
965#[cfg_attr(docsrs, doc(cfg(feature = "video-avatar")))]
966pub mod avatar {
967    pub use adk_realtime::avatar::*;
968}
969
970// ============================================================================
971// Convenience Functions
972// ============================================================================
973
974/// Detect LLM provider from environment variables.
975///
976/// Checks environment variables in precedence order and returns the first
977/// matching provider:
978///
979/// 1. `ANTHROPIC_API_KEY` → Anthropic (Claude)
980/// 2. `OPENAI_API_KEY` → OpenAI
981/// 3. `GOOGLE_API_KEY` → Gemini
982///
983/// # Errors
984///
985/// Returns [`AdkError`] when no supported environment variable is set.
986///
987/// # Example
988///
989/// ```rust,ignore
990/// use adk_rust::provider_from_env;
991/// use std::sync::Arc;
992///
993/// let model: Arc<dyn adk_rust::Llm> = provider_from_env()?;
994/// ```
995pub fn provider_from_env() -> Result<std::sync::Arc<dyn Llm>> {
996    #[cfg(feature = "anthropic")]
997    {
998        if let Ok(key) = std::env::var("ANTHROPIC_API_KEY") {
999            return Ok(std::sync::Arc::new(model::anthropic::AnthropicClient::from_api_key(key)?));
1000        }
1001    }
1002
1003    #[cfg(feature = "openai")]
1004    {
1005        if let Ok(key) = std::env::var("OPENAI_API_KEY") {
1006            let config = model::openai::OpenAIConfig::new(key, "gpt-4o-mini");
1007            return Ok(std::sync::Arc::new(model::openai::OpenAIClient::new(config)?));
1008        }
1009    }
1010
1011    #[cfg(feature = "gemini")]
1012    {
1013        if let Ok(key) = std::env::var("GOOGLE_API_KEY") {
1014            return Ok(std::sync::Arc::new(model::GeminiModel::new(key, "gemini-2.5-flash")?));
1015        }
1016    }
1017
1018    Err(AdkError::config(
1019        "No LLM provider detected. Set one of: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY",
1020    ))
1021}
1022
1023/// High-level single-turn agent invocation.
1024///
1025/// Creates an agent with the given instructions, sends the input, and returns
1026/// the text response. Uses [`provider_from_env`] to auto-detect the LLM provider.
1027///
1028/// This is the fastest way to get started with ADK — a single function call
1029/// that handles provider selection, session creation, agent building, and
1030/// execution.
1031///
1032/// # Arguments
1033///
1034/// * `instructions` - System instructions for the agent
1035/// * `input` - User input to send to the agent
1036///
1037/// # Returns
1038///
1039/// The agent's text response as a `String`.
1040///
1041/// # Errors
1042///
1043/// Returns [`AdkError`] when no supported environment variable is set, or
1044/// when agent execution fails.
1045///
1046/// # Example
1047///
1048/// ```rust,ignore
1049/// use adk_rust::run;
1050///
1051/// let response = run("You are a helpful assistant.", "What is 2 + 2?").await?;
1052/// println!("{response}");
1053/// ```
1054#[cfg(all(feature = "agents", feature = "sessions", feature = "runner"))]
1055pub async fn run(instructions: &str, input: &str) -> Result<String> {
1056    use futures::StreamExt;
1057    use std::collections::HashMap;
1058    use std::sync::Arc;
1059
1060    type ProviderPair = (Arc<dyn Llm>, Option<Arc<dyn CacheCapable>>);
1061
1062    let (model, cache_capable): ProviderPair = {
1063        #[allow(unused_assignments)]
1064        let mut result: Option<ProviderPair> = None;
1065
1066        #[cfg(feature = "anthropic")]
1067        {
1068            if result.is_none() {
1069                if let Ok(key) = std::env::var("ANTHROPIC_API_KEY") {
1070                    let m = model::anthropic::AnthropicClient::from_api_key(key)?;
1071                    result = Some((Arc::new(m), None));
1072                }
1073            }
1074        }
1075
1076        #[cfg(feature = "openai")]
1077        {
1078            if result.is_none() {
1079                if let Ok(key) = std::env::var("OPENAI_API_KEY") {
1080                    let config = model::openai::OpenAIConfig::new(key, "gpt-4o-mini");
1081                    let m = model::openai::OpenAIClient::new(config)?;
1082                    result = Some((Arc::new(m), None));
1083                }
1084            }
1085        }
1086
1087        #[cfg(feature = "gemini")]
1088        {
1089            if result.is_none() {
1090                if let Ok(key) = std::env::var("GOOGLE_API_KEY") {
1091                    let m = Arc::new(model::GeminiModel::new(key, "gemini-2.5-flash")?);
1092                    let cc: Arc<dyn CacheCapable> = m.clone();
1093                    result = Some((m, Some(cc)));
1094                }
1095            }
1096        }
1097
1098        result.ok_or_else(|| {
1099            AdkError::config(
1100                "No LLM provider detected. Set one of: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY",
1101            )
1102        })?
1103    };
1104
1105    let agent =
1106        agent::LlmAgentBuilder::new("adk_run").instruction(instructions).model(model).build()?;
1107
1108    let session_service: Arc<dyn adk_session::SessionService> =
1109        Arc::new(session::InMemorySessionService::new());
1110
1111    let session_id = SessionId::generate();
1112
1113    session_service
1114        .create(session::CreateRequest {
1115            app_name: "adk_run".into(),
1116            user_id: "user".into(),
1117            session_id: Some(session_id.to_string()),
1118            state: HashMap::new(),
1119        })
1120        .await?;
1121
1122    let runner = runner::Runner::new(runner::RunnerConfig {
1123        app_name: "adk_run".into(),
1124        agent: Arc::new(agent),
1125        session_service,
1126        artifact_service: None,
1127        memory_service: None,
1128        plugin_manager: None,
1129        run_config: None,
1130        compaction_config: None,
1131        context_cache_config: None,
1132        cache_capable,
1133        request_context: None,
1134        cancellation_token: None,
1135        intra_compaction_config: None,
1136        intra_compaction_summarizer: None,
1137    })?;
1138
1139    let content = Content::new("user").with_text(input);
1140    let mut stream = runner.run(UserId::new("user")?, session_id, content).await?;
1141
1142    let mut result = String::new();
1143    while let Some(event) = stream.next().await {
1144        let event = event?;
1145        if let Some(content) = &event.llm_response.content {
1146            for part in &content.parts {
1147                if let Some(text) = part.text() {
1148                    result.push_str(text);
1149                }
1150            }
1151        }
1152    }
1153
1154    Ok(result)
1155}
1156
1157// ============================================================================
1158// Prelude
1159// ============================================================================
1160
1161/// Convenience prelude for common imports.
1162///
1163/// Import everything you need with a single line:
1164///
1165/// ```
1166/// use adk_rust::prelude::*;
1167/// ```
1168///
1169/// This includes:
1170/// - Core traits: `Agent`, `Tool`, `Llm`, `Session`
1171/// - Agent builders: `LlmAgentBuilder`, `CustomAgentBuilder`
1172/// - Workflow agents: `SequentialAgent`, `ParallelAgent`, `LoopAgent`
1173/// - Models: `GeminiModel`
1174/// - Tools: `FunctionTool`, `GoogleSearchTool`, `McpToolset`
1175/// - Services: `InMemorySessionService`, `InMemoryArtifactService`
1176/// - Runtime: `Runner`, `RunnerConfig`
1177/// - Common types: `Arc`, `Result`, `Content`, `Event`
1178pub mod prelude {
1179    // Core types (always available)
1180    pub use crate::{
1181        AdkError, Agent, BeforeModelResult, Content, Event, EventStream, InvocationContext, Llm,
1182        LlmRequest, LlmResponse, Part, Result, RunConfig, Session, State, Tool, ToolContext,
1183        Toolset,
1184    };
1185
1186    // Agents
1187    #[cfg(feature = "agents")]
1188    pub use crate::agent::{
1189        ConditionalAgent, CustomAgent, CustomAgentBuilder, LlmAgent, LlmAgentBuilder,
1190        LlmConditionalAgent, LlmConditionalAgentBuilder, LoopAgent, ParallelAgent, SequentialAgent,
1191    };
1192
1193    // Models
1194    #[cfg(feature = "models")]
1195    pub use crate::model::GeminiModel;
1196
1197    // Model providers (when specific features are enabled)
1198    #[cfg(feature = "openai")]
1199    pub use crate::model::openai::{OpenAIClient, OpenAIConfig};
1200
1201    #[cfg(feature = "openrouter")]
1202    pub use crate::model::openrouter::{
1203        OpenRouterApiMode, OpenRouterClient, OpenRouterConfig, OpenRouterPlugin,
1204        OpenRouterProviderPreferences, OpenRouterReasoningConfig, OpenRouterRequestOptions,
1205        OpenRouterResponseTool,
1206    };
1207
1208    #[cfg(feature = "anthropic")]
1209    pub use crate::model::anthropic::{AnthropicClient, AnthropicConfig, Effort, ThinkingMode};
1210
1211    #[cfg(feature = "deepseek")]
1212    pub use crate::model::deepseek::{DeepSeekClient, DeepSeekConfig};
1213
1214    #[cfg(feature = "groq")]
1215    pub use crate::model::groq::{GroqClient, GroqConfig};
1216
1217    #[cfg(feature = "ollama")]
1218    pub use crate::model::ollama::{OllamaConfig, OllamaModel};
1219
1220    // OpenAI-compatible providers: use OpenAICompatible with provider presets
1221    // e.g. OpenAICompatibleConfig::fireworks(api_key, model)
1222    #[cfg(feature = "openai")]
1223    pub use crate::model::openai_compatible::{OpenAICompatible, OpenAICompatibleConfig};
1224
1225    #[cfg(feature = "bedrock")]
1226    pub use crate::model::bedrock::{BedrockClient, BedrockConfig};
1227
1228    #[cfg(feature = "azure-ai")]
1229    pub use crate::model::azure_ai::{AzureAIClient, AzureAIConfig};
1230
1231    // Tools
1232    #[cfg(feature = "tools")]
1233    pub use crate::tool::{
1234        BasicToolset, ExitLoopTool, FunctionTool, GoogleSearchTool, LoadArtifactsTool, McpToolset,
1235        UrlContextTool, WebSearchTool,
1236    };
1237
1238    // Skills
1239    #[cfg(feature = "skills")]
1240    pub use crate::skill::{SelectionPolicy, SkillInjector, SkillInjectorConfig, load_skill_index};
1241
1242    // Sessions
1243    #[cfg(feature = "sessions")]
1244    pub use crate::session::InMemorySessionService;
1245
1246    // Artifacts
1247    #[cfg(feature = "artifacts")]
1248    pub use crate::artifact::InMemoryArtifactService;
1249
1250    // Memory
1251    #[cfg(feature = "memory")]
1252    pub use crate::memory::InMemoryMemoryService;
1253
1254    // Runner
1255    #[cfg(feature = "runner")]
1256    pub use crate::runner::{Runner, RunnerConfig};
1257
1258    // Graph workflows
1259    #[cfg(feature = "graph")]
1260    pub use crate::graph::{END, GraphAgent, NodeOutput, Router, START, StateGraph};
1261
1262    // Realtime
1263    #[cfg(feature = "realtime")]
1264    pub use crate::realtime::{
1265        RealtimeAgent, RealtimeAgentBuilder, RealtimeConfig, RealtimeModel, RealtimeRunner,
1266        RealtimeSession,
1267    };
1268
1269    // Common re-exports
1270    pub use crate::anyhow::Result as AnyhowResult;
1271    pub use crate::async_trait;
1272    pub use std::sync::Arc;
1273
1274    // Convenience functions
1275    pub use crate::provider_from_env;
1276    #[cfg(all(feature = "agents", feature = "sessions", feature = "runner"))]
1277    pub use crate::run;
1278}