zai_rs/knowledge/
create.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2use validator::Validate;
3
4use crate::client::http::HttpClient;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum EmbeddingId {
9 Embedding2,
11 Embedding3New,
13}
14
15impl EmbeddingId {
16 pub fn as_i64(&self) -> i64 {
17 match self {
18 EmbeddingId::Embedding2 => 3,
19 EmbeddingId::Embedding3New => 11,
20 }
21 }
22}
23
24impl Serialize for EmbeddingId {
25 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
26 serializer.serialize_i64(self.as_i64())
27 }
28}
29
30impl<'de> Deserialize<'de> for EmbeddingId {
31 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
32 let v = i64::deserialize(deserializer)?;
33 match v {
34 3 => Ok(EmbeddingId::Embedding2),
35 11 => Ok(EmbeddingId::Embedding3New),
36 other => Err(serde::de::Error::custom(format!(
37 "unsupported embedding_id: {} (expected 3 or 11)",
38 other
39 ))),
40 }
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
46#[serde(rename_all = "lowercase")]
47pub enum BackgroundColor {
48 Blue,
49 Red,
50 Orange,
51 Purple,
52 Sky,
53 Green,
54 Yellow,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
59#[serde(rename_all = "lowercase")]
60pub enum KnowledgeIcon {
61 Question,
62 Book,
63 Seal,
64 Wrench,
65 Tag,
66 Horn,
67 House,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
72pub struct CreateKnowledgeBody {
73 pub embedding_id: EmbeddingId,
75 #[validate(length(min = 1))]
77 pub name: String,
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub description: Option<String>,
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub background: Option<BackgroundColor>,
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub icon: Option<KnowledgeIcon>,
87}
88
89pub struct CreateKnowledgeRequest {
91 pub key: String,
93 url: String,
94 body: CreateKnowledgeBody,
95}
96
97impl CreateKnowledgeRequest {
98 pub fn new(key: String, embedding_id: EmbeddingId, name: impl Into<String>) -> Self {
100 let url = "https://open.bigmodel.cn/api/llm-application/open/knowledge".to_string();
101 let body = CreateKnowledgeBody {
102 embedding_id,
103 name: name.into(),
104 description: None,
105 background: None,
106 icon: None,
107 };
108 Self { key, url, body }
109 }
110
111 pub fn with_description(mut self, desc: impl Into<String>) -> Self {
113 self.body.description = Some(desc.into());
114 self
115 }
116 pub fn with_background(mut self, bg: BackgroundColor) -> Self {
117 self.body.background = Some(bg);
118 self
119 }
120 pub fn with_icon(mut self, icon: KnowledgeIcon) -> Self {
121 self.body.icon = Some(icon);
122 self
123 }
124
125 pub async fn send(&self) -> anyhow::Result<CreateKnowledgeResponse> {
127 self.body.validate()?;
128 let resp: reqwest::Response = self.post().await?;
129 let parsed = resp.json::<CreateKnowledgeResponse>().await?;
130 Ok(parsed)
131 }
132}
133
134impl HttpClient for CreateKnowledgeRequest {
135 type Body = CreateKnowledgeBody;
136 type ApiUrl = String;
137 type ApiKey = String;
138
139 fn api_url(&self) -> &Self::ApiUrl {
140 &self.url
141 }
142 fn api_key(&self) -> &Self::ApiKey {
143 &self.key
144 }
145 fn body(&self) -> &Self::Body {
146 &self.body
147 }
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
152pub struct CreateKnowledgeResponseData {
153 #[serde(skip_serializing_if = "Option::is_none")]
155 pub id: Option<String>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
159pub struct CreateKnowledgeResponse {
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub data: Option<CreateKnowledgeResponseData>,
162 #[serde(skip_serializing_if = "Option::is_none")]
163 pub code: Option<i64>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub message: Option<String>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub timestamp: Option<u64>,
168}