Skip to content

fix(daemon): migrate codex usage API to wham endpoint#267

Merged
AnnatarHe merged 1 commit intomainfrom
fix/codex-usage-api-endpoint
Apr 6, 2026
Merged

fix(daemon): migrate codex usage API to wham endpoint#267
AnnatarHe merged 1 commit intomainfrom
fix/codex-usage-api-endpoint

Conversation

@AnnatarHe
Copy link
Copy Markdown
Contributor

@AnnatarHe AnnatarHe commented Apr 6, 2026

Summary

  • Migrate codex usage API from api.openai.com/api/codex/usage to chatgpt.com/backend-api/wham/usage
  • Update response parsing to handle new category-based structure (rate_limit, code_review_rate_limit) with primary/secondary windows
  • Synthesize LimitID as <category>:<position> (e.g. rate_limit:primary) for downstream compatibility

Test plan

  • go test ./daemon/... passes
  • go vet ./daemon/... clean
  • Verify daemon correctly fetches and syncs usage data with live Codex auth

🤖 Generated with Claude Code


Open with Devin

…usage

The old OpenAI endpoint (api.openai.com/api/codex/usage) has been
replaced with the new wham usage endpoint. Updated response parsing
to handle the new category-based structure (rate_limit,
code_review_rate_limit) with primary/secondary windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 6, 2026

Codecov Report

❌ Patch coverage is 0% with 23 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
daemon/codex_ratelimit.go 0.00% 23 Missing ⚠️
Flag Coverage Δ
unittests 39.91% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
daemon/codex_ratelimit.go 25.64% <0.00%> (-2.67%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AnnatarHe
Copy link
Copy Markdown
Contributor Author

@claude review

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 6, 2026

Claude finished @AnnatarHe's task in 1m 16s —— View job


Code Review: PR #267 — Migrate Codex usage API to wham endpoint

  • Read changed file and diff
  • Analyze code changes and downstream usage
  • Post review feedback

Overall this is a clean migration. The structure changes look reasonable and mapWhamWindow is a nice extraction. A few observations:

1. Allowed and LimitReached fields are parsed but never used

whamRateLimitCategory defines Allowed and LimitReached (codex_ratelimit.go:171-172), but these fields are never read — not in fetchCodexUsage, not propagated to CodexRateLimitData, and not sent to the server. This is fine if you're intentionally ignoring them for now, but worth noting:

  • If the downstream server or statusline should know whether a limit has been reached, this data is silently dropped.
  • If they're genuinely unused, consider removing them from the struct to avoid confusion (or add a comment explaining they're parsed for future use).

2. AccountID is now a dead field on codexAuthData

The ChatGPT-Account-Id header was removed from fetchCodexUsage, which is correct for the new endpoint. However, codexAuthData.AccountID is still populated in loadCodexAuth() (codex_ratelimit.go:159) but never consumed anywhere. Consider removing it from codexAuthData and loadCodexAuth to keep things clean.

Clean up dead AccountID field →

3. Integer division truncation in WindowDurationMinutes

codex_ratelimit.go:244: w.LimitWindowSeconds / 60 uses integer division, so a window of e.g. 90 seconds becomes 1 minute (not 1.5). This is probably fine since rate limit windows are typically whole-minute values, but worth being aware of — if the new API ever returns sub-minute granularity, this silently rounds down.

4. UsedPercent is int but mapped to float64

whamRateLimitWindow.UsedPercent is typed as int (codex_ratelimit.go:178), then cast to float64 in mapWhamWindow. The old API returned a float64 directly (usagePercentage: 72.5). If the new API actually returns fractional percentages, you'll lose precision by parsing into int. Verify the API response — if it can return decimals, change UsedPercent to float64.

5. No test coverage for the new parsing logic

Codecov flags 23 new lines with 0% coverage. The existing tests mock fetchCodexUsageFunc entirely, so the new whamUsageResponse parsing and mapWhamWindow helper are untested. Consider adding a unit test for mapWhamWindow (it's a pure function, easy to test) and optionally an httptest server that returns a wham-shaped JSON response to exercise the full fetchCodexUsage path.

6. Minor: error messages still say "codex usage"

codex_ratelimit.go:205,210: Error strings reference "codex usage API" — this is fine for internal logging consistency, but could be confusing if someone is debugging and sees "codex" while the actual endpoint is chatgpt.com/backend-api/wham/usage. Not a blocker, just something to consider updating for clarity.


Verdict: The migration logic is correct and well-structured. The main actionable items are cleaning up the dead AccountID field and adding test coverage for the new parsing code. The rest are minor observations.
| Branch: fix/codex-usage-api-endpoint

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the rate limit tracking logic from the legacy Codex usage API to the new WHAM usage API endpoint. The changes include updated data structures to match the new response schema and a revised mapping process for primary and secondary rate limit windows. Feedback highlights the need to use float64 for usage percentages to prevent decoding failures and recommends restoring the ChatGPT-Account-Id header to ensure correct account identification.

Comment thread daemon/codex_ratelimit.go
ResetAt int64 `json:"resetAt"`
WindowDurationMinutes int `json:"windowDurationMinutes"`
type whamRateLimitWindow struct {
UsedPercent int `json:"used_percent"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The UsedPercent field is defined as an int. If the API returns a floating-point number (e.g., 45.5), the JSON decoding will fail with an error. Given that the previous API used float64 for usage percentages, it is safer to use float64 here to ensure robust parsing of the response.

Suggested change
UsedPercent int `json:"used_percent"`
UsedPercent float64 "json:\"used_percent\""

Comment thread daemon/codex_ratelimit.go
Comment on lines 191 to 192
req.Header.Set("Authorization", "Bearer "+auth.AccessToken)
if auth.AccountID != "" {
req.Header.Set("ChatGPT-Account-Id", auth.AccountID)
}
req.Header.Set("User-Agent", "shelltime-daemon")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The ChatGPT-Account-Id header was removed in this migration. This header is typically required by ChatGPT backend APIs to correctly identify the target account, especially for users who are members of multiple workspaces or organizations. Since auth.AccountID is still being loaded from the configuration, it should be included in the request headers to ensure the correct usage data is fetched.

Suggested change
req.Header.Set("Authorization", "Bearer "+auth.AccessToken)
if auth.AccountID != "" {
req.Header.Set("ChatGPT-Account-Id", auth.AccountID)
}
req.Header.Set("User-Agent", "shelltime-daemon")
req.Header.Set("Authorization", "Bearer "+auth.AccessToken)
if auth.AccountID != "" {
req.Header.Set("ChatGPT-Account-Id", auth.AccountID)
}
req.Header.Set("User-Agent", "shelltime-daemon")

@AnnatarHe AnnatarHe merged commit 67b3886 into main Apr 6, 2026
5 of 6 checks passed
@AnnatarHe AnnatarHe deleted the fix/codex-usage-api-endpoint branch April 6, 2026 16:55
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant