ferro_ai/lib.rs
1//! # ferro-ai
2//!
3//! AI structured classification and confirmation primitives for the Ferro framework.
4//!
5//! ## Classification
6//!
7//! Provider-abstracted wrapper for LLM structured JSON output with configurable
8//! schema, model selection, confidence threshold, and retry behavior.
9//!
10//! ```rust,ignore
11//! use ferro_ai::{Classifier, ClassifierConfig, AnthropicProvider};
12//! use serde::Deserialize;
13//! use std::sync::Arc;
14//!
15//! #[derive(Deserialize)]
16//! struct CommandIntent {
17//! action: String,
18//! confidence: f64,
19//! }
20//!
21//! let provider = AnthropicProvider::from_env().unwrap();
22//! let classifier = Classifier::<CommandIntent>::new(
23//! Arc::new(provider),
24//! ClassifierConfig::default(),
25//! );
26//! ```
27//!
28//! ## Confirmation
29//!
30//! State machine for gating destructive actions behind explicit user confirmation
31//! with configurable TTL expiry and event-driven observability.
32//!
33//! ```rust,ignore
34//! use ferro_ai::{InMemoryConfirmationStore, ConfirmationStore};
35//! use std::time::Duration;
36//!
37//! let store = InMemoryConfirmationStore::new();
38//! let payload = serde_json::json!({"action": "delete_user", "user_id": 42});
39//!
40//! store.request_confirmation("confirm-delete-42", payload, Duration::from_secs(60)).await?;
41//! let confirmed = store.confirm("confirm-delete-42").await?;
42//! ```
43
44pub mod classifier;
45pub mod client;
46pub mod complete;
47pub mod config;
48pub mod confirmation;
49pub mod embed;
50pub mod error;
51pub mod schema;
52pub mod similarity;
53pub mod tools;
54
55#[cfg(feature = "pgvector")]
56pub mod pgvector;
57
58pub use classifier::anthropic::AnthropicProvider;
59pub use classifier::provider::ClassificationProvider;
60pub use classifier::{ClassificationResult, Classifier, ClassifierConfig};
61pub use client::{
62 AnthropicClient, CompletionRequest, CompletionResponse, LlmClient, OllamaClient, OpenAiClient,
63 TokenStream, ToolChoice, ToolRequest, ToolUseBlock,
64};
65pub use complete::{complete, complete_with, CompleteOptions};
66pub use config::AiConfig;
67pub use confirmation::events::ConfirmationExpired;
68pub use confirmation::store::InMemoryConfirmationStore;
69pub use confirmation::{ConfirmationStore, PendingActionInfo};
70pub use embed::embed;
71pub use error::Error;
72pub use schema::for_structured_output;
73pub use similarity::cosine_similarity;
74pub use tools::{make_handler, ToolDef, ToolError, ToolRegistry};
75
76#[cfg(feature = "pgvector")]
77pub use pgvector::{Neighbor, PgVectorStore};
78
79/// Process-wide mutex that serializes env-var mutation across all test modules.
80///
81/// Tests that read or write `FERRO_AI_*` environment variables must hold this
82/// lock for the duration of the test to prevent cross-module interference.
83/// Per-module `static ENV_LOCK` instances are insufficient because each module
84/// gets its own mutex instance; only a crate-level mutex serializes across modules.
85#[cfg(test)]
86pub static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());