Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::models::ModelInfo;
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;

Expand All @@ -9,6 +11,10 @@ pub struct Config {
pub server: ServerConfig,
pub upload: UploadConfig,
pub formatting: FormattingConfig,
#[serde(default)]
pub models: HashMap<String, ModelInfo>,
#[serde(default)]
pub aliases: HashMap<String, String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -52,6 +58,8 @@ impl Default for Config {
locale: "en".to_string(),
decimal_places: 2,
},
models: HashMap::new(),
aliases: HashMap::new(),
}
}
}
Expand Down Expand Up @@ -171,6 +179,12 @@ pub fn show_config() -> Result<()> {
println!(" Number Human: {}", config.formatting.number_human);
println!(" Locale: {}", config.formatting.locale);
println!(" Decimal Places: {}", config.formatting.decimal_places);
if !config.models.is_empty() {
println!(" Custom Models: {}", config.models.len());
}
if !config.aliases.is_empty() {
println!(" Custom Aliases: {}", config.aliases.len());
}
}
None => {
println!("❌ No configuration file found.");
Expand Down Expand Up @@ -235,6 +249,54 @@ mod tests {
(dir, config_path)
}

#[test]
fn test_config_with_custom_models() {
let toml_str = r#"
[server]
url = "https://custom.example.com"
api_token = "test-token"

[upload]
auto_upload = true
upload_today_only = false
retry_attempts = 5
last_date_uploaded = 0

[formatting]
number_comma = true
number_human = false
locale = "zh"
decimal_places = 4

[models."custom-model"]
pricing = { Flat = { input_per_1m = 10.0, output_per_1m = 20.0 } }
caching = "None"
is_estimated = true

[aliases]
"my-alias" = "custom-model"
"#;

let config: Config = toml::from_str(toml_str).unwrap();

assert_eq!(config.server.url, "https://custom.example.com");
assert!(config.models.contains_key("custom-model"));

let custom_model = config.models.get("custom-model").unwrap();
match &custom_model.pricing {
PricingStructure::Flat {
input_per_1m,
output_per_1m,
} => {
assert_eq!(*input_per_1m, 10.0);
assert_eq!(*output_per_1m, 20.0);
}
_ => panic!("Expected flat pricing"),
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

assert_eq!(config.aliases.get("my-alias").unwrap(), "custom-model");
}

#[test]
fn default_config_round_trip() {
let (_dir, _path) = setup_test_config();
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ async fn main() {
// Load config file to get defaults
let config = config::Config::load().unwrap_or(None).unwrap_or_default();

// Initialize external models from config
models::init_external_models(config.models.clone(), config.aliases.clone());

// Create format options merging config defaults with CLI overrides
let format_options = utils::NumberFormatOptions {
use_comma: cli.number_comma || config.formatting.number_comma,
Expand Down
Loading