1use crate::deep_seek::Client;
2use bon::Builder;
3use serde::{Deserialize, Serialize};
4
5#[derive(Builder, Serialize)]
7pub struct Chat<'a> {
8 #[builder(start_fn)]
9 #[serde(skip_serializing)]
10 pub(crate) client: &'a Client,
11 #[builder(field)]
12 stop: Vec<String>,
13 pub(crate) messages: &'a [Message],
14 model: &'a str,
15 frequency_penalty: Option<f32>, max_tokens: Option<u32>, presence_penalty: Option<f32>, response_format: Option<ResponseFormat<'a>>, #[builder(default = false)]
20 pub(crate) stream: bool,
21 stream_options: Option<StreamOption>,
22 temperature: Option<f32>, top_p: Option<f32>, logprobs: Option<bool>,
29 top_logprobs: Option<u32>, }
31
32#[derive(Serialize, Debug)]
33pub struct Message {
34 pub content: String,
35 pub role: Role,
36}
37
38#[derive(Serialize, Deserialize, PartialEq, Debug)]
39#[serde(rename_all = "lowercase")]
40pub enum Role {
41 System,
42 User,
43 Assistant,
44}
45
46#[derive(Serialize, Debug)]
47pub struct ResponseFormat<'a> {
48 pub r#type: &'a str,
49}
50
51#[derive(Serialize, Debug)]
52pub struct StreamOption {
53 pub include_usage: bool,
54}
55#[derive(Debug, Deserialize)]
59pub struct ChatResponse {
60 pub id: String,
61 pub choices: Vec<Choice>,
62 pub created: i64,
63 pub model: String,
64 pub system_fingerprint: String,
65 pub object: String,
66 pub usage: Usage,
67}
68
69#[derive(Debug, Deserialize)]
70pub struct Choice {
71 pub finish_reason: String,
73 pub index: i32,
74 pub message: ChoiceMessage,
75}
76
77#[derive(Debug, Deserialize)]
78pub struct ChoiceMessage {
79 pub content: String,
81 pub role: Role, pub reasoning_content: Option<String>,
84}
85
86#[derive(Debug, Deserialize)]
87pub struct Usage {
88 pub completion_tokens: i32,
89 pub prompt_tokens: i32,
90 pub prompt_cache_hit_tokens: i32,
91 pub prompt_cache_miss_tokens: i32,
92 pub total_tokens: i32,
93 pub completion_tokens_details: Option<CompletionTokensDetails>,
94}
95
96#[derive(Debug, Deserialize)]
97pub struct CompletionTokensDetails {
98 pub reasoning_tokens: i32,
99}
100
101#[test]
102fn check_response_deserialize() {
103 let json = r#"
104{
105 "id": "string", "choices": [
106 {
107 "finish_reason": "stop", "index": 0,
108 "message": {
109 "content": "string", "reasoning_content": "string",
110 "tool_calls": [
111 {
112 "id": "string", "type": "function",
113 "function": { "name": "string", "arguments": "string" }
114 }
115 ],
116 "role": "assistant"
117 },
118 "logprobs": {
119 "content": [
120 {
121 "token": "string", "logprob": 0, "bytes": [0],
122 "top_logprobs": [
123 { "token": "string", "logprob": 0, "bytes": [0] }
124 ]
125 }
126 ]
127 }
128 }
129 ],
130 "created": 0, "model": "string", "system_fingerprint": "string",
131 "object": "chat.completion",
132 "usage": {
133 "completion_tokens": 0, "prompt_tokens": 0,
134 "prompt_cache_hit_tokens": 0, "prompt_cache_miss_tokens": 0,
135 "total_tokens": 0,
136 "completion_tokens_details": { "reasoning_tokens": 0 }
137 }
138}
139"#;
140 let response = serde_json::from_str::<ChatResponse>(json);
141 assert!(
142 response.is_ok(),
143 "Failed to deserialize response: {:?}",
144 response.err()
145 );
146}
147
148#[derive(Deserialize, Debug)]
150pub struct StreamEventData {
151 pub id: String,
152 pub choices: Vec<StreamDataChoices>,
153 pub created: i64,
154 pub model: String,
155 pub system_fingerprint: String,
156 pub object: String,
157}
158
159#[derive(Deserialize, Debug)]
160pub struct StreamDataChoices {
161 pub delta: Delta,
162 pub finish_reason: Option<String>,
163 pub index: i32,
164}
165
166#[derive(Deserialize, Debug)]
167pub struct Delta {
168 pub content: Option<String>,
169 pub reasoning_content: Option<String>,
170 pub role: Option<Role>,
171}
172
173#[test]
174fn check_stream_event_data_deserialize() {
175 let json1 = r#"
176{
177 "id": "1f633d8bfc032625086f14113c411638",
178 "choices": [
179 {
180 "index": 0,
181 "delta": { "content": "", "role": "assistant" },
182 "finish_reason": null,
183 "logprobs": null
184 }
185 ],
186 "created": 1718345013,
187 "model": "deepseek-chat",
188 "system_fingerprint": "fp_a49d71b8a1",
189 "object": "chat.completion.chunk",
190 "usage": null
191}
192"#;
193 let json2 = r#"
194{
195 "choices": [
196 {
197 "delta": { "content": "", "role": null },
198 "finish_reason": "stop",
199 "index": 0,
200 "logprobs": null
201 }
202 ],
203 "created": 1718345013,
204 "id": "1f633d8bfc032625086f14113c411638",
205 "model": "deepseek-chat",
206 "object": "chat.completion.chunk",
207 "system_fingerprint": "fp_a49d71b8a1",
208 "usage": {
209 "completion_tokens": 9,
210 "prompt_tokens": 17,
211 "total_tokens": 26
212 }
213}
214 "#;
215
216 let response1 = serde_json::from_str::<StreamEventData>(json1);
217 let response2 = serde_json::from_str::<StreamEventData>(json2);
218
219 assert!(
220 response1.is_ok(),
221 "Failed to deserialize response1: {:?}",
222 response1.err()
223 );
224 assert!(
225 response2.is_ok(),
226 "Failed to deserialize response2: {:?}",
227 response2.err()
228 );
229}
230#[derive(Deserialize, Debug)]
233pub struct CheckBalanceResponse {
234 pub is_available: bool,
235 pub balance_infos: Vec<BalanceInfo>,
236}
237
238#[derive(Deserialize, Debug)]
239pub struct BalanceInfo {
240 pub currency: String,
241 pub total_balance: String,
242 pub granted_balance: String,
243 pub topped_up_balance: String,
244}