origin_asset/search/
mod.rs1pub 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}