cdx-manager 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -294,8 +294,8 @@ def create_session_store(base_dir):
294
294
  continue
295
295
  try:
296
296
  entry = json.loads(line)
297
- except json.JSONDecodeError as error:
298
- raise CdxError(f"Corrupt JSONL file: {launch_history_file}") from error
297
+ except json.JSONDecodeError:
298
+ continue
299
299
  if session_name and entry.get("session_name") != session_name:
300
300
  continue
301
301
  entries.append(entry)
@@ -20,10 +20,6 @@ _KEY_VALUE_PATTERNS = [
20
20
  ("remaining_5h_pct", re.compile(r"remaining_?5h_pct\s*[:=]\s*(\d{1,3})%?", re.I)),
21
21
  ("remaining_week_pct", re.compile(r"remaining_?week_pct\s*[:=]\s*(\d{1,3})%?", re.I)),
22
22
  ("credits", re.compile(r"credits?\s*[:=]\s*(\d[\d, ]*(?:\.\d+)?)\s*(?:credits?)?", re.I)),
23
- ("remaining_5h_pct", re.compile(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", re.I)),
24
- ("remaining_week_pct", re.compile(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", re.I)),
25
- ("remaining_5h_pct", re.compile(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", re.I)),
26
- ("remaining_week_pct", re.compile(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", re.I)),
27
23
  ("usage_pct", re.compile(r"usage\s*[:=]\s*(\d{1,3})%", re.I)),
28
24
  ("usage_pct", re.compile(r"current\s*[:=]\s*(\d{1,3})%", re.I)),
29
25
  ("remaining_5h_pct", re.compile(r"5h(?:\s+remaining)?\s*[:=]\s*(\d{1,3})%", re.I)),
@@ -32,6 +28,14 @@ _KEY_VALUE_PATTERNS = [
32
28
  ("remaining_week_pct", re.compile(r"remaining\s+week\s*[:=]\s*(\d{1,3})%", re.I)),
33
29
  ]
34
30
 
31
+ _CODEX_LIMIT_PERCENT_PATTERNS = [
32
+ ("remaining_5h_pct", re.compile(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", re.I)),
33
+ ("remaining_5h_pct", re.compile(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", re.I)),
34
+ ("remaining_week_pct", re.compile(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", re.I)),
35
+ ("remaining_week_pct", re.compile(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", re.I)),
36
+ ]
37
+ _KEY_VALUE_PATTERNS.extend(_CODEX_LIMIT_PERCENT_PATTERNS)
38
+
35
39
 
36
40
  def _strip_ansi(text):
37
41
  return _ANSI_ESCAPE.sub("", str(text or ""))
@@ -103,6 +107,27 @@ def _is_zero_credit_balance(value):
103
107
  return False
104
108
 
105
109
 
110
+ def _get_structured_rate_limit_window(rate_limits, duration_mins, fallback_key):
111
+ for key in ("primary", "secondary"):
112
+ window = rate_limits.get(key) or {}
113
+ if window.get("windowDurationMins") == duration_mins:
114
+ return window
115
+ if window.get("window_minutes") == duration_mins:
116
+ return window
117
+ fallback = rate_limits.get(fallback_key) or {}
118
+ if "windowDurationMins" in fallback or "window_minutes" in fallback:
119
+ return {}
120
+ return fallback
121
+
122
+
123
+ def _get_rate_limit_used_percent(window):
124
+ return window.get("used_percent", window.get("usedPercent"))
125
+
126
+
127
+ def _get_rate_limit_reset_at(window):
128
+ return window.get("resets_at", window.get("resetsAt"))
129
+
130
+
106
131
  def _extract_structured_rate_limits(record):
107
132
  if not isinstance(record, dict):
108
133
  return None
@@ -111,25 +136,27 @@ def _extract_structured_rate_limits(record):
111
136
  if not isinstance(rate_limits, dict):
112
137
  return None
113
138
 
114
- primary = rate_limits.get("primary") or {}
115
- secondary = rate_limits.get("secondary") or {}
139
+ five_hour = _get_structured_rate_limit_window(rate_limits, 300, "primary")
140
+ weekly = _get_structured_rate_limit_window(rate_limits, 10080, "secondary")
116
141
  credits = rate_limits.get("credits") or {}
117
142
 
118
- primary_used = _coerce_percentage(primary.get("used_percent"))
119
- secondary_used = _coerce_percentage(secondary.get("used_percent"))
120
- remaining_5h_pct = None if primary_used is None else max(0, 100 - primary_used)
121
- remaining_week_pct = None if secondary_used is None else max(0, 100 - secondary_used)
143
+ five_hour_used = _coerce_percentage(_get_rate_limit_used_percent(five_hour))
144
+ weekly_used = _coerce_percentage(_get_rate_limit_used_percent(weekly))
145
+ remaining_5h_pct = None if five_hour_used is None else max(0, 100 - five_hour_used)
146
+ remaining_week_pct = None if weekly_used is None else max(0, 100 - weekly_used)
122
147
 
123
148
  result = {
124
- "usage_pct": primary_used if primary_used is not None else secondary_used,
149
+ "usage_pct": five_hour_used if five_hour_used is not None else weekly_used,
125
150
  "remaining_5h_pct": remaining_5h_pct,
126
151
  "remaining_week_pct": remaining_week_pct,
127
152
  "credits": None,
128
- "reset_5h_at": _normalize_timestamp_value(primary.get("resets_at")),
129
- "reset_week_at": _normalize_timestamp_value(secondary.get("resets_at")),
153
+ "reset_5h_at": _normalize_timestamp_value(_get_rate_limit_reset_at(five_hour)),
154
+ "reset_week_at": _normalize_timestamp_value(_get_rate_limit_reset_at(weekly)),
130
155
  "reset_at": None,
131
156
  "raw_status_text": json.dumps(rate_limits, sort_keys=True),
132
157
  }
158
+ if not five_hour and weekly:
159
+ result["_skip_5h_backfill"] = True
133
160
 
134
161
  balance = credits.get("balance")
135
162
  if balance not in (None, "") and not (
@@ -496,18 +523,10 @@ def extract_named_statuses_from_text(text):
496
523
  break
497
524
 
498
525
  for line in lines:
499
- m = re.search(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", line, re.I)
500
- if m and "remaining_5h_pct" not in result:
501
- result["remaining_5h_pct"] = int(m[1])
502
- m = re.search(r"5h\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", line, re.I)
503
- if m and "remaining_5h_pct" not in result:
504
- result["remaining_5h_pct"] = int(m[1])
505
- m = re.search(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})%\s*left", line, re.I)
506
- if m and "remaining_week_pct" not in result:
507
- result["remaining_week_pct"] = int(m[1])
508
- m = re.search(r"weekly\s+limit\s*:\s*\[[^\]]*\]\s*(\d{1,3})(?:%|\b)", line, re.I)
509
- if m and "remaining_week_pct" not in result:
510
- result["remaining_week_pct"] = int(m[1])
526
+ for field, pattern in _CODEX_LIMIT_PERCENT_PATTERNS:
527
+ m = pattern.search(line)
528
+ if m and field not in result:
529
+ result[field] = int(m[1])
511
530
 
512
531
  if "remaining_5h_pct" in result and "usage_pct" not in result:
513
532
  result["usage_pct"] = max(0, 100 - result["remaining_5h_pct"])
@@ -640,6 +659,8 @@ _STATUS_VALUE_FIELDS = (
640
659
 
641
660
  def _backfill_missing_fields(target, source):
642
661
  for field in _STATUS_VALUE_FIELDS:
662
+ if target.get("_skip_5h_backfill") and field in ("remaining_5h_pct", "reset_5h_at"):
663
+ continue
643
664
  if target.get(field) is None and source.get(field) is not None:
644
665
  target[field] = source[field]
645
666
 
@@ -694,6 +715,7 @@ def find_latest_status_artifact(
694
715
  "reset_week_at": candidate["structured"].get("reset_week_at"),
695
716
  "reset_at": candidate["structured"].get("reset_at"),
696
717
  "raw_status_text": candidate["structured"].get("raw_status_text"),
718
+ "_skip_5h_backfill": candidate["structured"].get("_skip_5h_backfill"),
697
719
  }
698
720
  if not parsed:
699
721
  continue