mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
fix(dashboard): 修复仪表盘与明细统计数值不一致并重建 cost_savings 聚合
- 统一 dashboard 聚合与 raw 查询的 token 计算,拆分今日节省和周期节省 - cache savings 改用 input price 估算未命中成本,修复历史 cost_savings 偏高 - raw 查询 total_tokens 改用 effective_input + output + cache_creation + cache_read 公式 - 新增独立 backfill 重建历史 cost_savings 聚合表,保留已发布 backfill 不变
This commit is contained in:
@@ -549,6 +549,7 @@ mod tests {
|
||||
cache_read_cost_usd,
|
||||
total_cost_usd,
|
||||
actual_total_cost_usd,
|
||||
input_price_per_1m,
|
||||
output_price_per_1m,
|
||||
status,
|
||||
billing_status,
|
||||
@@ -576,6 +577,7 @@ mod tests {
|
||||
1.25,
|
||||
1.10,
|
||||
50.0,
|
||||
50.0,
|
||||
'completed',
|
||||
'settled',
|
||||
TIMESTAMPTZ '2024-05-06 07:18:09+00',
|
||||
@@ -595,9 +597,10 @@ mod tests {
|
||||
let pending_before = pending_backfills(&pool)
|
||||
.await
|
||||
.expect("pending backfills should load");
|
||||
assert_eq!(pending_before.len(), 2);
|
||||
assert_eq!(pending_before.len(), 3);
|
||||
assert_eq!(pending_before[0].version, 20260422110000);
|
||||
assert_eq!(pending_before[1].version, 20260422120000);
|
||||
assert_eq!(pending_before[2].version, 20260504120000);
|
||||
|
||||
run_backfills(&pool)
|
||||
.await
|
||||
@@ -613,7 +616,10 @@ mod tests {
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.expect("applied backfill versions should load");
|
||||
assert_eq!(applied_versions, vec![20260422110000, 20260422120000]);
|
||||
assert_eq!(
|
||||
applied_versions,
|
||||
vec![20260422110000, 20260422120000, 20260504120000]
|
||||
);
|
||||
|
||||
let api_key_total_requests: i64 = query_scalar(
|
||||
"SELECT COALESCE(total_requests, 0)::BIGINT FROM public.api_keys WHERE id = 'api-key-backfill-1'",
|
||||
@@ -1265,6 +1271,6 @@ mod tests {
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.expect("backfill count should load");
|
||||
assert_eq!(applied_count, 1);
|
||||
assert_eq!(applied_count, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1915,7 +1915,7 @@ impl UsageReadRepository for InMemoryUsageReadRepository {
|
||||
.saturating_add(item.cache_read_input_tokens);
|
||||
summary.cache_read_cost_usd += item.cache_read_cost_usd;
|
||||
summary.cache_creation_cost_usd += item.cache_creation_cost_usd;
|
||||
summary.estimated_full_cost_usd += item.settlement_output_price_per_1m().unwrap_or(0.0)
|
||||
summary.estimated_full_cost_usd += item.settlement_input_price_per_1m().unwrap_or(0.0)
|
||||
* item.cache_read_input_tokens as f64
|
||||
/ 1_000_000.0;
|
||||
}
|
||||
|
||||
@@ -1394,7 +1394,7 @@ SELECT
|
||||
COALESCE(SUM(input_tokens), 0)::BIGINT AS input_tokens,
|
||||
COALESCE(SUM(effective_input_tokens), 0)::BIGINT AS effective_input_tokens,
|
||||
COALESCE(SUM(output_tokens), 0)::BIGINT AS output_tokens,
|
||||
COALESCE(SUM(input_tokens + output_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(effective_input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(cache_creation_tokens), 0)::BIGINT AS cache_creation_tokens,
|
||||
COALESCE(SUM(cache_read_tokens), 0)::BIGINT AS cache_read_tokens,
|
||||
COALESCE(SUM(total_input_context), 0)::BIGINT AS total_input_context,
|
||||
@@ -1425,7 +1425,7 @@ SELECT
|
||||
COALESCE(SUM(input_tokens), 0)::BIGINT AS input_tokens,
|
||||
COALESCE(SUM(effective_input_tokens), 0)::BIGINT AS effective_input_tokens,
|
||||
COALESCE(SUM(output_tokens), 0)::BIGINT AS output_tokens,
|
||||
COALESCE(SUM(input_tokens + output_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(effective_input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(cache_creation_tokens), 0)::BIGINT AS cache_creation_tokens,
|
||||
COALESCE(SUM(cache_read_tokens), 0)::BIGINT AS cache_read_tokens,
|
||||
COALESCE(SUM(total_input_context), 0)::BIGINT AS total_input_context,
|
||||
@@ -1482,7 +1482,33 @@ SELECT
|
||||
END
|
||||
), 0)::BIGINT AS effective_input_tokens,
|
||||
COALESCE(SUM(GREATEST(COALESCE("usage".output_tokens, 0), 0)), 0)::BIGINT AS output_tokens,
|
||||
COALESCE(SUM(GREATEST(COALESCE("usage".total_tokens, 0), 0)), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(
|
||||
CASE
|
||||
WHEN GREATEST(COALESCE("usage".input_tokens, 0), 0) <= 0 THEN 0
|
||||
WHEN GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0) <= 0
|
||||
THEN GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
WHEN split_part(lower(COALESCE(COALESCE("usage".endpoint_api_format, "usage".api_format), '')), ':', 1)
|
||||
IN ('openai', 'gemini', 'google')
|
||||
THEN GREATEST(
|
||||
GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
- GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0),
|
||||
0
|
||||
)
|
||||
ELSE GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
END
|
||||
+ GREATEST(COALESCE("usage".output_tokens, 0), 0)
|
||||
+ CASE
|
||||
WHEN COALESCE("usage".cache_creation_input_tokens, 0) = 0
|
||||
AND (
|
||||
COALESCE("usage".cache_creation_input_tokens_5m, 0)
|
||||
+ COALESCE("usage".cache_creation_input_tokens_1h, 0)
|
||||
) > 0
|
||||
THEN COALESCE("usage".cache_creation_input_tokens_5m, 0)
|
||||
+ COALESCE("usage".cache_creation_input_tokens_1h, 0)
|
||||
ELSE COALESCE("usage".cache_creation_input_tokens, 0)
|
||||
END
|
||||
+ GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0)
|
||||
), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(
|
||||
CASE
|
||||
WHEN COALESCE("usage".cache_creation_input_tokens, 0) = 0
|
||||
@@ -3740,7 +3766,33 @@ SELECT
|
||||
"usage".model AS model,
|
||||
"usage".provider_name AS provider,
|
||||
COUNT(*)::BIGINT AS requests,
|
||||
COALESCE(SUM(GREATEST(COALESCE("usage".total_tokens, 0), 0)), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(
|
||||
CASE
|
||||
WHEN GREATEST(COALESCE("usage".input_tokens, 0), 0) <= 0 THEN 0
|
||||
WHEN GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0) <= 0
|
||||
THEN GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
WHEN split_part(lower(COALESCE(COALESCE("usage".endpoint_api_format, "usage".api_format), '')), ':', 1)
|
||||
IN ('openai', 'gemini', 'google')
|
||||
THEN GREATEST(
|
||||
GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
- GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0),
|
||||
0
|
||||
)
|
||||
ELSE GREATEST(COALESCE("usage".input_tokens, 0), 0)
|
||||
END
|
||||
+ GREATEST(COALESCE("usage".output_tokens, 0), 0)
|
||||
+ CASE
|
||||
WHEN COALESCE("usage".cache_creation_input_tokens, 0) = 0
|
||||
AND (
|
||||
COALESCE("usage".cache_creation_input_tokens_5m, 0)
|
||||
+ COALESCE("usage".cache_creation_input_tokens_1h, 0)
|
||||
) > 0
|
||||
THEN COALESCE("usage".cache_creation_input_tokens_5m, 0)
|
||||
+ COALESCE("usage".cache_creation_input_tokens_1h, 0)
|
||||
ELSE COALESCE("usage".cache_creation_input_tokens, 0)
|
||||
END
|
||||
+ GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0)
|
||||
), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(COALESCE(CAST("usage".total_cost_usd AS DOUBLE PRECISION), 0)), 0)
|
||||
AS total_cost_usd,
|
||||
COALESCE(SUM(
|
||||
@@ -3944,7 +3996,7 @@ SELECT
|
||||
{group_column} AS group_key,
|
||||
COALESCE(SUM(total_requests), 0)::BIGINT AS request_count,
|
||||
COALESCE(SUM(input_tokens), 0)::BIGINT AS input_tokens,
|
||||
COALESCE(SUM(total_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(effective_input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0)::BIGINT AS total_tokens,
|
||||
COALESCE(SUM(output_tokens), 0)::BIGINT AS output_tokens,
|
||||
COALESCE(SUM(effective_input_tokens), 0)::BIGINT AS effective_input_tokens,
|
||||
COALESCE(SUM(total_input_context), 0)::BIGINT AS total_input_context,
|
||||
@@ -4951,7 +5003,7 @@ SELECT
|
||||
AS cache_creation_cost_usd,
|
||||
COALESCE(SUM(
|
||||
COALESCE(
|
||||
CAST("usage".output_price_per_1m AS DOUBLE PRECISION),
|
||||
CAST("usage".input_price_per_1m AS DOUBLE PRECISION),
|
||||
0
|
||||
) * GREATEST(COALESCE("usage".cache_read_input_tokens, 0), 0)::DOUBLE PRECISION / 1000000.0
|
||||
), 0) AS estimated_full_cost_usd
|
||||
|
||||
Reference in New Issue
Block a user