feat: show pricing per 1M tokens in model inspects

This commit is contained in:
katR 2026-09-27 17:57:46 +05:30
parent d8163174fd
commit 7425895931
2 changed files with 91 additions and 4 deletions

View file

@ -249,11 +249,11 @@ async fn autocomplete_model_id<'a>(
#[poise::command(slash_command)] #[poise::command(slash_command)]
async fn model( async fn model(
ctx: Context<'_>, ctx: Context<'_>,
#[description = "Exact model ID from /models or /status"] #[description = "Exact model ID from /free-models or /status"]
#[autocomplete = "autocomplete_model_id"] #[autocomplete = "autocomplete_model_id"]
id: String, id: String,
#[description = "Hide the description (default false)"] compact: Option<bool>, #[description = "Hide the description (default false)"] compact: Option<bool>,
#[description = "Include raw pricing (default true)"] show_pricing: Option<bool>, #[description = "Include pricing per 1M tokens (default true)"] show_pricing: Option<bool>,
#[description = "Show details to everyone (default false)"] public: Option<bool>, #[description = "Show details to everyone (default false)"] public: Option<bool>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let public = public.unwrap_or(false); let public = public.unwrap_or(false);

View file

@ -173,6 +173,56 @@ pub fn snapshot(state: &State, options: &Browse, poll_seconds: u64) -> serenity:
.field("Poll interval", format!("{formatted_poll} seconds · run /status again to refresh this snapshot"), false) .field("Poll interval", format!("{formatted_poll} seconds · run /status again to refresh this snapshot"), false)
} }
fn format_price_usd(val: f64) -> String {
if val == 0.0 {
return "$0.00".into();
}
let formatted = format!("{val:.4}");
let trimmed = formatted.trim_end_matches('0');
let result = if trimmed.ends_with('.') {
format!("{trimmed}00")
} else {
let decimals = trimmed.split('.').nth(1).unwrap_or("").len();
if decimals < 2 {
format!("{trimmed}0")
} else {
trimmed.to_string()
}
};
format!("${result}")
}
pub fn format_price_per_1m(key: &str, raw: &str) -> String {
if let Ok(price) = raw.parse::<f64>() {
if price < 0.0 {
return "Variable / unknown".into();
}
if key == "request" {
if price == 0.0 {
"$0 / request".into()
} else {
format!("${price:.4} / request")
}
} else if key == "image" {
if price == 0.0 {
"$0 / image".into()
} else {
format!("${price:.4} / image")
}
} else {
let per_1m = price * 1_000_000.0;
let formatted = format_price_usd(per_1m);
if per_1m == 0.0 {
format!("{formatted} / 1M tokens (Free)")
} else {
format!("{formatted} / 1M tokens")
}
}
} else {
raw.to_string()
}
}
pub fn model_details(model: &Model, compact: bool, show_pricing: bool) -> serenity::CreateEmbed { pub fn model_details(model: &Model, compact: bool, show_pricing: bool) -> serenity::CreateEmbed {
let mut result = embed(&model.name) let mut result = embed(&model.name)
.field("Model ID", text(&model.id, 1024), false) .field("Model ID", text(&model.id, 1024), false)
@ -206,11 +256,17 @@ pub fn model_details(model: &Model, compact: bool, show_pricing: bool) -> sereni
.pricing .pricing
.iter() .iter()
.take(10) .take(10)
.map(|(key, value)| format!("{}: {}", text(key, 40), text(value, 45))) .map(|(key, value)| {
format!(
"{}: {}",
text(key, 40),
text(&format_price_per_1m(key, value), 45)
)
})
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join("\n");
result = result.field( result = result.field(
"Raw USD prices (prompt/completion per token)", "Pricing (USD per 1M tokens)",
if prices.is_empty() { if prices.is_empty() {
"Unavailable" "Unavailable"
} else { } else {
@ -411,4 +467,35 @@ pub mod tests {
assert_eq!(format_number(1000000), "1,000,000"); assert_eq!(format_number(1000000), "1,000,000");
assert_eq!(format_number(u64::MAX), "18,446,744,073,709,551,615"); assert_eq!(format_number(u64::MAX), "18,446,744,073,709,551,615");
} }
#[test]
fn format_price_per_1m_cases() {
assert_eq!(
format_price_per_1m("prompt", "0"),
"$0.00 / 1M tokens (Free)"
);
assert_eq!(
format_price_per_1m("prompt", "0.00000015"),
"$0.15 / 1M tokens"
);
assert_eq!(
format_price_per_1m("completion", "0.0000015"),
"$1.50 / 1M tokens"
);
assert_eq!(
format_price_per_1m("prompt", "0.000003"),
"$3.00 / 1M tokens"
);
assert_eq!(
format_price_per_1m("prompt", "0.000000075"),
"$0.075 / 1M tokens"
);
assert_eq!(format_price_per_1m("request", "0"), "$0 / request");
assert_eq!(format_price_per_1m("image", "0.001"), "$0.0010 / image");
assert_eq!(format_price_per_1m("prompt", "-1"), "Variable / unknown");
assert_eq!(
format_price_per_1m("overrides", "tiered pricing"),
"tiered pricing"
);
}
} }