mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
Merge upstream/main: adopt rate limit struct changes; keep TUI behavior
- Prefer ours for TUI conflicted files (chatwidget.rs, history_cell.rs) - Adopt upstream protocol rate limit renames (primary/secondary) - Update core + exec + TUI to new fields and labels - Purge check: no reintroduced images - verify.sh + build-fast.sh: pass (zero warnings)
This commit is contained in:
@@ -663,18 +663,18 @@ fn attach_item_ids(payload_json: &mut Value, original_items: &[ResponseItem]) {
|
||||
|
||||
fn parse_rate_limit_snapshot(headers: &HeaderMap) -> Option<RateLimitSnapshotEvent> {
|
||||
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 primary_to_weekly_ratio_percent =
|
||||
parse_header_f64(headers, "x-codex-primary-over-protection-limit-percent")?;
|
||||
let secondary_used_percent = parse_header_f64(headers, "x-codex-secondary-used-percent")?;
|
||||
let primary_to_secondary_ratio_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 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 {
|
||||
primary_used_percent,
|
||||
weekly_used_percent,
|
||||
primary_to_weekly_ratio_percent,
|
||||
secondary_used_percent,
|
||||
primary_to_secondary_ratio_percent,
|
||||
primary_window_minutes,
|
||||
weekly_window_minutes,
|
||||
secondary_window_minutes,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3927,10 +3927,10 @@ async fn try_run_turn(
|
||||
let mut state = sess.state.lock().unwrap();
|
||||
state.latest_rate_limits = Some(RateLimitSnapshotEvent {
|
||||
primary_used_percent: snapshot.primary_used_percent,
|
||||
weekly_used_percent: snapshot.weekly_used_percent,
|
||||
primary_to_weekly_ratio_percent: snapshot.primary_to_weekly_ratio_percent,
|
||||
secondary_used_percent: snapshot.secondary_used_percent,
|
||||
primary_to_secondary_ratio_percent: snapshot.primary_to_secondary_ratio_percent,
|
||||
primary_window_minutes: snapshot.primary_window_minutes,
|
||||
weekly_window_minutes: snapshot.weekly_window_minutes,
|
||||
secondary_window_minutes: snapshot.secondary_window_minutes,
|
||||
});
|
||||
}
|
||||
// Note: ReasoningSummaryPartAdded handled above without scratchpad mutation.
|
||||
|
||||
@@ -779,14 +779,14 @@ impl TokenUsageInfo {
|
||||
pub struct RateLimitSnapshotEvent {
|
||||
/// Percentage (0-100) of the primary window that has been consumed.
|
||||
pub primary_used_percent: f64,
|
||||
/// Percentage (0-100) of the protection window that has been consumed.
|
||||
pub weekly_used_percent: f64,
|
||||
/// Size of the primary window relative to weekly (0-100).
|
||||
pub primary_to_weekly_ratio_percent: f64,
|
||||
/// Percentage (0-100) of the secondary window that has been consumed.
|
||||
pub secondary_used_percent: f64,
|
||||
/// Size of the primary window relative to secondary (0-100).
|
||||
pub primary_to_secondary_ratio_percent: f64,
|
||||
/// Rolling window duration for the primary limit, in minutes.
|
||||
pub primary_window_minutes: u64,
|
||||
/// Rolling window duration for the weekly limit, in minutes.
|
||||
pub weekly_window_minutes: u64,
|
||||
/// Rolling window duration for the secondary limit, in minutes.
|
||||
pub secondary_window_minutes: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
||||
@@ -860,10 +860,10 @@ async fn token_count_includes_rate_limits_snapshot() {
|
||||
let response = ResponseTemplate::new(200)
|
||||
.insert_header("content-type", "text/event-stream")
|
||||
.insert_header("x-codex-primary-used-percent", "12.5")
|
||||
.insert_header("x-codex-protection-used-percent", "40.0")
|
||||
.insert_header("x-codex-primary-over-protection-limit-percent", "75.0")
|
||||
.insert_header("x-codex-secondary-used-percent", "40.0")
|
||||
.insert_header("x-codex-primary-over-secondary-limit-percent", "75.0")
|
||||
.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");
|
||||
|
||||
Mock::given(method("POST"))
|
||||
@@ -926,10 +926,10 @@ async fn token_count_includes_rate_limits_snapshot() {
|
||||
},
|
||||
"rate_limits": {
|
||||
"primary_used_percent": 12.5,
|
||||
"weekly_used_percent": 40.0,
|
||||
"primary_to_weekly_ratio_percent": 75.0,
|
||||
"secondary_used_percent": 40.0,
|
||||
"primary_to_secondary_ratio_percent": 75.0,
|
||||
"primary_window_minutes": 10,
|
||||
"weekly_window_minutes": 60
|
||||
"secondary_window_minutes": 60
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -294,9 +294,9 @@ impl EventProcessor for EventProcessorWithHumanOutput {
|
||||
if let Some(snapshot) = &ev.rate_limits {
|
||||
ts_println!(
|
||||
self,
|
||||
"rate limits: hourly {:.1}% • weekly {:.1}%",
|
||||
"rate limits: hourly {:.1}% • secondary {:.1}%",
|
||||
snapshot.primary_used_percent,
|
||||
snapshot.weekly_used_percent
|
||||
snapshot.secondary_used_percent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,14 +647,14 @@ pub struct TokenCountEvent {
|
||||
pub struct RateLimitSnapshotEvent {
|
||||
/// Percentage (0-100) of the primary window that has been consumed.
|
||||
pub primary_used_percent: f64,
|
||||
/// Percentage (0-100) of the protection window that has been consumed.
|
||||
pub weekly_used_percent: f64,
|
||||
/// Size of the primary window relative to weekly (0-100).
|
||||
pub primary_to_weekly_ratio_percent: f64,
|
||||
/// Percentage (0-100) of the secondary window that has been consumed.
|
||||
pub secondary_used_percent: f64,
|
||||
/// Size of the primary window relative to secondary (0-100).
|
||||
pub primary_to_secondary_ratio_percent: f64,
|
||||
/// Rolling window duration for the primary limit, in minutes.
|
||||
pub primary_window_minutes: u64,
|
||||
/// Rolling window duration for the weekly limit, in minutes.
|
||||
pub weekly_window_minutes: u64,
|
||||
/// Rolling window duration for the secondary limit, in minutes.
|
||||
pub secondary_window_minutes: u64,
|
||||
}
|
||||
|
||||
/// Payload for `ReplayHistory` containing prior `ResponseItem`s and optional events.
|
||||
|
||||
@@ -242,7 +242,7 @@ impl RateLimitWarningState {
|
||||
{
|
||||
let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.weekly_index];
|
||||
warnings.push(format!(
|
||||
"Weekly usage exceeded {threshold:.0}% of the limit. Run /limits for detailed usage."
|
||||
"Secondary usage exceeded {threshold:.0}% of the limit. Run /limits for detailed usage."
|
||||
));
|
||||
self.weekly_index += 1;
|
||||
}
|
||||
@@ -4244,7 +4244,7 @@ impl ChatWidget<'_> {
|
||||
self.update_rate_limit_resets(previous_snapshot.as_ref(), &snapshot);
|
||||
let warnings = self
|
||||
.rate_limit_warnings
|
||||
.take_warnings(snapshot.weekly_used_percent, snapshot.primary_used_percent);
|
||||
.take_warnings(snapshot.secondary_used_percent, snapshot.primary_used_percent);
|
||||
self.rate_limit_snapshot = Some(snapshot);
|
||||
if !warnings.is_empty() {
|
||||
for warning in warnings {
|
||||
@@ -5260,7 +5260,7 @@ fn update_rate_limit_resets(
|
||||
changed_primary = true;
|
||||
}
|
||||
}
|
||||
if current.weekly_used_percent + 0.5 < prev.weekly_used_percent {
|
||||
if current.secondary_used_percent + 0.5 < prev.secondary_used_percent {
|
||||
if self
|
||||
.rate_limit_last_weekly_reset_at
|
||||
.map_or(true, |existing| now > existing)
|
||||
@@ -5276,7 +5276,7 @@ fn update_rate_limit_resets(
|
||||
self.rate_limit_last_primary_reset_at = Some(now);
|
||||
changed_primary = true;
|
||||
}
|
||||
if current.weekly_used_percent <= 1.0
|
||||
if current.secondary_used_percent <= 1.0
|
||||
&& self.rate_limit_last_weekly_reset_at.is_none()
|
||||
{
|
||||
self.rate_limit_last_weekly_reset_at = Some(now);
|
||||
|
||||
@@ -82,10 +82,10 @@ fn run_refresh(
|
||||
|
||||
let snapshot = CoreRateLimitSnapshotEvent {
|
||||
primary_used_percent: proto_snapshot.primary_used_percent,
|
||||
weekly_used_percent: proto_snapshot.weekly_used_percent,
|
||||
primary_to_weekly_ratio_percent: proto_snapshot.primary_to_weekly_ratio_percent,
|
||||
secondary_used_percent: proto_snapshot.secondary_used_percent,
|
||||
primary_to_secondary_ratio_percent: proto_snapshot.primary_to_secondary_ratio_percent,
|
||||
primary_window_minutes: proto_snapshot.primary_window_minutes,
|
||||
weekly_window_minutes: proto_snapshot.weekly_window_minutes,
|
||||
secondary_window_minutes: proto_snapshot.secondary_window_minutes,
|
||||
};
|
||||
|
||||
let event = Event {
|
||||
|
||||
@@ -128,14 +128,14 @@ struct RateLimitMetrics {
|
||||
impl RateLimitMetrics {
|
||||
fn from_snapshot(snapshot: &RateLimitSnapshotEvent) -> Self {
|
||||
let hourly_used = snapshot.primary_used_percent.clamp(0.0, 100.0);
|
||||
let weekly_used = snapshot.weekly_used_percent.clamp(0.0, 100.0);
|
||||
let weekly_used = snapshot.secondary_used_percent.clamp(0.0, 100.0);
|
||||
Self {
|
||||
hourly_used,
|
||||
weekly_used,
|
||||
hourly_remaining: (100.0 - hourly_used).max(0.0),
|
||||
weekly_remaining: (100.0 - weekly_used).max(0.0),
|
||||
primary_window_minutes: snapshot.primary_window_minutes,
|
||||
weekly_window_minutes: snapshot.weekly_window_minutes,
|
||||
weekly_window_minutes: snapshot.secondary_window_minutes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ fn build_summary_lines(
|
||||
|
||||
lines.push("".into());
|
||||
|
||||
lines.push(section_header("Weekly Limit"));
|
||||
lines.push(section_header("Secondary Limit"));
|
||||
lines.push(build_bar_line(
|
||||
"Usage",
|
||||
metrics.weekly_used,
|
||||
@@ -193,7 +193,7 @@ fn build_summary_lines(
|
||||
reset_info.weekly_last_reset,
|
||||
));
|
||||
lines.push(build_weekly_reset_line(
|
||||
snapshot.weekly_window_minutes,
|
||||
snapshot.secondary_window_minutes,
|
||||
reset_info.weekly_last_reset,
|
||||
));
|
||||
|
||||
@@ -800,7 +800,7 @@ fn format_minutes_round_units(minutes: u64) -> String {
|
||||
}
|
||||
|
||||
fn extract_capacity_fraction(snapshot: &RateLimitSnapshotEvent) -> Option<f64> {
|
||||
let ratio = snapshot.primary_to_weekly_ratio_percent;
|
||||
let ratio = snapshot.primary_to_secondary_ratio_percent;
|
||||
if ratio.is_finite() {
|
||||
Some((ratio / 100.0).clamp(0.0, 1.0))
|
||||
} else {
|
||||
@@ -958,10 +958,10 @@ mod tests {
|
||||
fn snapshot() -> RateLimitSnapshotEvent {
|
||||
RateLimitSnapshotEvent {
|
||||
primary_used_percent: 30.0,
|
||||
weekly_used_percent: 60.0,
|
||||
primary_to_weekly_ratio_percent: 40.0,
|
||||
secondary_used_percent: 60.0,
|
||||
primary_to_secondary_ratio_percent: 40.0,
|
||||
primary_window_minutes: 300,
|
||||
weekly_window_minutes: 10_080,
|
||||
secondary_window_minutes: 10_080,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1026,7 @@ mod tests {
|
||||
#[test]
|
||||
fn build_display_without_ratio_skips_gauge() {
|
||||
let mut s = snapshot();
|
||||
s.primary_to_weekly_ratio_percent = f64::NAN;
|
||||
s.primary_to_secondary_ratio_percent = f64::NAN;
|
||||
let display = build_limits_view(&s, RateLimitResetInfo::default(), DEFAULT_GRID_CONFIG);
|
||||
assert!(display.gauge_lines(80).is_empty());
|
||||
assert!(display.legend_lines.is_empty());
|
||||
|
||||
Reference in New Issue
Block a user