Read Codex limits without waiting on account/read (#13733)
Codex 0.158's app-server can leave account/read unanswered, and asking it first lost the limits whenever it did, leaving the agents panel showing "Codex limits unavailable". The limits name the plan themselves, so they're asked first and account/read is only a short fallback when they don't. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e332dc975d
commit
b421b1b479
2 files changed
+28
-7
No files matched your search
@@ -544,12 +544,20 @@ def fetch_codex_rpc():
|
||||
rpc_request(proc, 1, "initialize", {"clientInfo": {"name": "omarchy-agent-usage", "version": "1"}}, timeout=8)
|
||||
proc.stdin.write(json.dumps({"method": "initialized", "params": {}}) + "\n")
|
||||
proc.stdin.flush()
|
||||
account_msg = rpc_request(proc, 2, "account/read", timeout=4)
|
||||
limits_msg = rpc_request(proc, 3, "account/rateLimits/read", timeout=4)
|
||||
|
||||
account = (account_msg.get("result") or {}).get("account") or {}
|
||||
limits_msg = rpc_request(proc, 2, "account/rateLimits/read", timeout=8)
|
||||
limits = (limits_msg.get("result") or {}).get("rateLimits") or {}
|
||||
plan = limits.get("planType") or account.get("planType") or account.get("type") or ""
|
||||
plan = limits.get("planType") or ""
|
||||
|
||||
# The limits name the plan themselves. account/read is only a fallback
|
||||
# for when they don't, and never a reason to lose them: Codex 0.158's
|
||||
# app-server can leave it unanswered for good.
|
||||
if not plan:
|
||||
try:
|
||||
account_msg = rpc_request(proc, 3, "account/read", timeout=2)
|
||||
account = (account_msg.get("result") or {}).get("account") or {}
|
||||
plan = account.get("planType") or account.get("type") or ""
|
||||
except TimeoutError:
|
||||
pass
|
||||
result["tierLabel"] = str(plan) if plan else ""
|
||||
|
||||
for window in (limits.get("primary"), limits.get("secondary")):
|
||||
|
||||
@@ -26,10 +26,12 @@ while read -r request; do
|
||||
jq -cn --argjson id "$id" '{id: $id, result: {}}'
|
||||
;;
|
||||
account/read)
|
||||
jq -cn --argjson id "$id" '{id: $id, result: {account: {}}}'
|
||||
# Codex 0.158 can leave this one unanswered for good.
|
||||
[[ -n ${CODEX_ACCOUNT_READ_HANGS:-} ]] ||
|
||||
jq -cn --argjson id "$id" '{id: $id, result: {account: {}}}'
|
||||
;;
|
||||
account/rateLimits/read)
|
||||
jq -cn --argjson id "$id" '{id: $id, result: {rateLimits: {}}}'
|
||||
jq -cn --argjson id "$id" --argjson limits "${CODEX_RATE_LIMITS:-{\}}" '{id: $id, result: {rateLimits: $limits}}'
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -603,3 +605,14 @@ result=$(HOME="$INTERRUPTED_HOME" CODEX_HOME="$INTERRUPTED_HOME/.codex" XDG_CACH
|
||||
[[ $(jq -r '.todayTotalTokens' <<<"$result") == "9" ]] ||
|
||||
fail "Codex collector does not reuse a snapshot from an interrupted scan" "$result"
|
||||
pass "Codex collector does not cache an interrupted opencode scan"
|
||||
|
||||
# The limits name the plan themselves, so an account/read that never answers
|
||||
# costs nothing: the limits still arrive, and quickly.
|
||||
started=$(date +%s)
|
||||
result=$(HOME="$TEST_HOME" CODEX_HOME="$TEST_HOME/.codex" XDG_DATA_HOME="$TEST_HOME/.local/share" PATH="$TEST_HOME/bin:$PATH" \
|
||||
CODEX_ACCOUNT_READ_HANGS=1 CODEX_RATE_LIMITS='{"planType":"pro","primary":{"usedPercent":36,"windowDurationMins":10080}}' \
|
||||
"$ROOT/bin/omarchy-agent-usage-codex" --limits-only)
|
||||
(( $(date +%s) - started < 4 )) || fail "Codex collector doesn't wait on account/read when the limits name the plan"
|
||||
[[ $(jq -c '{tierLabel, usageStatusText, limits: [.limits[] | {label, percent}]}' <<<"$result") == '{"tierLabel":"pro","usageStatusText":"","limits":[{"label":"Weekly (7-day)","percent":0.36}]}' ]] ||
|
||||
fail "Codex collector reads limits even when account/read never answers" "$result"
|
||||
pass "Codex collector reads limits even when account/read never answers"
|
||||
Reference in new issue
Block a user