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