use super::Figure;
pub fn render(ui: &mut egui::Ui, figure: &Figure) {
ui.horizontal(|ui| {
let spend = figure.tokens;
ui.label(format!("budget {} tok", spend.total_tokens()));
ui.weak(format!(
"(in {} · out {} · cache r {} · w {})",
spend.input_tokens,
spend.output_tokens,
spend.cache_read_tokens,
spend.cache_write_tokens
));
if let Some(cost) = figure.cost {
ui.label(cost.usd());
if cost.unpriced_tokens > 0 {
ui.weak(format!("+{} tok unpriced", cost.unpriced_tokens))
.on_hover_text(
"These tokens ran on a model the price table has no rate for \
(ui.json `prices`), so the figure beside them is a floor.",
);
}
}
if let Some(note) = figure.attribution.note() {
ui.weak(note.label).on_hover_text(note.hover);
}
});
}
#[cfg(test)]
mod tests {
use super::*;
use crate::budgets::BudgetSpend;
use crate::spend::{Attribution, Cost};
fn painted(figure: &Figure) -> String {
crate::paint_probe::paint(|ui| render(ui, figure))
}
fn tokens() -> BudgetSpend {
BudgetSpend {
input_tokens: 10,
output_tokens: 5,
cache_read_tokens: 2,
cache_write_tokens: 1,
}
}
#[test]
fn renders_total_and_counters_unpriced() {
let text = painted(&Figure {
tokens: tokens(),
cost: None,
attribution: Attribution::Conversations(1),
});
assert!(text.contains("budget 18 tok"), "got:\n{text}");
assert!(
text.contains("in 10 · out 5 · cache r 2 · w 1"),
"got:\n{text}"
);
assert!(!text.contains('$'), "got:\n{text}");
}
#[test]
fn a_workspace_wide_sum_says_so_with_no_price_table() {
let text = painted(&Figure {
tokens: tokens(),
cost: None,
attribution: Attribution::Workspace,
});
assert!(!text.contains('$'), "still no cost column: {text}");
assert!(
text.contains("workspace-wide"),
"the honesty clause does not ride on pricing: {text}"
);
}
#[test]
fn a_multi_conversation_sum_says_so_with_no_price_table() {
let text = painted(&Figure {
tokens: tokens(),
cost: None,
attribution: Attribution::Conversations(3),
});
assert!(text.contains("over 3 conversations"), "got:\n{text}");
}
#[test]
fn renders_zero_spend() {
assert!(
painted(&Figure {
tokens: BudgetSpend::default(),
cost: None,
attribution: Attribution::Conversations(1),
})
.contains("budget 0 tok")
);
}
#[test]
fn renders_cost_with_unpriced_remainder_and_attribution() {
let text = painted(&Figure {
tokens: tokens(),
cost: Some(Cost {
micro_usd: 1_234_500,
unpriced_tokens: 9,
}),
attribution: Attribution::Workspace,
});
assert!(text.contains("$1.23"), "got:\n{text}");
assert!(text.contains("+9 tok unpriced"), "got:\n{text}");
assert!(text.contains("workspace-wide"), "got:\n{text}");
}
#[test]
fn fully_priced_single_conversation_renders_cost_alone() {
let text = painted(&Figure {
tokens: tokens(),
cost: Some(Cost {
micro_usd: 0,
unpriced_tokens: 0,
}),
attribution: Attribution::Conversations(1),
});
assert!(text.contains("$0.00"), "got:\n{text}");
assert!(!text.contains("unpriced"), "got:\n{text}");
assert!(!text.contains("conversations"), "got:\n{text}");
}
}