diff --git a/backend/crates/gateway-store/src/postgres/observability/queries/dashboard.rs b/backend/crates/gateway-store/src/postgres/observability/queries/dashboard.rs index dbf1f4cad..73a9e455a 100644 --- a/backend/crates/gateway-store/src/postgres/observability/queries/dashboard.rs +++ b/backend/crates/gateway-store/src/postgres/observability/queries/dashboard.rs @@ -448,18 +448,20 @@ pub(crate) async fn provider_observations( range: ObservabilityRange, filter: &UsageRecordFilter, ) -> StoreResult> { - let mut query = QueryBuilder::::new( + let fact = completed_usage_fact_predicate("mr"); + // 请求、attempt 与失败覆盖执行审计;token 只累计完整交付的用量事实。 + let mut query = QueryBuilder::::new(format!( "select coalesce(mr.provider_kind, 'unrouted') as provider_kind, count(*)::bigint as request_count, coalesce(sum(mr.attempt_count), 0)::bigint as attempt_count, count(*) filter (where mr.outcome = 'failed')::bigint as failure_count, - coalesce(sum(mr.total_tokens), 0)::bigint as total_tokens - from model_requests mr where mr.started_at >= ", - ); + coalesce(sum(mr.total_tokens) filter (where {fact}), 0)::bigint + as total_tokens + from model_requests mr where mr.started_at >= " + )); query.push_bind(range.start); query.push(" and mr.started_at < "); query.push_bind(range.end); - push_completed_usage_fact_filter(&mut query, "mr"); push_usage_filter(&mut query, filter, "mr"); query.push(" group by coalesce(mr.provider_kind, 'unrouted') order by request_count desc"); let rows = query diff --git a/backend/crates/gateway-store/tests/postgres/observability.rs b/backend/crates/gateway-store/tests/postgres/observability.rs index ab7e03326..ed2fce54c 100644 --- a/backend/crates/gateway-store/tests/postgres/observability.rs +++ b/backend/crates/gateway-store/tests/postgres/observability.rs @@ -949,6 +949,15 @@ async fn observability_queries_preserve_request_account_cost_and_diagnostic_fact assert_eq!(overview.attempts.failure_count, 2); assert_eq!(overview.requests.request_count, 3); assert_eq!(overview.requests.failure_count, 1); + assert_eq!( + ( + overview.providers[0].request_count, + overview.providers[0].attempt_count, + overview.providers[0].failure_count, + overview.providers[0].total_tokens, + ), + (3, 4, 1, 120), + ); let succeeded = repository .usage_summary(