use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum FinishReason {
Stop,
Length,
ContentFilter,
}
#[derive(Clone, Debug, Default, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Logprobs {
#[default]
No,
Sampled,
Top(u8),
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Logprob {
pub token: Vec<u8>,
pub logprob: f64,
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Distribution {
pub sampled: Logprob,
pub top: Vec<Logprob>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
pub struct TokenUsage {
pub prompt: u32,
pub completion: u32,
}
#[derive(Clone, Debug, Serialize)]
pub struct CompletionParams {
pub max_tokens: Option<u32>,
pub temperature: Option<f64>,
pub top_k: Option<u32>,
pub top_p: Option<f64>,
pub stop: Vec<String>,
pub return_special_tokens: bool,
pub frequency_penalty: Option<f64>,
pub presence_penalty: Option<f64>,
pub logprobs: Logprobs,
}
impl Default for CompletionParams {
fn default() -> Self {
Self {
return_special_tokens: true,
max_tokens: None,
temperature: None,
top_k: None,
top_p: None,
stop: Vec::new(),
frequency_penalty: None,
presence_penalty: None,
logprobs: Logprobs::default(),
}
}
}
#[derive(Clone, Debug, Serialize)]
pub struct CompletionRequest {
pub model: String,
pub prompt: String,
pub params: CompletionParams,
}
impl CompletionRequest {
pub fn new(model: impl Into<String>, prompt: impl Into<String>) -> Self {
Self {
model: model.into(),
prompt: prompt.into(),
params: CompletionParams::default(),
}
}
#[must_use]
pub fn with_params(mut self, params: CompletionParams) -> Self {
self.params = params;
self
}
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Completion {
pub text: String,
pub finish_reason: FinishReason,
pub logprobs: Vec<Distribution>,
pub usage: TokenUsage,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message {
pub role: String,
pub content: String,
}
impl Message {
pub fn new(role: impl Into<String>, content: impl Into<String>) -> Self {
Self {
role: role.into(),
content: content.into(),
}
}
pub fn user(content: impl Into<String>) -> Self {
Self::new("user", content)
}
pub fn assistant(content: impl Into<String>) -> Self {
Self::new("assistant", content)
}
pub fn system(content: impl Into<String>) -> Self {
Self::new("system", content)
}
}
#[derive(Clone, Debug, Default, Serialize)]
pub struct ChatParams {
pub max_tokens: Option<u32>,
pub temperature: Option<f64>,
pub top_p: Option<f64>,
pub frequency_penalty: Option<f64>,
pub presence_penalty: Option<f64>,
pub logprobs: Logprobs,
}
#[derive(Clone, Debug, Serialize)]
pub struct ChatRequest {
pub model: String,
pub messages: Vec<Message>,
pub params: ChatParams,
}
impl ChatRequest {
pub fn new(model: impl Into<String>, message: Message) -> Self {
Self {
model: model.into(),
messages: vec![message],
params: ChatParams::default(),
}
}
#[must_use]
pub fn and_message(mut self, message: Message) -> Self {
self.messages.push(message);
self
}
#[must_use]
pub fn with_params(mut self, params: ChatParams) -> Self {
self.params = params;
self
}
}
#[derive(Clone, Debug, Deserialize)]
pub struct ChatResponse {
pub message: Message,
pub finish_reason: FinishReason,
pub logprobs: Vec<Distribution>,
pub usage: TokenUsage,
}