zai_rs/knowledge/
document_upload_url.rs

1use crate::client::http::HttpClient;
2use serde::{Deserialize, Serialize};
3use validator::Validate;
4
5use super::types::UploadUrlResponse;
6
7/// Single URL upload detail
8#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
9pub struct UploadUrlDetail {
10    /// Source URL to fetch
11    #[validate(url)]
12    pub url: String,
13    /// Slice type (integer)
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub knowledge_type: Option<i64>,
16    /// Custom separators
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub custom_separator: Option<Vec<String>>,
19    /// Sentence size
20    #[serde(skip_serializing_if = "Option::is_none")]
21    #[validate(range(min = 1))]
22    pub sentence_size: Option<u32>,
23    /// Callback URL
24    #[serde(skip_serializing_if = "Option::is_none")]
25    #[validate(url)]
26    pub callback_url: Option<String>,
27    /// Callback headers
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub callback_header: Option<std::collections::BTreeMap<String, String>>,
30}
31
32impl UploadUrlDetail {
33    pub fn new(url: impl Into<String>) -> Self {
34        Self {
35            url: url.into(),
36            knowledge_type: None,
37            custom_separator: None,
38            sentence_size: None,
39            callback_url: None,
40            callback_header: None,
41        }
42    }
43    pub fn with_knowledge_type(mut self, t: i64) -> Self {
44        self.knowledge_type = Some(t);
45        self
46    }
47    pub fn with_custom_separator(mut self, seps: Vec<String>) -> Self {
48        self.custom_separator = Some(seps);
49        self
50    }
51    pub fn with_sentence_size(mut self, size: u32) -> Self {
52        self.sentence_size = Some(size);
53        self
54    }
55    pub fn with_callback_url(mut self, url: impl Into<String>) -> Self {
56        self.callback_url = Some(url.into());
57        self
58    }
59    pub fn with_callback_header(
60        mut self,
61        headers: std::collections::BTreeMap<String, String>,
62    ) -> Self {
63        self.callback_header = Some(headers);
64        self
65    }
66}
67
68/// Upload URL request body
69#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
70pub struct UploadUrlBody {
71    /// Upload detail list (at least 1)
72    #[validate(length(min = 1))]
73    pub upload_detail: Vec<UploadUrlDetail>,
74    /// Knowledge base id
75    #[validate(length(min = 1))]
76    pub knowledge_id: String,
77}
78
79impl UploadUrlBody {
80    pub fn new(knowledge_id: impl Into<String>) -> Self {
81        Self {
82            upload_detail: Vec::new(),
83            knowledge_id: knowledge_id.into(),
84        }
85    }
86    pub fn add_detail(mut self, detail: UploadUrlDetail) -> Self {
87        self.upload_detail.push(detail);
88        self
89    }
90    pub fn add_url(mut self, url: impl Into<String>) -> Self {
91        self.upload_detail.push(UploadUrlDetail::new(url));
92        self
93    }
94}
95
96/// Upload URL request (POST /llm-application/open/document/upload_url)
97pub struct DocumentUploadUrlRequest {
98    /// Bearer API key
99    pub key: String,
100    url: String,
101    body: UploadUrlBody,
102}
103
104impl DocumentUploadUrlRequest {
105    pub fn new(key: String, body: UploadUrlBody) -> Self {
106        let url =
107            "https://open.bigmodel.cn/api/llm-application/open/document/upload_url".to_string();
108        Self { key, url, body }
109    }
110
111    pub fn body_mut(&mut self) -> &mut UploadUrlBody {
112        &mut self.body
113    }
114
115    /// Validate and send
116    pub async fn send(&self) -> anyhow::Result<UploadUrlResponse> {
117        self.body.validate()?;
118        let resp = self.post().await?;
119        let parsed = resp.json::<UploadUrlResponse>().await?;
120        Ok(parsed)
121    }
122}
123
124impl HttpClient for DocumentUploadUrlRequest {
125    type Body = UploadUrlBody;
126    type ApiUrl = String;
127    type ApiKey = String;
128
129    fn api_url(&self) -> &Self::ApiUrl {
130        &self.url
131    }
132    fn api_key(&self) -> &Self::ApiKey {
133        &self.key
134    }
135    fn body(&self) -> &Self::Body {
136        &self.body
137    }
138}