Skip to main content

deepseek_sdk/chat/
response.rs

1use super::*;
2
3/// Token usage statistics for a request.
4#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
5pub struct Usage {
6    /// Number of tokens in the generated completion.
7    pub completion_tokens: u64,
8
9    /// Number of tokens in the prompt. It equals prompt_cache_hit_tokens + prompt_cache_miss_tokens.
10    pub prompt_tokens: u64,
11
12    /// Number of tokens in the prompt that hits the context cache.
13    pub prompt_cache_hit_tokens: u64,
14
15    /// Number of tokens in the prompt that misses the context cache.
16    pub prompt_cache_miss_tokens: u64,
17
18    /// Total number of tokens used in the request (prompt + completion).
19    pub total_tokens: u64,
20
21    /// Breakdown of tokens used in a completion.
22    pub completion_tokens_details: Option<CompletionTokensDetails>,
23}
24#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
25pub struct CompletionTokensDetails {
26    /// Tokens generated by the model for reasoning.
27    pub reasoning_tokens: u64,
28}
29
30/// Generic chat response container.
31#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
32pub struct ChatGeneric<C> {
33    /// A unique identifier for the chat completion.
34    pub id: String,
35
36    pub choices: Vec<C>,
37
38    /// The Unix timestamp (in seconds) of when the chat completion was created.
39    pub created: u64,
40
41    /// The model used for the chat completion.
42    pub model: String,
43    /// This fingerprint represents the backend configuration that the model runs with.
44    pub system_fingerprint: String,
45
46    /// Possible values: \`chat.completion\`
47    ///
48    /// The object type, which is always `chat.completion`.
49    pub object: String,
50
51    /// Usage statistics for the completion request.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub usage: Option<Usage>,
54}
55
56/// Non-streaming choice result.
57#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
58pub struct ChatChoice {
59    /// Possible values: [`stop`, `length`, `content_filter`, `tool_calls`,
60    /// `insufficient_system_resource`]
61    ///
62    /// The reason the model stopped generating tokens.
63    /// This will be `stop` if the model hit a natural stop point or a provided stop sequence,
64    /// `length` if the maximum number of tokens specified in the request was reached,
65    /// `content_filter` if content was omitted due to a flag from our content filters,
66    /// `tool_calls` if the model called a tool,
67    /// or `insufficient_system_resource` if the request is interrupted due to insufficient resource of the inference system.
68    pub finish_reason: FinishReason,
69
70    /// The index of the choice in the list of choices.
71    pub index: u64,
72
73    /// A chat completion message generated by the model.
74    pub message: ChoiceMessage,
75
76    /// Log probability information for the choice.
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub logprobs: Option<Logprobs>,
79}
80
81/// Streaming choice delta.
82#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
83pub struct ChatChoiceStream {
84    /// Possible values: [`stop`, `length`, `content_filter`, `tool_calls`, `insufficient_system_resource`]
85    ///
86    /// The reason the model stopped generating tokens.
87    /// This will be `stop` if the model hit a natural stop point or a provided stop sequence,
88    /// `length` if the maximum number of tokens specified in the request was reached,
89    /// `content_filter` if content was omitted due to a flag from our content filters,
90    /// `tool_calls` if the model called a tool,
91    /// or `insufficient_system_resource` if the request is interrupted due to insufficient resource of the inference system.
92    pub finish_reason: Option<FinishReason>,
93
94    /// The index of the choice in the list of choices.
95    pub index: u64,
96
97    /// A chat completion delta generated by streamed model responses.
98    pub delta: ChoiceMessageDelta,
99
100    /// Log probability information for the choice.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub logprobs: Option<Logprobs>,
103}
104
105/// Assistant message content in non-streaming responses.
106#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
107pub struct ChoiceMessage {
108    /// The contents of the message.
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub content: Option<String>,
111
112    /// For thinking mode only. The reasoning contents of the assistant message, before the final answer.
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub reasoning_content: Option<String>,
115
116    /// The tool calls generated by the model.
117    #[serde(skip_serializing_if = "is_none_or_empty_vec")]
118    pub tool_calls: Option<Vec<ToolCall>>,
119
120    /// The role of the author of this message.
121    pub role: Role,
122}
123
124/// Assistant message delta in streaming responses.
125#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
126pub struct ChoiceMessageDelta {
127    /// The contents of the chunk message.
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub content: Option<String>,
130
131    /// For thinking mode only. The reasoning contents of the assistant message, before the final answer.
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub reasoning_content: Option<String>,
134    #[serde(skip_serializing_if = "is_none_or_empty_vec")]
135    pub tool_calls: Option<Vec<ToolCall>>,
136    /// Possible values: \`assistant\`
137    ///
138    /// The role of the author of this message.
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub role: Option<Role>,
141}
142
143/// Role of a chat message.
144#[non_exhaustive]
145#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
146#[serde(rename_all = "snake_case")]
147pub enum Role {
148    System,
149    User,
150    Assistant,
151    Tool,
152}
153
154/// Tool call emitted by the model.
155#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
156pub struct ToolCall {
157    /// The ID of the tool call.
158    pub id: String,
159    #[serde(rename = "type")]
160
161    /// Possible values: \`function\`
162    ///
163    ///The type of the tool. Currently, only `function` is supported.
164    pub typ: ToolCallType,
165
166    /// The function that the model called.
167    pub function: ToolCallFunction,
168}
169
170impl ToolCall {
171    /// Build a function tool call with an id, name, and arguments JSON string.
172    pub fn new(
173        id: impl Into<String>,
174        name: impl Into<String>,
175        arguments: impl Into<String>,
176    ) -> Self {
177        ToolCall {
178            id: id.into(),
179            typ: ToolCallType::Function,
180            function: ToolCallFunction {
181                name: name.into(),
182                arguments: arguments.into(),
183            },
184        }
185    }
186}
187
188/// Tool call type.
189#[non_exhaustive]
190#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
191#[serde(rename_all = "snake_case")]
192pub enum ToolCallType {
193    Function,
194}
195
196/// Tool call function payload.
197#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
198pub struct ToolCallFunction {
199    /// The name of the function to call.
200    pub name: String,
201    /// The arguments to call the function with, as generated by the model in JSON format.
202    /// Note that the model does not always generate valid JSON,
203    /// and may hallucinate parameters not defined by your function schema.
204    /// Validate the arguments in your code before calling your function.
205    pub arguments: String,
206}
207/// Reason for completion termination.
208#[non_exhaustive]
209#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
210#[serde(rename_all = "snake_case")]
211pub enum FinishReason {
212    Stop,
213    Length,
214    ContentFilter,
215    ToolCalls,
216    InsufficientSystemResources,
217}
218/// Token-level log probability data.
219#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
220pub struct Logprobs {
221    #[serde(skip_serializing_if = "is_none_or_empty_vec")]
222    pub content: Option<Vec<LogprobsContent>>,
223    #[serde(skip_serializing_if = "is_none_or_empty_vec")]
224    pub reasoning_content: Option<Vec<LogprobsReasoningContent>>,
225}
226/// Logprobs for content tokens.
227#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
228pub struct LogprobsContent {
229    pub token: String,
230    pub logprob: f64,
231    pub bytes: Option<Vec<u8>>,
232    pub top_logprobs: Vec<TopLogprobs>,
233}
234
235/// Top logprob candidates for a token.
236#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
237pub struct TopLogprobs {
238    pub token: String,
239    pub logprob: f64,
240    pub bytes: Option<Vec<u8>>,
241}
242/// Logprobs for reasoning tokens.
243#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
244pub struct LogprobsReasoningContent {
245    pub token: String,
246    pub logprob: f64,
247    pub bytes: Option<Vec<u8>>,
248    pub top_logprobs: Vec<TopLogprobs>,
249}