use thiserror::Error;
#[derive(Debug, Clone, PartialEq)]
pub struct Temperature(f32);
impl Temperature {
pub fn as_f32(&self) -> f32 {
self.0
}
}
#[derive(Debug, Error)]
#[error("Expected a value between 0.0 and 2.0, received {0}")]
pub struct InvalidTemperatureValueError(f32);
impl TryFrom<f32> for Temperature {
type Error = InvalidTemperatureValueError;
fn try_from(value: f32) -> Result<Self, Self::Error> {
if !(0.0..=2.0).contains(&value) {
return Err(InvalidTemperatureValueError(value));
}
Ok(Temperature(value))
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct TopP(f32);
impl TopP {
pub fn as_f32(&self) -> f32 {
self.0
}
}
#[derive(Debug, Error)]
#[error("Expected a value between 0.0 and 1.0, received {0}")]
pub struct InvalidTopPValueError(f32);
impl TryFrom<f32> for TopP {
type Error = InvalidTopPValueError;
fn try_from(value: f32) -> Result<Self, Self::Error> {
if !(0.0..=1.0).contains(&value) {
return Err(InvalidTopPValueError(value));
}
Ok(TopP(value))
}
}
#[derive(Debug, Clone, Default)]
pub struct Settings {
pub temperature: Option<Temperature>,
pub top_p: Option<TopP>,
pub top_k: Option<u32>,
pub max_output_tokens: Option<u32>,
pub presence_penalty: Option<f32>,
pub stop_sequences: Option<Vec<String>>,
pub seed: Option<i32>,
}
impl Settings {
pub fn new() -> Self {
Settings::default()
}
pub fn merge(self, other: Settings) -> Self {
Settings {
temperature: other.temperature.or(self.temperature),
top_p: other.top_p.or(self.top_p),
top_k: other.top_k.or(self.top_k),
seed: other.seed.or(self.seed),
stop_sequences: other.stop_sequences.or(self.stop_sequences),
presence_penalty: other.presence_penalty.or(self.presence_penalty),
max_output_tokens: other.max_output_tokens.or(self.max_output_tokens),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merge_should_prioritize_other() {
let settings_1 = Settings::default();
let settings_2 = Settings {
temperature: Some(Temperature::try_from(0.7).unwrap()),
..Default::default()
};
let merged_settings = settings_1.merge(settings_2);
assert_eq!(
merged_settings.temperature,
Some(Temperature::try_from(0.7).unwrap())
);
}
#[test]
fn test_merge_should_keep_original_when_other_is_none() {
let settings_1 = Settings {
temperature: Some(Temperature::try_from(0.7).unwrap()),
..Default::default()
};
let settings_2 = Settings::default();
let merged_settings = settings_1.merge(settings_2);
assert_eq!(
merged_settings.temperature,
Some(Temperature::try_from(0.7).unwrap())
);
}
}