1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ChatCompletionChunk {
6 pub id: String,
7 pub object: String,
8 pub created: i64,
9 pub model: String,
10 pub choices: Vec<Choice>,
11}
12
13impl ChatCompletionChunk {
14 pub fn new(id: impl Into<String>, model: impl Into<String>) -> Self {
15 Self {
16 id: id.into(),
17 object: "chat.completion.chunk".to_string(),
18 created: chrono::Utc::now().timestamp(),
19 model: model.into(),
20 choices: Vec::new(),
21 }
22 }
23
24 pub fn with_choice(mut self, choice: Choice) -> Self {
25 self.choices.push(choice);
26 self
27 }
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct Choice {
32 pub index: u32,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub delta: Option<MessageDelta>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub finish_reason: Option<String>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct MessageDelta {
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub role: Option<String>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub content: Option<String>,
45}
46
47impl MessageDelta {
48 pub fn content(content: impl Into<String>) -> Self {
49 Self {
50 role: None,
51 content: Some(content.into()),
52 }
53 }
54
55 pub fn with_role(mut self, role: impl Into<String>) -> Self {
56 self.role = Some(role.into());
57 self
58 }
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct ChatCompletionResponse {
64 pub id: String,
65 pub object: String,
66 pub created: i64,
67 pub model: String,
68 pub choices: Vec<CompletionChoice>,
69 pub usage: Usage,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct CompletionChoice {
74 pub index: u32,
75 pub message: MessageContent,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub finish_reason: Option<String>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct MessageContent {
82 pub role: String,
83 pub content: String,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize, Default)]
87pub struct Usage {
88 pub prompt_tokens: u32,
89 pub completion_tokens: u32,
90 pub total_tokens: u32,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct ModelInfo {
96 pub id: String,
97 pub object: String,
98 pub created: i64,
99 pub owned_by: String,
100}
101
102impl ModelInfo {
103 pub fn new(id: impl Into<String>, owned_by: impl Into<String>) -> Self {
104 Self {
105 id: id.into(),
106 object: "model".to_string(),
107 created: chrono::Utc::now().timestamp(),
108 owned_by: owned_by.into(),
109 }
110 }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct ModelListResponse {
116 pub object: String,
117 pub data: Vec<ModelInfo>,
118}
119
120impl ModelListResponse {
121 pub fn new(models: Vec<ModelInfo>) -> Self {
122 Self {
123 object: "list".to_string(),
124 data: models,
125 }
126 }
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct ErrorResponse {
132 pub error: ErrorDetail,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ErrorDetail {
137 pub message: String,
138 #[serde(rename = "type")]
139 pub error_type: String,
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub param: Option<String>,
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub code: Option<String>,
144}
145
146impl ErrorResponse {
147 pub fn new(message: impl Into<String>, error_type: impl Into<String>) -> Self {
148 Self {
149 error: ErrorDetail {
150 message: message.into(),
151 error_type: error_type.into(),
152 param: None,
153 code: None,
154 },
155 }
156 }
157
158 pub fn with_code(mut self, code: impl Into<String>) -> Self {
159 self.error.code = Some(code.into());
160 self
161 }
162}