use serde::{Deserialize, Serialize};
use typed_builder::TypedBuilder;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, TypedBuilder, Default,
)]
#[builder(field_defaults(default))]
pub struct BudgetConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(setter(strip_option))]
pub max_model_calls: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(setter(strip_option))]
pub max_tool_calls: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(setter(strip_option))]
pub max_input_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(setter(strip_option))]
pub max_output_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(setter(strip_option))]
pub max_total_tokens: Option<u64>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_budget_config_builder_and_defaults() {
let budget = BudgetConfig::default();
assert_eq!(budget.max_model_calls, None);
assert_eq!(budget.max_tool_calls, None);
assert_eq!(budget.max_input_tokens, None);
assert_eq!(budget.max_output_tokens, None);
assert_eq!(budget.max_total_tokens, None);
let custom = BudgetConfig::builder()
.max_model_calls(10)
.max_tool_calls(50)
.max_input_tokens(100_000)
.max_output_tokens(20_000)
.max_total_tokens(120_000)
.build();
assert_eq!(custom.max_model_calls, Some(10));
assert_eq!(custom.max_tool_calls, Some(50));
assert_eq!(custom.max_input_tokens, Some(100_000));
assert_eq!(custom.max_output_tokens, Some(20_000));
assert_eq!(custom.max_total_tokens, Some(120_000));
}
#[test]
fn test_budget_config_serde_roundtrip() {
let custom = BudgetConfig::builder()
.max_model_calls(5)
.max_total_tokens(50_000)
.build();
let json = serde_json::to_string(&custom).expect("serialize");
let parsed: BudgetConfig = serde_json::from_str(&json).expect("deserialize");
assert_eq!(custom, parsed);
}
}