Skip to main content

unified_agent_sdk/
lib.rs

1//! Unified Rust SDK for multiple AI coding agents.
2//!
3//! `unified-agent-sdk` provides one consistent interface over multiple agent backends.
4//! It is designed for applications that want to swap executors without rewriting
5//! orchestration logic.
6//!
7//! # Feature Overview
8//!
9//! - Unified executor API via [`AgentExecutor`]
10//! - Provider adapter architecture
11//! - Unified event pipeline (`raw logs -> normalized logs -> AgentEvent`)
12//! - Profile/config resolution with runtime discovery ([`ProfileManager`])
13//! - Cross-provider capability and availability introspection
14//!
15//! # Supported Agents
16//!
17//! | Agent | `ExecutorType` | Executor Adapter | Log Normalizer | Profile Discovery |
18//! | --- | --- | --- | --- | --- |
19//! | Claude Code | `ExecutorType::ClaudeCode` | [`ClaudeCodeExecutor`] | [`ClaudeCodeLogNormalizer`] | `providers::claude_code::profile` |
20//! | Codex | `ExecutorType::Codex` | [`CodexExecutor`] | [`CodexLogNormalizer`] | `providers::codex::profile` |
21//!
22//! # Common Scenarios
23//!
24//! Start a new session with one provider:
25//!
26//! ```rust,no_run
27//! use unified_agent_sdk::{
28//!     AgentExecutor, CodexExecutor, PermissionPolicy, executor::SpawnConfig,
29//! };
30//!
31//! # async fn run() -> unified_agent_sdk::Result<()> {
32//! let executor = CodexExecutor::default();
33//! let config = SpawnConfig {
34//!     model: Some("gpt-5-codex".to_string()),
35//!     reasoning: Some("medium".to_string()),
36//!     permission_policy: Some(PermissionPolicy::Prompt),
37//!     env: vec![],
38//!     context_window_override_tokens: None,
39//! };
40//!
41//! let cwd = std::env::current_dir()?;
42//! let session = executor
43//!     .spawn(&cwd, "Summarize this repository in three bullets.", &config)
44//!     .await?;
45//!
46//! println!("session_id={}", session.session_id);
47//! # Ok(())
48//! # }
49//! ```
50//!
51//! Resolve profile + runtime overrides before spawning:
52//!
53//! ```rust,no_run
54//! use unified_agent_sdk::{
55//!     ExecutorConfig, ExecutorType, ProfileId, ProfileManager,
56//! };
57//!
58//! # async fn run() -> unified_agent_sdk::Result<()> {
59//! let manager = ProfileManager::new();
60//! let resolved = manager
61//!     .resolve(&ExecutorConfig {
62//!         profile_id: ProfileId::new(ExecutorType::Codex, Some("default".to_string())),
63//!         model_override: None,
64//!         reasoning_override: Some("high".to_string()),
65//!         permission_policy: None,
66//!     })
67//!     .await?;
68//!
69//! let _ = (resolved.model, resolved.reasoning, resolved.permission_policy);
70//! # Ok(())
71//! # }
72//! ```
73//!
74//! Build a session event stream with hooks:
75//!
76//! ```rust,no_run
77//! use futures::{StreamExt, stream};
78//! use std::path::PathBuf;
79//! use std::sync::Arc;
80//! use unified_agent_sdk::{
81//!     AgentEvent, AgentSession, CodexLogNormalizer, EventType, ExecutorType, HookManager,
82//!     session::RawLogStream,
83//! };
84//!
85//! # async fn run() {
86//! let session = AgentSession::new(
87//!     "demo-session",
88//!     ExecutorType::Codex,
89//!     PathBuf::from("."),
90//!     None,
91//! );
92//!
93//! let hooks = Arc::new(HookManager::new());
94//! hooks.register(
95//!     EventType::MessageReceived,
96//!     Arc::new(|event| Box::pin(async move {
97//!         if let AgentEvent::MessageReceived { content, .. } = event {
98//!             println!("message={content}");
99//!         }
100//!     })),
101//! );
102//!
103//! let raw_logs: RawLogStream = Box::pin(stream::iter(vec![
104//!     br#"{"type":"item.completed","item":{"type":"agent_message","id":"m1","text":"hello"}}"#
105//!         .to_vec(),
106//!     b"\n".to_vec(),
107//! ]));
108//!
109//! let mut stream = session.event_stream(raw_logs, Box::new(CodexLogNormalizer::new()), Some(hooks));
110//! let _ = stream.next().await;
111//! # }
112//! ```
113
114pub mod error;
115pub mod event;
116pub mod executor;
117pub mod log;
118pub mod profile;
119pub mod providers;
120pub mod session;
121pub mod types;
122
123pub use error::{ExecutorError, Result};
124pub use event::{
125    AgentEvent, EventConverter, EventStream, EventType, HookManager, normalized_log_to_event,
126};
127pub use executor::{AgentCapabilities, AgentExecutor, AvailabilityStatus};
128pub use log::{LogNormalizer, NormalizedLog};
129pub use profile::{DiscoveryData, ExecutorConfig, ProfileId, ProfileManager};
130pub use providers::{
131    ClaudeCodeExecutor, ClaudeCodeLogNormalizer, CodexExecutor, CodexLogNormalizer,
132};
133pub use session::{AgentSession, SessionMetadata, SessionResume};
134pub use types::{
135    ContextUsage, ContextUsageSource, ExecutorType, ExitStatus, PermissionPolicy, Role, ToolStatus,
136};