use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize)]
pub struct OllamaChatRequest {
pub model: String,
pub messages: Vec<OllamaChatMessage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<OllamaTool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_alive: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub think: Option<bool>,
}
#[derive(Debug, Clone, Serialize)]
pub struct OllamaGenerateRequest {
pub model: String,
pub prompt: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub suffix: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub images: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub template: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub raw: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_alive: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<Vec<i32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub think: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OllamaChatMessage {
pub role: String,
pub content: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub images: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_calls: Option<Vec<OllamaToolCall>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub thinking: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OllamaTool {
#[serde(rename = "type")]
pub tool_type: String,
pub function: OllamaFunction,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OllamaFunction {
pub name: String,
pub description: String,
pub parameters: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OllamaToolCall {
pub function: OllamaFunctionCall,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OllamaFunctionCall {
pub name: String,
pub arguments: serde_json::Value,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaChatResponse {
pub model: String,
pub created_at: String,
pub message: OllamaChatMessage,
pub done: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub done_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub load_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_eval_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_eval_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eval_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eval_duration: Option<u64>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaGenerateResponse {
pub model: String,
pub created_at: String,
pub response: String,
pub done: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<Vec<i32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub load_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_eval_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_eval_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eval_count: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eval_duration: Option<u64>,
}
#[derive(Debug, Clone, Serialize)]
pub struct OllamaEmbeddingRequest {
pub model: String,
pub input: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncate: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<HashMap<String, serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_alive: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaEmbeddingResponse {
pub model: String,
pub embeddings: Vec<Vec<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub load_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prompt_eval_count: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaModel {
pub name: String,
pub model: String,
pub modified_at: String,
pub size: u64,
pub digest: String,
pub details: OllamaModelDetails,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaModelDetails {
pub parent_model: String,
pub format: String,
pub family: String,
pub families: Vec<String>,
pub parameter_size: String,
pub quantization_level: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaModelsResponse {
pub models: Vec<OllamaModel>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaRunningModelsResponse {
pub models: Vec<OllamaRunningModel>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaRunningModel {
pub name: String,
pub model: String,
pub size: u64,
pub digest: String,
pub details: OllamaModelDetails,
pub expires_at: String,
pub size_vram: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct OllamaVersionResponse {
pub version: String,
}
#[derive(Debug, Clone, Default)]
pub struct OllamaEmbeddingOptions {
pub truncate: Option<bool>,
pub keep_alive: Option<String>,
pub options: Option<HashMap<String, serde_json::Value>>,
}
impl OllamaEmbeddingOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_truncate(mut self, truncate: bool) -> Self {
self.truncate = Some(truncate);
self
}
pub fn with_keep_alive(mut self, duration: impl Into<String>) -> Self {
self.keep_alive = Some(duration.into());
self
}
pub fn with_options(mut self, options: HashMap<String, serde_json::Value>) -> Self {
self.options = Some(options);
self
}
pub fn with_option(mut self, key: impl Into<String>, value: serde_json::Value) -> Self {
let mut options = self.options.unwrap_or_default();
options.insert(key.into(), value);
self.options = Some(options);
self
}
pub fn apply_to_request(
self,
mut request: crate::types::EmbeddingRequest,
) -> crate::types::EmbeddingRequest {
if let Some(truncate) = self.truncate {
request = request.with_provider_param("truncate", serde_json::Value::Bool(truncate));
}
if let Some(keep_alive) = self.keep_alive {
request =
request.with_provider_param("keep_alive", serde_json::Value::String(keep_alive));
}
if let Some(options) = self.options {
request = request.with_provider_param(
"options",
serde_json::Value::Object(options.into_iter().collect()),
);
}
request
}
}
pub trait OllamaEmbeddingRequestExt {
fn with_ollama_config(self, config: OllamaEmbeddingOptions) -> Self;
fn with_ollama_truncate(self, truncate: bool) -> Self;
fn with_ollama_keep_alive(self, duration: impl Into<String>) -> Self;
fn with_ollama_option(self, key: impl Into<String>, value: serde_json::Value) -> Self;
}
impl OllamaEmbeddingRequestExt for crate::types::EmbeddingRequest {
fn with_ollama_config(self, config: OllamaEmbeddingOptions) -> Self {
config.apply_to_request(self)
}
fn with_ollama_truncate(self, truncate: bool) -> Self {
self.with_provider_param("truncate", serde_json::Value::Bool(truncate))
}
fn with_ollama_keep_alive(self, duration: impl Into<String>) -> Self {
self.with_provider_param("keep_alive", serde_json::Value::String(duration.into()))
}
fn with_ollama_option(self, key: impl Into<String>, value: serde_json::Value) -> Self {
let mut options = self
.provider_params
.get("options")
.and_then(|v| v.as_object())
.cloned()
.unwrap_or_default();
options.insert(key.into(), value);
self.with_provider_param("options", serde_json::Value::Object(options))
}
}