use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use uuid::Uuid; #[derive(Debug, Serialize, ToSchema)] pub struct ErrorResponse { pub error: String, } impl ErrorResponse { pub fn new(msg: impl Into) -> Self { Self { error: msg.into() } } } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct ModelsResponse { pub models: Vec, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct ModelInfo { pub name: String, pub family: Option, pub parameter_size: Option, pub quantization: Option, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct LoadModelResponse { pub model: String, pub status: String, pub keep_alive: String, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct LoadModelBody { pub keep_alive: Option, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct UnloadModelResponse { pub model: String, pub status: String, } #[derive(Debug, Deserialize, Serialize, ToSchema, Default)] pub struct BaseLLMRequest { pub model: String, #[serde(default)] pub stream: bool, pub temperature: Option, pub top_p: Option, // Ollama-native pub top_k: Option, pub repeat_penalty: Option, pub seed: Option, pub num_ctx: Option, pub num_predict: Option, pub stop: Option>, pub keep_alive: Option, } #[derive(Debug, Deserialize, Serialize, ToSchema)] pub struct CompletionRequest { #[serde(flatten)] pub base: BaseLLMRequest, pub prompt: String, } #[derive(Debug, Serialize, Deserialize, ToSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum CompletionObject { TextCompletion, } #[derive(Debug, Serialize, Deserialize, ToSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum FinishReason { Stop, Length, ContentFilter, ToolCalls, Error, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct CompletionResponse { pub id: String, pub object: CompletionObject, pub created: u64, pub model: String, pub choices: Vec, pub usage: Usage, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct Choice { pub text: String, pub index: u32, pub finish_reason: FinishReason, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct Usage { pub prompt_tokens: u32, pub completion_tokens: u32, pub total_tokens: u32, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct CompletionChunk { pub id: String, pub object: String, pub choices: Vec, } #[derive(Debug, Deserialize, Serialize, ToSchema)] pub struct ChatRequest { #[serde(flatten)] pub base: BaseLLMRequest, pub messages: Vec, // Non standard Open AI pub conversation_id: Option, } #[derive(Debug, Deserialize, Serialize, ToSchema)] pub struct Message { pub role: Role, pub content: String, } #[derive(Debug, Deserialize, Serialize, ToSchema, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum Role { System, User, Assistant, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct ChatCompletionResponse { pub id: String, pub object: String, pub created: u64, pub model: String, pub choices: Vec, pub usage: Option, // optional (Ollama may not always provide) pub conversation_id: Option, } #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct ChatChoice { pub index: u32, pub message: Message, pub finish_reason: FinishReason, } #[derive(Debug, Serialize, ToSchema)] pub struct ChatCompletionChunk { pub id: String, pub object: String, pub choices: Vec, } #[derive(Debug, Serialize, ToSchema)] pub struct ChatChunkChoice { pub index: u32, pub delta: ChatDelta, pub finish_reason: Option, } #[derive(Debug, Serialize, ToSchema)] pub struct ChatDelta { pub role: Option, pub content: Option, } #[derive(serde::Deserialize)] pub struct CreateApiKeyRequest { pub name: String, pub scopes: Vec, } #[derive(serde::Serialize)] pub struct CreateApiKeyResponse { pub api_key: String, // ONLY returned once }