Skip to main content

origin_asset/search/
mod.rs

1pub mod types;
2pub use types::*;
3
4use serde::Deserialize;
5use serde_json::{json, Value};
6
7use crate::error::Result;
8use crate::transport::HttpTransport;
9
10#[derive(Debug, Clone)]
11pub struct SearchClient {
12    pub(crate) transport: HttpTransport,
13}
14
15impl SearchClient {
16    pub fn new(transport: HttpTransport) -> Self {
17        Self { transport }
18    }
19
20    pub async fn search(
21        &self,
22        query: &str,
23        options: Option<SearchOptions>,
24    ) -> Result<SearchResponse> {
25        let options = options.unwrap_or(SearchOptions {
26            mode: None,
27            model: None,
28            split: None,
29            num: None,
30        });
31
32        let mut body = json!({ "query": query });
33        let payload = body
34            .as_object_mut()
35            .expect("search request payload should be an object");
36
37        if let Some(mode) = options.mode {
38            payload.insert("mode".to_string(), serde_json::to_value(mode)?);
39        }
40        if let Some(model) = options.model {
41            payload.insert("model".to_string(), Value::String(model));
42        }
43        if let Some(split) = options.split {
44            payload.insert("split".to_string(), json!(split));
45        }
46        if let Some(num) = options.num {
47            payload.insert("num".to_string(), json!(num));
48        }
49
50        self.transport.post("/api/search", &body).await
51    }
52
53    pub async fn search_fast(&self, query: &str) -> Result<SearchResponse> {
54        self.search(
55            query,
56            Some(SearchOptions {
57                mode: Some(SearchMode::Fast),
58                model: None,
59                split: None,
60                num: None,
61            }),
62        )
63        .await
64    }
65
66    pub async fn search_deep(&self, query: &str) -> Result<SearchResponse> {
67        self.search(
68            query,
69            Some(SearchOptions {
70                mode: Some(SearchMode::Deep),
71                model: None,
72                split: None,
73                num: None,
74            }),
75        )
76        .await
77    }
78
79    pub async fn search_answer(&self, query: &str) -> Result<SearchResponse> {
80        self.search(
81            query,
82            Some(SearchOptions {
83                mode: Some(SearchMode::Answer),
84                model: None,
85                split: None,
86                num: None,
87            }),
88        )
89        .await
90    }
91
92    pub async fn models(&self) -> Result<Vec<String>> {
93        let response: ModelsResponse = self.transport.get("/api/models").await?;
94        Ok(response.models)
95    }
96
97    pub async fn providers(&self) -> Result<Value> {
98        self.transport.get("/api/providers").await
99    }
100
101    pub async fn health(&self) -> Result<bool> {
102        let payload: Value = self.transport.get("/health").await?;
103
104        let status = payload.get("status").and_then(Value::as_str).or_else(|| {
105            payload
106                .get("data")
107                .and_then(|data| data.get("status"))
108                .and_then(Value::as_str)
109        });
110
111        Ok(matches!(status, Some("ok")))
112    }
113}
114
115#[derive(Debug, Deserialize)]
116struct ModelsResponse {
117    models: Vec<String>,
118}