(
state: web::Data<Arc<RwLock<Master<M>>>>,
request: ChatRequest,
)
| 180 | } |
| 181 | |
| 182 | async fn generate_text_stream<M: Model>( |
| 183 | state: web::Data<Arc<RwLock<Master<M>>>>, |
| 184 | request: ChatRequest, |
| 185 | ) -> HttpResponse { |
| 186 | let id = format!("chatcmpl-{}", uuid::Uuid::new_v4()); |
| 187 | let created = SystemTime::now() |
| 188 | .duration_since(UNIX_EPOCH) |
| 189 | .unwrap() |
| 190 | .as_secs(); |
| 191 | let model = M::MODEL_NAME.to_string(); |
| 192 | |
| 193 | let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<Option<String>>(); |
| 194 | |
| 195 | let state_clone = state.clone(); |
| 196 | tokio::spawn(async move { |
| 197 | let mut master = state_clone.write().await; |
| 198 | |
| 199 | if let Err(e) = master.reset() { |
| 200 | log::error!("reset error: {e}"); |
| 201 | let _ = tx.send(None); |
| 202 | return; |
| 203 | } |
| 204 | |
| 205 | let model = match master.model.as_mut() { |
| 206 | Some(m) if m.output_modality() == OutputModality::Text => m, |
| 207 | _ => { |
| 208 | log::error!("no text model loaded"); |
| 209 | let _ = tx.send(None); |
| 210 | return; |
| 211 | } |
| 212 | }; |
| 213 | for message in request.messages { |
| 214 | if let Err(e) = model.add_message(message) { |
| 215 | log::error!("add_message error: {e}"); |
| 216 | let _ = tx.send(None); |
| 217 | return; |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | if let Err(e) = master |
| 222 | .generate_text(request.max_tokens, |data| { |
| 223 | if data.is_empty() { |
| 224 | let _ = tx.send(None); |
| 225 | } else { |
| 226 | let _ = tx.send(Some(data.to_string())); |
| 227 | } |
| 228 | }) |
| 229 | .await |
| 230 | { |
| 231 | log::error!("generate_text error: {e}"); |
| 232 | let _ = tx.send(None); |
| 233 | } |
| 234 | |
| 235 | let _ = master.goodbye().await; |
| 236 | }); |
| 237 | |
| 238 | let stream = async_stream::stream! { |
| 239 | // Send initial role chunk |
no test coverage detected