af_llm/lib.rs
1//! `af-llm` — unified async LLM access for the Agent Factory platform.
2//!
3//! Provider-neutral model transport and request types. Provides:
4//!
5//! - [`LlmClient`] — async chat completions against any OpenAI-compatible
6//! endpoint, with a hard per-request timeout and a shared
7//! [`CircuitBreaker`].
8//! - Strongly-typed request/response models ([`CompletionRequest`],
9//! [`CompletionResponse`], [`ChatMessage`], [`Tool`], …) — the Pydantic
10//! equivalent, validated at the wire boundary.
11//! - [`parse_json`] — pull structured output out of fenced LLM text into any
12//! `serde` type.
13//!
14//! # Example
15//!
16//! ```no_run
17//! use af_llm::{LlmClient, LlmConfig, CompletionRequest, ChatMessage};
18//!
19//! # async fn run() -> af_llm::Result<()> {
20//! let client = LlmClient::new(LlmConfig::new("http://localhost:4000/v1", ""))?;
21//! let req = CompletionRequest::new(
22//! "deepseek/deepseek-chat",
23//! vec![ChatMessage::user("Say hi in one word.")],
24//! );
25//! let resp = client.complete_stream_single_attempt(&req, |_, _| {}).await?;
26//! println!("{:?}", resp.first_content());
27//! # Ok(())
28//! # }
29//! ```
30
31pub mod circuit_breaker;
32pub mod client;
33pub mod error;
34pub mod json;
35pub mod stream;
36pub mod types;
37
38pub use circuit_breaker::{CircuitBreaker, State as CircuitState, Status as CircuitStatus};
39pub use client::{LlmClient, LlmConfig, DEFAULT_TIMEOUT};
40pub use error::{LlmError, Result};
41pub use json::{parse_json, strip_code_fence};
42pub use stream::StreamDelta;
43pub use types::{
44 AssistantBlock, ChatMessage, Choice, CompletionRequest, CompletionResponse, FinishReason,
45 FunctionCall, FunctionDef, ReasoningEffort, Role, StreamOptions, Tool, ToolCall, ToolChoice,
46 Usage,
47};