Skip to main content

origin_asset/
lib.rs

1//! # Origin Asset
2//!
3//! Rust client for the Origin platform services:
4//!
5//! - **Asset Gateway** — generate images, video, audio, TTS, music, 3D models, sprites, text
6//! - **AI Search** — multi-source web search with AI summarization
7//! - **Cognee** — knowledge graph construction and semantic search
8//!
9//! ## Quick Start
10//!
11//! ```rust,no_run
12//! use origin_asset::OriginClient;
13//!
14//! #[tokio::main]
15//! async fn main() -> origin_asset::Result<()> {
16//!     let client = OriginClient::new("your-api-key");
17//!
18//!     // Generate an image
19//!     let image = client.asset().generate_image("a fire sword", None).await?;
20//!     println!("Image URL: {:?}", image.output_url);
21//!
22//!     // Search the web
23//!     let results = client.search().search("Rust async runtime", None).await?;
24//!     println!("Content: {}", results.content);
25//!
26//!     // Search knowledge graph
27//!     let knowledge = client.cognee().search("game combat system", None).await?;
28//!     println!("{:?}", knowledge);
29//!
30//!     Ok(())
31//! }
32//! ```
33
34pub mod error;
35pub mod transport;
36
37#[cfg(feature = "asset")]
38pub mod asset;
39#[cfg(feature = "cognee")]
40pub mod cognee;
41#[cfg(feature = "search")]
42pub mod search;
43
44pub use error::{OriginError, Result};
45use transport::HttpTransport;
46
47/// Default base URLs for each service.
48pub mod defaults {
49    pub const ASSET_GATEWAY_URL: &str = "https://upload.xiaomao.chat";
50    pub const AI_SEARCH_URL: &str = "https://search.xiaomao.chat";
51    pub const COGNEE_URL: &str = "https://cogneeapi.xiaomao.chat";
52}
53
54/// Builder for configuring an [`OriginClient`].
55pub struct OriginClientBuilder {
56    api_key: String,
57    asset_url: String,
58    search_url: String,
59    cognee_url: String,
60    cognee_token: Option<String>,
61    client: Option<reqwest::Client>,
62}
63
64impl OriginClientBuilder {
65    pub fn new(api_key: impl Into<String>) -> Self {
66        Self {
67            api_key: api_key.into(),
68            asset_url: defaults::ASSET_GATEWAY_URL.to_string(),
69            search_url: defaults::AI_SEARCH_URL.to_string(),
70            cognee_url: defaults::COGNEE_URL.to_string(),
71            cognee_token: None,
72            client: None,
73        }
74    }
75
76    /// Override the Asset Gateway base URL.
77    pub fn asset_url(mut self, url: impl Into<String>) -> Self {
78        self.asset_url = url.into();
79        self
80    }
81
82    /// Override the AI Search base URL.
83    pub fn search_url(mut self, url: impl Into<String>) -> Self {
84        self.search_url = url.into();
85        self
86    }
87
88    /// Override the Cognee API base URL.
89    pub fn cognee_url(mut self, url: impl Into<String>) -> Self {
90        self.cognee_url = url.into();
91        self
92    }
93
94    /// Use a separate `ca_xxx` token for Cognee (defaults to main api_key).
95    pub fn cognee_token(mut self, token: impl Into<String>) -> Self {
96        self.cognee_token = Some(token.into());
97        self
98    }
99
100    /// Use a custom `reqwest::Client` for all services.
101    pub fn http_client(mut self, client: reqwest::Client) -> Self {
102        self.client = Some(client);
103        self
104    }
105
106    /// Build the [`OriginClient`].
107    pub fn build(self) -> OriginClient {
108        let make_transport = |url: String, key: String| {
109            let transport = HttpTransport::new(url, key);
110            if let Some(ref client) = self.client {
111                transport.with_client(client.clone())
112            } else {
113                transport
114            }
115        };
116
117        let cognee_key = self.cognee_token.unwrap_or_else(|| self.api_key.clone());
118
119        OriginClient {
120            asset_transport: make_transport(self.asset_url, self.api_key.clone()),
121            search_transport: make_transport(self.search_url, self.api_key.clone()),
122            cognee_transport: make_transport(self.cognee_url, cognee_key),
123        }
124    }
125}
126
127/// Unified client for all Origin platform services.
128///
129/// Use [`OriginClient::new`] for defaults or [`OriginClient::builder`] for customization.
130#[derive(Debug, Clone)]
131pub struct OriginClient {
132    asset_transport: HttpTransport,
133    search_transport: HttpTransport,
134    cognee_transport: HttpTransport,
135}
136
137impl OriginClient {
138    /// Create a client with default URLs and a shared API key.
139    pub fn new(api_key: impl Into<String>) -> Self {
140        OriginClientBuilder::new(api_key).build()
141    }
142
143    /// Create a builder for fine-grained configuration.
144    pub fn builder(api_key: impl Into<String>) -> OriginClientBuilder {
145        OriginClientBuilder::new(api_key)
146    }
147
148    /// Access the Asset Gateway client.
149    #[cfg(feature = "asset")]
150    pub fn asset(&self) -> asset::AssetClient {
151        asset::AssetClient::new(self.asset_transport.clone())
152    }
153
154    /// Access the AI Search client.
155    #[cfg(feature = "search")]
156    pub fn search(&self) -> search::SearchClient {
157        search::SearchClient::new(self.search_transport.clone())
158    }
159
160    /// Access the Cognee knowledge graph client.
161    #[cfg(feature = "cognee")]
162    pub fn cognee(&self) -> cognee::CogneeClient {
163        cognee::CogneeClient::new(self.cognee_transport.clone())
164    }
165}