Change headers and struct of rate limits (#4060)
This commit is contained in:
@@ -487,18 +487,18 @@ fn attach_item_ids(payload_json: &mut Value, original_items: &[ResponseItem]) {
|
|||||||
|
|
||||||
fn parse_rate_limit_snapshot(headers: &HeaderMap) -> Option<RateLimitSnapshotEvent> {
|
fn parse_rate_limit_snapshot(headers: &HeaderMap) -> Option<RateLimitSnapshotEvent> {
|
||||||
let primary_used_percent = parse_header_f64(headers, "x-codex-primary-used-percent")?;
|
let primary_used_percent = parse_header_f64(headers, "x-codex-primary-used-percent")?;
|
||||||
let weekly_used_percent = parse_header_f64(headers, "x-codex-protection-used-percent")?;
|
let secondary_used_percent = parse_header_f64(headers, "x-codex-secondary-used-percent")?;
|
||||||
let primary_to_weekly_ratio_percent =
|
let primary_to_secondary_ratio_percent =
|
||||||
parse_header_f64(headers, "x-codex-primary-over-protection-limit-percent")?;
|
parse_header_f64(headers, "x-codex-primary-over-secondary-limit-percent")?;
|
||||||
let primary_window_minutes = parse_header_u64(headers, "x-codex-primary-window-minutes")?;
|
let primary_window_minutes = parse_header_u64(headers, "x-codex-primary-window-minutes")?;
|
||||||
let weekly_window_minutes = parse_header_u64(headers, "x-codex-protection-window-minutes")?;
|
let secondary_window_minutes = parse_header_u64(headers, "x-codex-secondary-window-minutes")?;
|
||||||
|
|
||||||
Some(RateLimitSnapshotEvent {
|
Some(RateLimitSnapshotEvent {
|
||||||
primary_used_percent,
|
primary_used_percent,
|
||||||
weekly_used_percent,
|
secondary_used_percent,
|
||||||
primary_to_weekly_ratio_percent,
|
primary_to_secondary_ratio_percent,
|
||||||
primary_window_minutes,
|
primary_window_minutes,
|
||||||
weekly_window_minutes,
|
secondary_window_minutes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -761,10 +761,10 @@ async fn token_count_includes_rate_limits_snapshot() {
|
|||||||
let response = ResponseTemplate::new(200)
|
let response = ResponseTemplate::new(200)
|
||||||
.insert_header("content-type", "text/event-stream")
|
.insert_header("content-type", "text/event-stream")
|
||||||
.insert_header("x-codex-primary-used-percent", "12.5")
|
.insert_header("x-codex-primary-used-percent", "12.5")
|
||||||
.insert_header("x-codex-protection-used-percent", "40.0")
|
.insert_header("x-codex-secondary-used-percent", "40.0")
|
||||||
.insert_header("x-codex-primary-over-protection-limit-percent", "75.0")
|
.insert_header("x-codex-primary-over-secondary-limit-percent", "75.0")
|
||||||
.insert_header("x-codex-primary-window-minutes", "10")
|
.insert_header("x-codex-primary-window-minutes", "10")
|
||||||
.insert_header("x-codex-protection-window-minutes", "60")
|
.insert_header("x-codex-secondary-window-minutes", "60")
|
||||||
.set_body_raw(sse_body, "text/event-stream");
|
.set_body_raw(sse_body, "text/event-stream");
|
||||||
|
|
||||||
Mock::given(method("POST"))
|
Mock::given(method("POST"))
|
||||||
@@ -827,10 +827,10 @@ async fn token_count_includes_rate_limits_snapshot() {
|
|||||||
},
|
},
|
||||||
"rate_limits": {
|
"rate_limits": {
|
||||||
"primary_used_percent": 12.5,
|
"primary_used_percent": 12.5,
|
||||||
"weekly_used_percent": 40.0,
|
"secondary_used_percent": 40.0,
|
||||||
"primary_to_weekly_ratio_percent": 75.0,
|
"primary_to_secondary_ratio_percent": 75.0,
|
||||||
"primary_window_minutes": 10,
|
"primary_window_minutes": 10,
|
||||||
"weekly_window_minutes": 60
|
"secondary_window_minutes": 60
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -596,14 +596,14 @@ pub struct TokenCountEvent {
|
|||||||
pub struct RateLimitSnapshotEvent {
|
pub struct RateLimitSnapshotEvent {
|
||||||
/// Percentage (0-100) of the primary window that has been consumed.
|
/// Percentage (0-100) of the primary window that has been consumed.
|
||||||
pub primary_used_percent: f64,
|
pub primary_used_percent: f64,
|
||||||
/// Percentage (0-100) of the protection window that has been consumed.
|
/// Percentage (0-100) of the secondary window that has been consumed.
|
||||||
pub weekly_used_percent: f64,
|
pub secondary_used_percent: f64,
|
||||||
/// Size of the primary window relative to weekly (0-100).
|
/// Size of the primary window relative to secondary (0-100).
|
||||||
pub primary_to_weekly_ratio_percent: f64,
|
pub primary_to_secondary_ratio_percent: f64,
|
||||||
/// Rolling window duration for the primary limit, in minutes.
|
/// Rolling window duration for the primary limit, in minutes.
|
||||||
pub primary_window_minutes: u64,
|
pub primary_window_minutes: u64,
|
||||||
/// Rolling window duration for the weekly limit, in minutes.
|
/// Rolling window duration for the secondary limit, in minutes.
|
||||||
pub weekly_window_minutes: u64,
|
pub secondary_window_minutes: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Includes prompts, tools and space to call compact.
|
// Includes prompts, tools and space to call compact.
|
||||||
|
|||||||
@@ -115,32 +115,36 @@ const RATE_LIMIT_WARNING_THRESHOLDS: [f64; 3] = [50.0, 75.0, 90.0];
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct RateLimitWarningState {
|
struct RateLimitWarningState {
|
||||||
weekly_index: usize,
|
secondary_index: usize,
|
||||||
hourly_index: usize,
|
primary_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RateLimitWarningState {
|
impl RateLimitWarningState {
|
||||||
fn take_warnings(&mut self, weekly_used_percent: f64, hourly_used_percent: f64) -> Vec<String> {
|
fn take_warnings(
|
||||||
|
&mut self,
|
||||||
|
secondary_used_percent: f64,
|
||||||
|
primary_used_percent: f64,
|
||||||
|
) -> Vec<String> {
|
||||||
let mut warnings = Vec::new();
|
let mut warnings = Vec::new();
|
||||||
|
|
||||||
while self.weekly_index < RATE_LIMIT_WARNING_THRESHOLDS.len()
|
while self.secondary_index < RATE_LIMIT_WARNING_THRESHOLDS.len()
|
||||||
&& weekly_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.weekly_index]
|
&& secondary_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.secondary_index]
|
||||||
{
|
{
|
||||||
let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.weekly_index];
|
let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.secondary_index];
|
||||||
warnings.push(format!(
|
warnings.push(format!(
|
||||||
"Heads up, you've used over {threshold:.0}% of your weekly limit. Run /status for a breakdown."
|
"Heads up, you've used over {threshold:.0}% of your weekly limit. Run /status for a breakdown."
|
||||||
));
|
));
|
||||||
self.weekly_index += 1;
|
self.secondary_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while self.hourly_index < RATE_LIMIT_WARNING_THRESHOLDS.len()
|
while self.primary_index < RATE_LIMIT_WARNING_THRESHOLDS.len()
|
||||||
&& hourly_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.hourly_index]
|
&& primary_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.primary_index]
|
||||||
{
|
{
|
||||||
let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.hourly_index];
|
let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.primary_index];
|
||||||
warnings.push(format!(
|
warnings.push(format!(
|
||||||
"Heads up, you've used over {threshold:.0}% of your 5h limit. Run /status for a breakdown."
|
"Heads up, you've used over {threshold:.0}% of your 5h limit. Run /status for a breakdown."
|
||||||
));
|
));
|
||||||
self.hourly_index += 1;
|
self.primary_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
warnings
|
warnings
|
||||||
@@ -339,9 +343,10 @@ impl ChatWidget {
|
|||||||
|
|
||||||
fn on_rate_limit_snapshot(&mut self, snapshot: Option<RateLimitSnapshotEvent>) {
|
fn on_rate_limit_snapshot(&mut self, snapshot: Option<RateLimitSnapshotEvent>) {
|
||||||
if let Some(snapshot) = snapshot {
|
if let Some(snapshot) = snapshot {
|
||||||
let warnings = self
|
let warnings = self.rate_limit_warnings.take_warnings(
|
||||||
.rate_limit_warnings
|
snapshot.secondary_used_percent,
|
||||||
.take_warnings(snapshot.weekly_used_percent, snapshot.primary_used_percent);
|
snapshot.primary_used_percent,
|
||||||
|
);
|
||||||
self.rate_limit_snapshot = Some(snapshot);
|
self.rate_limit_snapshot = Some(snapshot);
|
||||||
if !warnings.is_empty() {
|
if !warnings.is_empty() {
|
||||||
for warning in warnings {
|
for warning in warnings {
|
||||||
|
|||||||
@@ -1619,7 +1619,7 @@ fn build_status_limit_lines(snapshot: Option<&RateLimitSnapshotEvent>) -> Vec<Li
|
|||||||
Some(snapshot) => {
|
Some(snapshot) => {
|
||||||
let rows = [
|
let rows = [
|
||||||
("5h limit".to_string(), snapshot.primary_used_percent),
|
("5h limit".to_string(), snapshot.primary_used_percent),
|
||||||
("Weekly limit".to_string(), snapshot.weekly_used_percent),
|
("Weekly limit".to_string(), snapshot.secondary_used_percent),
|
||||||
];
|
];
|
||||||
let label_width = rows
|
let label_width = rows
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user