fix(observability): correct provider failure semantics

Count provider request, attempt, and failure facts across the full execution audit while restricting token totals to completed usage facts. Add a PostgreSQL regression assertion for the mixed success/failure boundary.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Zyy
2026-08-31 02:34:21 +08:00
co-authored by Codex
parent a268f5ca66
commit f10f825404
2 changed files with 16 additions and 5 deletions
@@ -448,18 +448,20 @@ pub(crate) async fn provider_observations(
range: ObservabilityRange,
filter: &UsageRecordFilter,
) -> StoreResult<Vec<ProviderObservation>> {
let mut query = QueryBuilder::<Postgres>::new(
let fact = completed_usage_fact_predicate("mr");
// 请求、attempt 与失败覆盖执行审计;token 只累计完整交付的用量事实。
let mut query = QueryBuilder::<Postgres>::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
@@ -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(