mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
fix(usage): 统一使用记录与仪表盘的缓存命中率计算口径
- 新增归一化总输入上下文计算逻辑,按 provider 区分 OpenAI/Gemini 与 Claude 的 cache token 语义 - 将管理端使用聚合、用户使用记录、仪表盘缓存统计、缓存亲和性分析统一为 token 级缓存命中率 - 修正 total_input_context 字段,避免 cache_read 在部分 provider 上被重复计入分母 - 同步更新相关 Rust 单元测试与网关集成测试断言 - 调整前端 dashboard mock 中 cache_hit_rate 的单位为百分比
This commit is contained in:
@@ -27,4 +27,6 @@ pub use schema::{
|
||||
BillingSnapshot, BillingSnapshotStatus, CostResult, BILLING_SNAPSHOT_SCHEMA_VERSION,
|
||||
};
|
||||
pub use service::BillingService;
|
||||
pub use token_normalization::normalize_input_tokens_for_billing;
|
||||
pub use token_normalization::{
|
||||
normalize_input_tokens_for_billing, normalize_total_input_context_for_cache_hit_rate,
|
||||
};
|
||||
|
||||
@@ -43,9 +43,42 @@ pub fn normalize_input_tokens_for_billing(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn normalize_total_input_context_for_cache_hit_rate(
|
||||
api_format: Option<&str>,
|
||||
input_tokens: i64,
|
||||
cache_creation_tokens: i64,
|
||||
cache_read_tokens: i64,
|
||||
) -> i64 {
|
||||
let normalized_input_tokens = input_tokens.max(0);
|
||||
let normalized_cache_creation_tokens = cache_creation_tokens.max(0);
|
||||
let normalized_cache_read_tokens = cache_read_tokens.max(0);
|
||||
|
||||
let fresh_input_tokens = match parse_api_family(api_format) {
|
||||
ApiFamily::Claude => {
|
||||
normalized_input_tokens.saturating_add(normalized_cache_creation_tokens)
|
||||
}
|
||||
ApiFamily::OpenAi | ApiFamily::Gemini => normalize_input_tokens_for_billing(
|
||||
api_format,
|
||||
normalized_input_tokens,
|
||||
normalized_cache_read_tokens,
|
||||
),
|
||||
ApiFamily::Unknown => {
|
||||
if normalized_cache_creation_tokens > 0 {
|
||||
normalized_input_tokens.saturating_add(normalized_cache_creation_tokens)
|
||||
} else {
|
||||
normalized_input_tokens
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fresh_input_tokens.saturating_add(normalized_cache_read_tokens)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::normalize_input_tokens_for_billing;
|
||||
use super::{
|
||||
normalize_input_tokens_for_billing, normalize_total_input_context_for_cache_hit_rate,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn subtracts_cache_tokens_for_openai_and_gemini() {
|
||||
@@ -66,4 +99,36 @@ mod tests {
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalizes_cache_hit_context_for_openai_and_gemini() {
|
||||
assert_eq!(
|
||||
normalize_total_input_context_for_cache_hit_rate(Some("openai:chat"), 120, 10, 15),
|
||||
120
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_total_input_context_for_cache_hit_rate(Some("gemini:chat"), 120, 10, 15),
|
||||
120
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn includes_cache_creation_for_claude_cache_hit_context() {
|
||||
assert_eq!(
|
||||
normalize_total_input_context_for_cache_hit_rate(Some("claude:chat"), 60, 15, 5),
|
||||
80
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn falls_back_to_creation_aware_context_for_unknown_formats() {
|
||||
assert_eq!(
|
||||
normalize_total_input_context_for_cache_hit_rate(None, 20, 10, 5),
|
||||
35
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_total_input_context_for_cache_hit_rate(None, 20, 0, 5),
|
||||
25
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user