use crate::cache::CacheStats;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum InputType {
Single(String),
Batch(Vec<String>),
}
impl InputType {
pub fn into_text_input(self) -> crate::server::channel::TextInput {
match self {
Self::Single(text) => crate::server::channel::TextInput::Single(text),
Self::Batch(texts) => crate::server::channel::TextInput::Batch(texts),
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct EmbeddingsRequest {
pub model: String,
pub input: InputType,
#[serde(default = "default_encoding_format")]
pub encoding_format: String,
pub dimensions: Option<usize>,
pub user: Option<String>,
pub truncate: Option<crate::config::TruncateTokens>,
}
fn default_encoding_format() -> String {
"float".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmbeddingsResponse {
pub object: String,
pub data: Vec<EmbeddingData>,
pub model: String,
pub usage: Usage,
}
impl EmbeddingsResponse {
pub fn new(model: String, embeddings: Vec<Vec<f32>>, token_count: usize) -> Self {
let data = embeddings
.into_iter()
.enumerate()
.map(|(index, embedding)| EmbeddingData {
index,
object: "embedding".to_string(),
embedding: EmbeddingValue::Float(embedding),
})
.collect();
Self {
object: "list".to_string(),
data,
model,
usage: Usage {
prompt_tokens: token_count,
total_tokens: token_count,
},
}
}
pub fn new_base64(model: String, embeddings: Vec<Vec<f32>>, token_count: usize) -> Self {
let data = embeddings
.into_iter()
.enumerate()
.map(|(index, embedding)| {
let bytes: Vec<u8> = embedding.iter().flat_map(|f| f.to_le_bytes()).collect();
let base64 = STANDARD.encode(&bytes);
EmbeddingData {
index,
object: "embedding".to_string(),
embedding: EmbeddingValue::Base64(base64),
}
})
.collect();
Self {
object: "list".to_string(),
data,
model,
usage: Usage {
prompt_tokens: token_count,
total_tokens: token_count,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmbeddingData {
pub index: usize,
pub object: String,
pub embedding: EmbeddingValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EmbeddingValue {
Float(Vec<f32>),
Base64(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Usage {
pub prompt_tokens: usize,
pub total_tokens: usize,
}
#[derive(Debug, Clone, Serialize)]
pub struct ErrorResponse {
pub error: ErrorDetail,
}
#[derive(Debug, Clone, Serialize)]
pub struct ErrorDetail {
pub message: String,
#[serde(rename = "type")]
pub error_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<String>,
}
impl ErrorResponse {
pub fn invalid_request(message: impl Into<String>) -> Self {
Self {
error: ErrorDetail {
message: message.into(),
error_type: "invalid_request_error".to_string(),
code: None,
},
}
}
pub fn model_not_found(model: &str) -> Self {
Self {
error: ErrorDetail {
message: format!("Model '{model}' not found"),
error_type: "model_not_found_error".to_string(),
code: Some("model_not_found".to_string()),
},
}
}
pub fn rate_limit() -> Self {
Self {
error: ErrorDetail {
message: "Rate limit exceeded. Please try again later.".to_string(),
error_type: "rate_limit_error".to_string(),
code: Some("rate_limit_exceeded".to_string()),
},
}
}
pub fn internal_error(message: impl Into<String>) -> Self {
Self {
error: ErrorDetail {
message: message.into(),
error_type: "internal_error".to_string(),
code: Some("internal_server_error".to_string()),
},
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct ListModelsResponse {
pub object: String,
pub data: Vec<ModelData>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ModelData {
pub id: String,
pub object: String,
pub created: i64,
pub owned_by: String,
pub context_size: Option<u32>,
}
impl ModelData {
pub fn new(id: String) -> Self {
Self {
id,
object: "model".to_string(),
created: 1_700_000_000, owned_by: "embellama".to_string(),
context_size: None,
}
}
pub fn new_with_context(id: String, context_size: Option<u32>) -> Self {
Self {
id,
object: "model".to_string(),
created: 1_700_000_000, owned_by: "embellama".to_string(),
context_size,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct RerankRequest {
pub model: String,
pub query: String,
pub documents: Vec<String>,
pub top_n: Option<usize>,
#[serde(default = "default_normalize")]
pub normalize: bool,
}
fn default_normalize() -> bool {
true
}
#[derive(Debug, Clone, Serialize)]
pub struct RerankResponse {
pub object: String,
pub results: Vec<RerankResultData>,
pub model: String,
pub usage: RerankUsage,
}
#[derive(Debug, Clone, Serialize)]
pub struct RerankResultData {
pub index: usize,
pub relevance_score: f32,
}
#[derive(Debug, Clone, Serialize)]
pub struct RerankUsage {
pub total_documents: usize,
}
use base64::{Engine as _, engine::general_purpose::STANDARD};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheWarmRequest {
pub texts: Vec<String>,
pub model: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct CacheWarmResponse {
pub status: String,
pub texts_processed: usize,
pub already_cached: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheStatsResponse {
pub enabled: bool,
pub stats: Option<CacheStats>,
pub memory: MemoryInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryInfo {
pub total_bytes: u64,
pub available_bytes: u64,
pub usage_percentage: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheClearResponse {
pub status: String,
pub previous_stats: Option<CacheStats>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PrefixRegisterRequest {
pub prefix: String,
pub model: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct PrefixRegisterResponse {
pub status: String,
pub token_count: usize,
pub memory_usage: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct PrefixListResponse {
pub prefixes: Vec<PrefixInfo>,
pub total_count: usize,
}
#[derive(Debug, Clone, Serialize)]
pub struct PrefixInfo {
pub key: String,
pub preview: String,
pub token_count: usize,
pub access_count: usize,
pub age_seconds: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct PrefixStatsResponse {
pub enabled: bool,
pub session_count: usize,
pub total_hits: u64,
pub total_misses: u64,
pub total_evictions: u64,
pub memory_usage_bytes: u64,
pub hit_rate: f64,
}