use super::{CompletionChoice, CompletionRequest, CompletionResponse};
use crate::protocols::common;
use crate::protocols::openai::CompletionUsage;
impl CompletionRequest {
pub fn response_generator(&self) -> DeltaGenerator {
let options = DeltaGeneratorOptions {
enable_usage: true,
enable_logprobs: false,
};
DeltaGenerator::new(self.inner.model.clone(), options)
}
}
#[derive(Debug, Clone, Default)]
pub struct DeltaGeneratorOptions {
pub enable_usage: bool,
pub enable_logprobs: bool,
}
#[derive(Debug, Clone)]
pub struct DeltaGenerator {
id: String,
object: String,
created: u64,
model: String,
system_fingerprint: Option<String>,
usage: CompletionUsage,
options: DeltaGeneratorOptions,
}
impl DeltaGenerator {
pub fn new(model: String, options: DeltaGeneratorOptions) -> Self {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
Self {
id: format!("cmpl-{}", uuid::Uuid::new_v4()),
object: "text_completion".to_string(),
created: now,
model,
system_fingerprint: None,
usage: CompletionUsage::default(),
options,
}
}
pub fn update_isl(&mut self, isl: i32) {
self.usage.prompt_tokens = isl;
}
pub fn create_choice(
&self,
index: u64,
text: Option<String>,
finish_reason: Option<String>,
) -> CompletionResponse {
CompletionResponse {
id: self.id.clone(),
object: self.object.clone(),
created: self.created,
model: self.model.clone(),
system_fingerprint: self.system_fingerprint.clone(),
choices: vec![CompletionChoice {
text: text.unwrap_or_default(),
index,
finish_reason,
logprobs: None,
}],
usage: if self.options.enable_usage {
Some(self.usage.clone())
} else {
None
},
}
}
}
impl crate::protocols::openai::DeltaGeneratorExt<CompletionResponse> for DeltaGenerator {
fn choice_from_postprocessor(
&mut self,
delta: common::llm_backend::BackendOutput,
) -> anyhow::Result<CompletionResponse> {
if self.options.enable_usage {
self.usage.completion_tokens += delta.token_ids.len() as i32;
}
let finish_reason = match delta.finish_reason {
Some(common::FinishReason::EoS) => Some("stop".to_string()),
Some(common::FinishReason::Stop) => Some("stop".to_string()),
Some(common::FinishReason::Length) => Some("length".to_string()),
Some(common::FinishReason::Cancelled) => Some("cancelled".to_string()),
Some(common::FinishReason::Error(err_msg)) => {
return Err(anyhow::anyhow!(err_msg));
}
None => None,
};
let index = 0;
Ok(self.create_choice(index, delta.text, finish_reason))
}
}