1use reqwest::Client;
27use serde::{Deserialize, Serialize};
28use std::sync::Arc;
29use thiserror::Error;
30
31pub mod agents;
32pub mod models;
33pub mod providers;
34pub mod skills;
35
36pub use agents::Agents;
37pub use models::Models;
38pub use providers::Providers;
39pub use skills::Skills;
40
41#[derive(Error, Debug)]
42pub enum Error {
43 #[error("HTTP error: {0}")]
44 Http(#[from] reqwest::Error),
45 #[error("API error: {0}")]
46 Api(String),
47 #[error("JSON error: {0}")]
48 Json(#[from] serde_json::Error),
49}
50
51pub type Result<T> = std::result::Result<T, Error>;
52
53#[derive(Debug, Clone)]
54pub struct LibreFang {
55 base_url: String,
56 #[allow(dead_code)]
57 client: Client,
58 agents: Arc<Agents>,
59 skills: Arc<Skills>,
60 models: Arc<Models>,
61 providers: Arc<Providers>,
62}
63
64impl LibreFang {
65 pub fn new(base_url: impl Into<String>) -> Self {
66 let base_url = base_url.into();
67 let client = Client::new();
68
69 let agents = Arc::new(Agents::new(base_url.clone(), client.clone()));
70 let skills = Arc::new(Skills::new(base_url.clone(), client.clone()));
71 let models = Arc::new(Models::new(base_url.clone(), client.clone()));
72 let providers = Arc::new(Providers::new(base_url.clone(), client.clone()));
73
74 Self {
75 base_url,
76 client,
77 agents,
78 skills,
79 models,
80 providers,
81 }
82 }
83
84 pub fn agents(&self) -> &Arc<Agents> {
85 &self.agents
86 }
87
88 pub fn skills(&self) -> &Arc<Skills> {
89 &self.skills
90 }
91
92 pub fn models(&self) -> &Arc<Models> {
93 &self.models
94 }
95
96 pub fn providers(&self) -> &Arc<Providers> {
97 &self.providers
98 }
99
100 pub fn base_url(&self) -> &str {
101 &self.base_url
102 }
103}
104
105#[derive(Debug, Deserialize, Serialize)]
107pub struct ApiResponse<T> {
108 pub data: Option<T>,
109 pub error: Option<String>,
110}
111
112#[derive(Debug, Deserialize, Serialize)]
113pub struct ApiError {
114 pub error: String,
115}
116
117pub fn extract_error(
118 status: reqwest::StatusCode,
119 body: &str,
120) -> Error {
121 if let Ok(api_err) = serde_json::from_str::<ApiError>(body) {
122 Error::Api(api_err.error)
123 } else {
124 Error::Api(format!("HTTP {}", status))
125 }
126}