feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and an account without it reports the weekly window alone. Until now the pool took such an account for an unprobed seat: always eligible, ranked after every other, never held to the weekly cutoff, with no cap on its passes. - The burst window is the 5-hour one, else the weekly one (Seats::BurstWindow). An account whose burst window is the weekly one is ranked by it and admitted under the 95 % cutoff with the passes in flight projected on it, at the measured share per pass (0.04 at xhigh, 0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly reset when over it. - Every OAuth account and the local login takes at most 128 passes at once, every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run measured with 149 or more in flight on one account drew usage-limit rejections, none of the 119 with 139 or fewer. - A 'concurrents' rejection pauses the seat for 20 s or its retry-after, not until a window's reset (a seat sat two hours at 10 % on one). - Board entries, the folded foreign record and the board's view carry cost7d, so the drivers see each other's weekly load. - `seats` and the log table say `no limit` in such an account's 5-hour column; the board's others-line names its weekly projection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a2974a8139
commit
c28307601b
11 changed files with 209 additions and 26 deletions
|
|
@ -827,6 +827,19 @@ namespace Crafter::Review::Seats {
|
|||
return std::format("{:02d}:{:02d}", d.tm_hour, d.tm_min);
|
||||
}
|
||||
|
||||
std::optional<std::string> BurstWindow(const Json& windows) {
|
||||
for (const std::string_view window : {std::string_view("five_hour"), std::string_view("seven_day")}) {
|
||||
if (!Dyn::Get(Dyn::Or(Dyn::Get(windows, window), Dyn::EmptyDict()), "utilization").is_null()) return std::string(window);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string WindowCell(const Json& windows, std::string_view window) {
|
||||
const Json& u = Dyn::Get(Dyn::Or(Dyn::Get(windows, window), Dyn::EmptyDict()), "utilization");
|
||||
if (!u.is_null()) return std::format("{}%", Fmt(u));
|
||||
return window == "five_hour" && BurstWindow(windows) == "seven_day" ? std::string("no limit") : std::string("—");
|
||||
}
|
||||
|
||||
std::string FormatWhen(double epoch, double now, const Zone& zone) {
|
||||
const auto diffMin = static_cast<std::int64_t>(JsRound((epoch - now) / 60));
|
||||
std::string relative;
|
||||
|
|
@ -876,10 +889,7 @@ namespace Crafter::Review::Seats {
|
|||
if (anyInflight) header.emplace_back("in flight");
|
||||
rows.push_back(header);
|
||||
for (const Json& s : ordered) {
|
||||
auto w = [&](std::string_view k) {
|
||||
if (!Dyn::Has(Dyn::Or(Dyn::Get(s, "windows"), Dyn::EmptyDict()), k)) return std::string("—");
|
||||
return std::format("{}%", Fmt(Dyn::At(Window(s, k), "utilization")));
|
||||
};
|
||||
auto w = [&](std::string_view k) { return WindowCell(Dyn::Or(Dyn::Get(s, "windows"), Dyn::EmptyDict()), k); };
|
||||
auto when = [&](std::string_view k) {
|
||||
const Json& at = Dyn::Get(Dyn::Or(Window(s, k), Dyn::EmptyDict()), "resetsAt");
|
||||
return Dyn::Truthy(at) ? FormatWhen(AsDouble(at), now, zone) : std::string("—");
|
||||
|
|
|
|||
Loading…
Reference in a new issue