periplon_sdk/lib.rs
1//! Periplon SDK - Multi-agent AI workflow orchestration
2//!
3//! This SDK provides a Rust interface for building and executing multi-agent AI workflows.
4//! It communicates with the CLI via stdin/stdout using newline-delimited JSON (NDJSON).
5//!
6//! # Architecture
7//!
8//! The SDK follows **Hexagonal Architecture** (Ports and Adapters pattern):
9//!
10//! - **Domain Core**: Pure business logic (message types, sessions, permissions, hooks, control)
11//! - **Primary Ports**: Inbound interfaces (AgentService, SessionManager, ControlProtocol)
12//! - **Secondary Ports**: Outbound interfaces (Transport, PermissionService, HookService, McpServer)
13//! - **Primary Adapters**: Implementations driving the application (query function, PeriplonSDKClient)
14//! - **Secondary Adapters**: Implementations connecting to external systems (SubprocessCLITransport, MockTransport)
15//! - **Application Services**: Orchestration layer (Query)
16//!
17//! # Examples
18//!
19//! ## Simple Query
20//!
21//! ```no_run
22//! use periplon_sdk::{query, Message, ContentBlock};
23//! use futures::StreamExt;
24//!
25//! #[tokio::main]
26//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
27//! let mut stream = query("What is 2 + 2?", None).await?;
28//!
29//! while let Some(msg) = stream.next().await {
30//! match msg {
31//! Message::Assistant(assistant_msg) => {
32//! for block in assistant_msg.message.content {
33//! if let ContentBlock::Text { text } = block {
34//! println!("Assistant: {}", text);
35//! }
36//! }
37//! }
38//! Message::Result(result_msg) => {
39//! println!("Cost: ${:.4}", result_msg.total_cost_usd.unwrap_or(0.0));
40//! }
41//! _ => {}
42//! }
43//! }
44//!
45//! Ok(())
46//! }
47//! ```
48//!
49//! ## Interactive Client
50//!
51//! ```no_run
52//! use periplon_sdk::{PeriplonSDKClient, AgentOptions};
53//! use futures::StreamExt;
54//!
55//! #[tokio::main]
56//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
57//! let options = AgentOptions {
58//! allowed_tools: vec!["Read".to_string(), "Bash".to_string()],
59//! permission_mode: Some("acceptEdits".to_string()),
60//! ..Default::default()
61//! };
62//!
63//! let mut client = PeriplonSDKClient::new(options);
64//! client.connect(None).await?;
65//!
66//! // First query
67//! client.query("List files in current directory").await?;
68//! {
69//! let stream = client.receive_response()?;
70//! futures::pin_mut!(stream);
71//! while let Some(msg) = stream.next().await {
72//! println!("{:?}", msg);
73//! }
74//! }
75//!
76//! // Follow-up query
77//! client.query("Create a README.md file").await?;
78//! {
79//! let stream = client.receive_response()?;
80//! futures::pin_mut!(stream);
81//! while let Some(msg) = stream.next().await {
82//! println!("{:?}", msg);
83//! }
84//! }
85//!
86//! client.disconnect().await?;
87//!
88//! Ok(())
89//! }
90//! ```
91
92pub mod adapters;
93pub mod application;
94pub mod data_fetcher;
95pub mod domain;
96pub mod dsl;
97pub mod error;
98pub mod options;
99pub mod ports;
100
101#[cfg(feature = "server")]
102pub mod server;
103
104#[cfg(feature = "tui")]
105pub mod tui;
106
107// Testing utilities - available in test/dev builds
108// This allows integration tests in the tests/ directory to access these utilities
109pub mod testing;
110
111// Re-export commonly used types
112pub use adapters::primary::{query, PeriplonSDKClient};
113pub use data_fetcher::{
114 DataFetcher, FetchError, FileMetadata, HttpMethod, HttpRequest, HttpResponse,
115};
116pub use domain::{ContentBlock, ContentValue, Message, PermissionResult, ToolPermissionContext};
117pub use dsl::{parse_workflow, parse_workflow_file, validate_workflow, DSLExecutor, DSLWorkflow};
118pub use error::{Error, Result};
119pub use options::{AgentOptions, SystemPromptConfig};
120
121#[cfg(feature = "tui")]
122pub use tui::TuiApp;