mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(provider): demote usage_limit_reached on OpenAI Responses (#4185)
Co-authored-by: M3gA-Mind <elvin@mahadao.com>
This commit is contained in:
@@ -6196,6 +6196,25 @@ mod tests {
|
||||
assert!(is_quota_exhausted_message(body));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quota_exhausted_filter_matches_responses_usage_limit_reached_event() {
|
||||
// TAURI-RUST-AFE: verbatim message as formatted by the `chat_via_responses`
|
||||
// emit site — the Codex/ChatGPT OAuth `/responses` plan cap. Mirrors the
|
||||
// real production shape `"<name> Responses API error (<status>): <body>"`
|
||||
// (`compatible_helpers.rs:135`), including the `(429)` status segment and
|
||||
// the full AFE payload (`plan_type` + `resets_at`) from `ops/http_error.rs`,
|
||||
// so this stays coupled to the actual wire format rather than a loose
|
||||
// substring. No "monthly"/"quota" co-marker, so it exercises the AFE
|
||||
// phrase extension reaching the before_send net on both message and
|
||||
// exception paths (the subconscious loop retries until `resets_at`).
|
||||
let body = "openai Responses API error (429): {\"error\":{\"type\":\
|
||||
\"usage_limit_reached\",\"message\":\"The usage limit has been reached\",\
|
||||
\"plan_type\":\"plus\",\"resets_at\":1750000000}}";
|
||||
assert!(is_quota_exhausted_event(&event_with_message(body)));
|
||||
assert!(is_quota_exhausted_event(&event_with_exception_value(body)));
|
||||
assert!(is_quota_exhausted_message(body));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quota_exhausted_filter_ignores_generic_500_and_rate_limit() {
|
||||
// A generic 500 outage and a 429 rate-limit are not plan-quota
|
||||
|
||||
@@ -222,6 +222,20 @@ impl OpenAiCompatibleProvider {
|
||||
Some(model),
|
||||
status,
|
||||
);
|
||||
} else if super::super::is_provider_quota_exhausted(&error) {
|
||||
// Codex/ChatGPT OAuth `/responses` plan cap hit
|
||||
// (`usage_limit_reached` / "The usage limit has been reached"): a
|
||||
// third-party plan limit with no local lever. The subconscious loop
|
||||
// retries until `resets_at`, so a single capped Plus user emits
|
||||
// hundreds of identical events — demote to info instead of paging on
|
||||
// every retry (TAURI-RUST-AFE, extends the #4076/C9A quota machinery
|
||||
// to the Responses path).
|
||||
super::super::log_provider_quota_exhausted(
|
||||
"responses_api",
|
||||
self.name.as_str(),
|
||||
Some(model),
|
||||
status,
|
||||
);
|
||||
} else if super::super::should_report_provider_http_failure(status) {
|
||||
crate::core::observability::report_error(
|
||||
message.as_str(),
|
||||
|
||||
@@ -255,6 +255,13 @@ pub fn body_indicates_quota_exhausted(body: &str) -> bool {
|
||||
|| lower.contains("monthly quota")
|
||||
|| lower.contains("quota exceeded")
|
||||
|| lower.contains("usage limit exceeded")
|
||||
// Codex/ChatGPT OAuth `/responses` plan-cap body (TAURI-RUST-AFE):
|
||||
// `usage_limit_reached` / "The usage limit has been reached" — a plan
|
||||
// quota with no "monthly"/"quota" co-marker, so the phrases above miss
|
||||
// it. Both are quota-specific enough to match on their own (the loop
|
||||
// retries until `resets_at`, flooding from a single capped Plus user).
|
||||
|| lower.contains("usage_limit_reached")
|
||||
|| lower.contains("usage limit has been reached")
|
||||
// "reached the limit" alone is ambiguous (rate-limit, token-limit), so
|
||||
// require a quota/plan/request/monthly co-marker to keep the blast
|
||||
// radius on plan-quota exhaustion only.
|
||||
@@ -1051,6 +1058,15 @@ mod tests {
|
||||
reached the limit.\\\",\\\"reason\\\":\\\"MONTHLY_REQUEST_COUNT\\\"}\",\
|
||||
\"type\":\"server_error\"}}";
|
||||
|
||||
/// Verbatim TAURI-RUST-AFE Responses-API body — the Codex/ChatGPT OAuth
|
||||
/// `/responses` endpoint refuses with `usage_limit_reached` once the Plus
|
||||
/// plan cap is hit. It carries no "monthly"/"quota" co-marker, so the C9A
|
||||
/// phrase set missed it; couple the test to the exact string so a wording
|
||||
/// drift fails CI rather than silently leaking events back to Sentry.
|
||||
const AFE_BODY: &str = "openai Responses API error: {\"error\":{\"type\":\
|
||||
\"usage_limit_reached\",\"message\":\"The usage limit has been reached\",\
|
||||
\"plan_type\":\"plus\",\"resets_at\":1750000000}}";
|
||||
|
||||
#[test]
|
||||
fn quota_exhausted_matches_verbatim_c9a_body() {
|
||||
// Status-agnostic: the verbatim 500-wrapped body must match even though
|
||||
@@ -1059,6 +1075,20 @@ mod tests {
|
||||
assert!(body_indicates_quota_exhausted(C9A_BODY));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quota_exhausted_matches_verbatim_afe_body() {
|
||||
// Coverage gap closed (TAURI-RUST-AFE): the Responses `usage_limit_reached`
|
||||
// body must demote through the same #4076 quota machinery even though it
|
||||
// lacks a "monthly"/"quota" co-marker.
|
||||
assert!(is_provider_quota_exhausted(AFE_BODY));
|
||||
assert!(body_indicates_quota_exhausted(AFE_BODY));
|
||||
// Bare phrasings (no surrounding envelope) must also match.
|
||||
assert!(body_indicates_quota_exhausted("usage_limit_reached"));
|
||||
assert!(body_indicates_quota_exhausted(
|
||||
"The usage limit has been reached"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quota_exhausted_matches_common_phrasings() {
|
||||
for body in [
|
||||
|
||||
Reference in New Issue
Block a user