//! Model parameter profile management — CRUD. use db::database::AppDatabase; use models::agents::model_parameter_profile; use sea_orm::*; use uuid::Uuid; use crate::error::AgentError; #[derive(Debug, Clone, serde::Deserialize, utoipa::ToSchema)] pub struct CreateModelParameterProfileRequest { pub model_version_id: Uuid, pub temperature_min: f64, pub temperature_max: f64, pub top_p_min: f64, pub top_p_max: f64, #[serde(default)] pub frequency_penalty_supported: bool, #[serde(default)] pub presence_penalty_supported: bool, } #[derive(Debug, Clone, serde::Deserialize, utoipa::ToSchema)] pub struct UpdateModelParameterProfileRequest { pub temperature_min: Option, pub temperature_max: Option, pub top_p_min: Option, pub top_p_max: Option, pub frequency_penalty_supported: Option, pub presence_penalty_supported: Option, } #[derive(Debug, Clone, serde::Serialize, utoipa::ToSchema)] pub struct ModelParameterProfileResponse { pub id: i64, pub model_version_id: Uuid, pub temperature_min: f64, pub temperature_max: f64, pub top_p_min: f64, pub top_p_max: f64, pub frequency_penalty_supported: bool, pub presence_penalty_supported: bool, } impl From for ModelParameterProfileResponse { fn from(p: model_parameter_profile::Model) -> Self { Self { id: p.id, model_version_id: p.model_version_id, temperature_min: p.temperature_min, temperature_max: p.temperature_max, top_p_min: p.top_p_min, top_p_max: p.top_p_max, frequency_penalty_supported: p.frequency_penalty_supported, presence_penalty_supported: p.presence_penalty_supported, } } } pub async fn list_parameter_profiles( db: &AppDatabase, model_version_id: Uuid, ) -> Result, AgentError> { let profiles = model_parameter_profile::Entity::find() .filter(model_parameter_profile::Column::ModelVersionId.eq(model_version_id)) .all(db) .await?; Ok(profiles .into_iter() .map(ModelParameterProfileResponse::from) .collect()) } pub async fn get_parameter_profile( db: &AppDatabase, id: i64, ) -> Result { let profile = model_parameter_profile::Entity::find_by_id(id) .one(db) .await? .ok_or_else(|| AgentError::NotFound(format!("Parameter profile not found: {}", id)))?; Ok(ModelParameterProfileResponse::from(profile)) } pub async fn create_parameter_profile( db: &AppDatabase, request: CreateModelParameterProfileRequest, ) -> Result { let active = model_parameter_profile::ActiveModel { model_version_id: Set(request.model_version_id), temperature_min: Set(request.temperature_min), temperature_max: Set(request.temperature_max), top_p_min: Set(request.top_p_min), top_p_max: Set(request.top_p_max), frequency_penalty_supported: Set(request.frequency_penalty_supported), presence_penalty_supported: Set(request.presence_penalty_supported), ..Default::default() }; let profile = active.insert(db).await?; Ok(ModelParameterProfileResponse::from(profile)) } pub async fn update_parameter_profile( db: &AppDatabase, id: i64, request: UpdateModelParameterProfileRequest, ) -> Result { let profile = model_parameter_profile::Entity::find_by_id(id) .one(db) .await? .ok_or_else(|| AgentError::NotFound(format!("Parameter profile not found: {}", id)))?; let mut active: model_parameter_profile::ActiveModel = profile.into(); if let Some(v) = request.temperature_min { active.temperature_min = Set(v); } if let Some(v) = request.temperature_max { active.temperature_max = Set(v); } if let Some(v) = request.top_p_min { active.top_p_min = Set(v); } if let Some(v) = request.top_p_max { active.top_p_max = Set(v); } if let Some(v) = request.frequency_penalty_supported { active.frequency_penalty_supported = Set(v); } if let Some(v) = request.presence_penalty_supported { active.presence_penalty_supported = Set(v); } let profile = active.update(db).await?; Ok(ModelParameterProfileResponse::from(profile)) } pub async fn delete_parameter_profile(db: &AppDatabase, id: i64) -> Result<(), AgentError> { model_parameter_profile::Entity::delete_by_id(id) .exec(db) .await?; Ok(()) }