1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::{Map, Value};
5use validator::Validate;
6
7use super::{
8 common::{default_true, deserialize_null_as_false, GenerationRequest, InputIds},
9 sampling_params::SamplingParams,
10};
11use crate::validated::Normalizable;
12
13#[derive(Clone, Debug, Serialize, Deserialize, Validate, schemars::JsonSchema)]
18#[validate(schema(function = "validate_generate_request"))]
19pub struct GenerateRequest {
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub text: Option<String>,
23
24 #[serde(default = "super::common::default_unknown_model")]
25 pub model: String,
26
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub input_ids: Option<InputIds>,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
35 pub input_embeds: Option<Value>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
42 pub image_data: Option<Value>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
49 pub video_data: Option<Value>,
50
51 #[serde(skip_serializing_if = "Option::is_none")]
56 pub audio_data: Option<Value>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub sampling_params: Option<SamplingParams>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub return_logprob: Option<bool>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub logprob_start_len: Option<i32>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub top_logprobs_num: Option<i32>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub token_ids_logprob: Option<Vec<u32>>,
77
78 #[serde(default)]
80 pub return_text_in_logprobs: bool,
81
82 #[serde(default, deserialize_with = "deserialize_null_as_false")]
84 pub stream: bool,
85
86 #[serde(default = "default_true")]
88 pub log_metrics: bool,
89
90 #[serde(default)]
92 pub return_hidden_states: bool,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub modalities: Option<Vec<String>>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 pub session_params: Option<HashMap<String, Value>>,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub lora_path: Option<String>,
105
106 #[serde(skip_serializing_if = "Option::is_none")]
108 pub lora_id: Option<String>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
114 pub custom_logit_processor: Option<String>,
115
116 #[serde(skip_serializing_if = "Option::is_none")]
118 pub bootstrap_host: Option<String>,
119
120 #[serde(skip_serializing_if = "Option::is_none")]
122 pub bootstrap_port: Option<i32>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub bootstrap_room: Option<i32>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub bootstrap_pair_key: Option<String>,
131
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub data_parallel_rank: Option<i32>,
135
136 #[serde(default)]
138 pub background: bool,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
142 pub conversation_id: Option<String>,
143
144 #[serde(skip_serializing_if = "Option::is_none")]
146 pub priority: Option<i32>,
147
148 #[serde(skip_serializing_if = "Option::is_none")]
150 pub extra_key: Option<String>,
151
152 #[serde(default)]
154 pub no_logs: bool,
155
156 #[serde(skip_serializing_if = "Option::is_none")]
158 pub custom_labels: Option<HashMap<String, String>>,
159
160 #[serde(default)]
162 pub return_bytes: bool,
163
164 #[serde(default)]
166 pub return_entropy: bool,
167
168 #[serde(skip_serializing_if = "Option::is_none")]
170 pub rid: Option<String>,
171
172 #[serde(flatten)]
174 pub other: Map<String, Value>,
175}
176
177impl Normalizable for GenerateRequest {
178 }
180
181fn validate_generate_request(req: &GenerateRequest) -> Result<(), validator::ValidationError> {
183 let has_text = req.text.is_some();
186 let has_input_ids = req.input_ids.is_some();
187
188 let count = [has_text, has_input_ids].iter().filter(|&&x| x).count();
189
190 if count == 0 {
191 return Err(validator::ValidationError::new(
192 "Either text or input_ids should be provided.",
193 ));
194 }
195
196 if count > 1 {
197 return Err(validator::ValidationError::new(
198 "Either text or input_ids should be provided.",
199 ));
200 }
201
202 Ok(())
203}
204
205impl GenerationRequest for GenerateRequest {
206 fn is_stream(&self) -> bool {
207 self.stream
208 }
209
210 fn get_model(&self) -> Option<&str> {
211 Some(self.model.as_str())
212 }
213
214 fn extract_text_for_routing(&self) -> String {
215 if let Some(ref text) = self.text {
217 return text.clone();
218 }
219
220 if let Some(ref input_ids) = self.input_ids {
221 return match input_ids {
222 InputIds::Single(ids) => ids
223 .iter()
224 .map(|&id| id.to_string())
225 .collect::<Vec<String>>()
226 .join(" "),
227 InputIds::Batch(batches) => batches
228 .iter()
229 .flat_map(|batch| batch.iter().map(|&id| id.to_string()))
230 .collect::<Vec<String>>()
231 .join(" "),
232 };
233 }
234
235 String::new()
237 }
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
263pub struct GenerateResponse {
264 pub text: String,
265 pub output_ids: Vec<u32>,
266 pub meta_info: GenerateMetaInfo,
267}
268
269#[serde_with::skip_serializing_none]
271#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
272pub struct GenerateMetaInfo {
273 pub id: String,
274 pub finish_reason: GenerateFinishReason,
275 pub prompt_tokens: u32,
276 pub weight_version: String,
277 pub input_token_logprobs: Option<Vec<Vec<Option<f64>>>>,
278 pub output_token_logprobs: Option<Vec<Vec<Option<f64>>>>,
279 pub completion_tokens: u32,
280 pub cached_tokens: u32,
281 pub e2e_latency: f64,
282 pub matched_stop: Option<Value>,
283}
284
285#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
287#[serde(untagged)]
288pub enum GenerateFinishReason {
289 Length {
290 #[serde(rename = "type")]
291 finish_type: GenerateFinishType,
292 length: u32,
293 },
294 Stop {
295 #[serde(rename = "type")]
296 finish_type: GenerateFinishType,
297 },
298 Other(Value),
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
302#[serde(rename_all = "lowercase")]
303pub enum GenerateFinishType {
304 Length,
305 Stop,
306}