zai_rs/knowledge/
update.rs1use std::{collections::HashMap, sync::Arc};
2
3use serde::{Deserialize, Serialize};
4use validator::Validate;
5
6use super::create::{BackgroundColor, EmbeddingId, KnowledgeIcon};
7use crate::client::{
8 endpoints::{ApiBase, EndpointConfig, join_url, paths},
9 http::{HttpClient, HttpClientConfig, parse_typed_response},
10};
11
12#[derive(Debug, Clone, Default, Serialize, Deserialize, Validate)]
14pub struct UpdateKnowledgeBody {
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub embedding_id: Option<EmbeddingId>,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 #[validate(length(min = 1))]
21 pub name: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub description: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
27 pub background: Option<BackgroundColor>,
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub icon: Option<KnowledgeIcon>,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub callback_url: Option<String>,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub callback_header: Option<HashMap<String, String>>,
37}
38
39impl UpdateKnowledgeBody {
40 fn is_empty(&self) -> bool {
42 self.embedding_id.is_none()
43 && self.name.is_none()
44 && self.description.is_none()
45 && self.background.is_none()
46 && self.icon.is_none()
47 && self.callback_url.is_none()
48 && self.callback_header.is_none()
49 }
50}
51
52pub struct KnowledgeUpdateRequest {
54 pub key: String,
56 url: String,
57 endpoint_config: EndpointConfig,
58 api_base: ApiBase,
59 id: String,
60 http_config: Arc<HttpClientConfig>,
61 body: UpdateKnowledgeBody,
62}
63
64impl KnowledgeUpdateRequest {
65 pub fn new(key: String, id: impl AsRef<str>) -> Self {
67 let id = id.as_ref().to_string();
68 let endpoint_config = EndpointConfig::default();
69 let api_base = ApiBase::LlmApplication;
70 let url = endpoint_config.url(&api_base, &join_url(paths::KNOWLEDGE, &id));
71 Self {
72 key,
73 url,
74 endpoint_config,
75 api_base,
76 id,
77 http_config: Arc::new(HttpClientConfig::default()),
78 body: UpdateKnowledgeBody::default(),
79 }
80 }
81
82 fn rebuild_url(&mut self) {
83 self.url = self
84 .endpoint_config
85 .url(&self.api_base, &join_url(paths::KNOWLEDGE, &self.id));
86 }
87
88 pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
89 self.api_base = ApiBase::Custom(base_url.into());
90 self.rebuild_url();
91 self
92 }
93
94 pub fn with_endpoint_config(mut self, endpoint_config: EndpointConfig) -> Self {
95 self.endpoint_config = endpoint_config;
96 self.rebuild_url();
97 self
98 }
99
100 pub fn with_http_config(mut self, config: HttpClientConfig) -> Self {
101 self.http_config = Arc::new(config);
102 self
103 }
104
105 pub fn with_embedding_id(mut self, id: EmbeddingId) -> Self {
107 self.body.embedding_id = Some(id);
108 self
109 }
110 pub fn with_name(mut self, name: impl Into<String>) -> Self {
111 self.body.name = Some(name.into());
112 self
113 }
114 pub fn with_description(mut self, desc: impl Into<String>) -> Self {
115 self.body.description = Some(desc.into());
116 self
117 }
118 pub fn with_background(mut self, bg: BackgroundColor) -> Self {
119 self.body.background = Some(bg);
120 self
121 }
122 pub fn with_icon(mut self, icon: KnowledgeIcon) -> Self {
123 self.body.icon = Some(icon);
124 self
125 }
126 pub fn with_callback_url(mut self, url: impl Into<String>) -> Self {
127 self.body.callback_url = Some(url.into());
128 self
129 }
130 pub fn with_callback_header(mut self, headers: HashMap<String, String>) -> Self {
131 self.body.callback_header = Some(headers);
132 self
133 }
134
135 pub async fn send(&self) -> crate::ZaiResult<KnowledgeUpdateResponse> {
136 if self.body.is_empty() {
137 return Err(crate::client::error::ZaiError::ApiError {
138 code: 1200,
139 message: "update body is empty; set at least one field".to_string(),
140 });
141 }
142
143 self.body.validate()?;
144 let resp = self.put().await?;
145 parse_typed_response::<KnowledgeUpdateResponse>(resp).await
146 }
147
148 pub fn put(
149 &self,
150 ) -> impl std::future::Future<Output = crate::ZaiResult<reqwest::Response>> + Send {
151 HttpClient::put(self)
152 }
153}
154
155impl HttpClient for KnowledgeUpdateRequest {
156 type Body = UpdateKnowledgeBody;
157 type ApiUrl = String;
158 type ApiKey = String;
159
160 fn api_url(&self) -> &Self::ApiUrl {
161 &self.url
162 }
163 fn api_key(&self) -> &Self::ApiKey {
164 &self.key
165 }
166 fn body(&self) -> &Self::Body {
167 &self.body
168 }
169
170 fn http_config(&self) -> Arc<HttpClientConfig> {
171 self.http_config.clone()
172 }
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
177pub struct KnowledgeUpdateResponse {
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub code: Option<i64>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub message: Option<String>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub timestamp: Option<u64>,
184}