Skip to main content

tower_llm/
lib.rs

1//! # Tower LLM
2//!
3//! A powerful Tower-based framework for building multi-agent workflows with OpenAI LLMs.
4//! This SDK provides composable, type-safe components using Tower's service architecture
5//! for maximum flexibility and performance.
6//!
7//! ## Core Concepts
8//!
9//! - **Agent**: A Tower service that processes chat requests through an LLM with tools
10//! - **Tools**: Type-safe functions that agents can call, with automatic schema generation
11//! - **Layers**: Tower middleware for cross-cutting concerns (retry, timeout, observability)
12//! - **Static DI**: All dependencies are injected at construction time - no runtime lookups
13//!
14//! ## Getting Started
15//!
16//! Set your OpenAI API key in the `OPENAI_API_KEY` environment variable.
17//!
18//! ```rust,no_run
19//! use tower_llm::{Agent, tool_typed, policies, CompositePolicy, run_user};
20//! use async_openai::{config::OpenAIConfig, Client};
21//! use schemars::JsonSchema;
22//! use serde::Deserialize;
23//! use std::sync::Arc;
24//! use tower::{Service, ServiceExt};
25//!
26//! #[derive(Debug, Deserialize, JsonSchema)]
27//! struct AddArgs {
28//!     a: f64,
29//!     b: f64,
30//! }
31//!
32//! # async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
33//! // Create OpenAI client
34//! let client = Arc::new(Client::<OpenAIConfig>::new());
35//!
36//! // Define a tool
37//! let calculator = tool_typed(
38//!     "add",
39//!     "Add two numbers",
40//!     |args: AddArgs| async move {
41//!         Ok(serde_json::json!({ "sum": args.a + args.b }))
42//!     },
43//! );
44//!
45//! // Build an agent with per-agent instructions
46//! let agent = Agent::builder(client)
47//!     .model("gpt-4o")
48//!     .instructions("You are a helpful math assistant")
49//!     .tool(calculator)
50//!     .policy(CompositePolicy::new(vec![policies::until_no_tool_calls()]))
51//!     .build();
52//!
53//! // Use the agent with Tower's Service trait
54//! let mut agent = agent;
55//! // Send only a user message; the agent injects its instructions as a system message
56//! let response = run_user(&mut agent, "What is 2 + 2?").await?;
57//!
58//! println!("Agent: {:?}", response);
59//! # Ok(())
60//! # }
61//! ```
62
63pub mod approvals;
64pub mod auto_compaction;
65pub mod budgets;
66pub mod codec;
67pub mod concurrency;
68pub mod error;
69pub mod groups;
70pub mod items;
71pub mod memory;
72pub mod observability;
73pub mod provider;
74pub mod recording;
75pub mod resilience;
76pub mod result;
77pub mod sessions;
78pub mod sqlite_session;
79pub mod streaming;
80pub mod tap;
81pub mod validation;
82
83// Core module with main implementation
84mod core;
85
86// Re-export core types
87pub use core::{
88    policies, run, run_user, simple_chat_request, simple_user_request, tool_typed, Agent,
89    AgentBuilder, AgentLoop, AgentLoopLayer, AgentPolicy, AgentRun, AgentStopReason, AgentSvc,
90    CompositePolicy, LoopState, Policy, PolicyFn, Step, StepAux, StepLayer, StepOutcome, ToolDef,
91    ToolInvocation, ToolOutput, ToolRouter, ToolSvc,
92};
93
94// Re-export join policy for tool execution configuration
95pub use core::ToolJoinPolicy;
96
97// Public re-exports for convenience
98pub use error::{AgentsError, Result};
99pub use memory::Session;
100pub use result::{RunResult, RunResultWithContext, StreamingRunResult};
101pub use sqlite_session::SqliteSession;
102
103// Re-export async-openai types that users need
104pub use async_openai::{
105    config::OpenAIConfig,
106    types::{
107        ChatCompletionRequestMessage, CreateChatCompletionRequest, CreateChatCompletionRequestArgs,
108        ReasoningEffort,
109    },
110    Client,
111};
112
113// Re-export Tower traits that users need
114pub use tower::{Layer, Service, ServiceExt};
115
116// Re-export llm instruction provider
117pub use core::LLMInstructionProvider;
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn test_module_imports() {
125        // Verify that all modules compile
126        let _ = std::mem::size_of::<AgentsError>();
127    }
128}