Skip to content

fix: check quotas without model probe - #208

Open
lubshad wants to merge 1 commit into
ndycode:mainfrom
lubshad:fix/free-account-quota-check
Open

fix: check quotas without model probe#208
lubshad wants to merge 1 commit into
ndycode:mainfrom
lubshad:fix/free-account-quota-check

Conversation

@lubshad

@lubshad lubshad commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • replace the terminal quota check synthetic model request with the model-independent /wham/usage endpoint
  • format shared usage windows, plan type, credits, and additional limits in the account menu
  • preserve deactivated-workspace and invalid-token cleanup without changing sanitized codex-limits errors
  • cover free-plan quota responses and verify no model request is sent

Testing

  • npm run typecheck
  • npm run lint
  • npm test (113 files, 2,825 tests)

Summary by CodeRabbit

  • New Features

    • Usage and quota information now comes from the Codex usage service, including free-plan limits and reset windows.
    • Account health checks display a more concise usage summary.
    • Deactivated workspaces and invalidated authentication are identified with clearer errors.
  • Bug Fixes

    • Improved handling of usage requests and account cleanup for free-plan accounts.
    • Usage checks no longer depend on legacy quota headers or model selection.

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

replaces synthetic model quota probes with the model-independent usage endpoint.

  • formats shared quota windows, plan type, credits, code-review limits, and additional limits.
  • preserves token-safe error sanitization and workspace/token cleanup.
  • adds vitest coverage for free-plan requests and normalized account errors.

Confidence Score: 5/5

the pr appears safe to merge.

the new usage endpoint preserves quota parsing, token-safe errors, workspace-scoped removal, and transaction-based concurrency protections without introducing an observable failure.

Important Files Changed

Filename Overview
index.ts routes quota checks through /wham/usage while retaining workspace-scoped cleanup and transactional persistence; no new concurrency defect was identified.
lib/codex-usage.ts adds opt-in account-error normalization without weakening token redaction or changing existing tui callers.
test/codex-usage.test.ts adds vitest coverage for model-independent free-plan usage and normalized workspace/token failures.
test/index.test.ts verifies the account-menu quota path avoids model requests and preserves workspace-scoped cleanup.

Reviews (1): Last reviewed commit: "fix: check quotas without model probe" | Re-trigger Greptile

Context used:

@lubshad
lubshad requested a review from ndycode as a code owner July 27, 2026 11:43
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The Codex OAuth plugin now probes /wham/usage JSON payloads, formats quota summaries from parsed usage windows, and optionally normalizes deactivated-workspace and invalidated-token errors. Tests cover request shape, error mapping, free-plan handling, and workspace cleanup.

Changes

Codex usage flow

Layer / File(s) Summary
Usage fetch and account-error normalization
lib/codex-usage.ts, test/codex-usage.test.ts
fetchCodexUsage accepts normalizeAccountErrors, parses JSON error bodies, and normalizes recognized workspace and authentication failures with endpoint and error-path tests.
Health-check usage formatting
index.ts
The health check fetches and parses Codex usage payloads, then formats usage windows, limits, plan, and credits into the quota log line.
Free-plan cleanup regression coverage
test/index.test.ts
The cleanup test uses free-plan usage JSON and verifies model-independent GET requests without request bodies.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: ndycode

Sequence Diagram(s)

sequenceDiagram
  participant HealthCheck
  participant fetchCodexUsage
  participant parseCodexUsagePayload
  participant formatCodexQuotaLine
  HealthCheck->>fetchCodexUsage: GET usage payload
  fetchCodexUsage-->>HealthCheck: UsagePayload
  HealthCheck->>parseCodexUsagePayload: Parse payload
  parseCodexUsagePayload-->>HealthCheck: CodexUsageSummary
  HealthCheck->>formatCodexQuotaLine: Format summary
  formatCodexQuotaLine-->>HealthCheck: Quota log line
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: switching quota checks to the model-independent usage endpoint.
Description check ✅ Passed The summary and testing sections are clear and specific; only Compliance Confirmation and Notes are missing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
index.ts (1)

3059-3078: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider moving formatCodexQuotaLine into lib/codex-usage.ts.

It's a pure function of CodexUsageSummary with no closure dependency on authorize's scope, and it sits alongside formatUsageLimitTitle/formatUsageLimitSummary, which already live in lib/codex-usage.ts. Relocating it would let it be unit-tested directly (currently it's only exercised indirectly through the account-check flow) and keeps formatting logic consolidated with its siblings.

♻️ Suggested relocation
-							const formatCodexQuotaLine = (usage: CodexUsageSummary): string => {
-								const parts: string[] = [];
-								for (const window of [usage.primary, usage.secondary]) {
-									if (!hasUsageWindow(window)) continue;
-									parts.push(
-										`${formatUsageLimitTitle(window.windowMinutes)} ${formatUsageLimitSummary(window)}`,
-									);
-								}
-								if (hasUsageWindow(usage.codeReview)) {
-									parts.push(`Code review ${formatUsageLimitSummary(usage.codeReview)}`);
-								}
-								for (const limit of usage.additionalLimits) {
-									if (hasUsageWindow(limit.window)) {
-										parts.push(`${limit.name} ${formatUsageLimitSummary(limit.window)}`);
-									}
-								}
-								if (usage.planType) parts.push(`plan:${usage.planType}`);
-								if (usage.credits) parts.push(`credits:${usage.credits}`);
-								return parts.length > 0 ? parts.join(", ") : "quota unavailable";
-							};

Move the body into lib/codex-usage.ts as export function formatCodexQuotaLine(usage: CodexUsageSummary): string { ... } and import it in index.ts alongside the other usage helpers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@index.ts` around lines 3059 - 3078, Move the pure formatCodexQuotaLine
function into lib/codex-usage.ts alongside formatUsageLimitTitle and
formatUsageLimitSummary, exporting it with the same CodexUsageSummary signature.
Remove the local definition from authorize’s scope and import the helper in
index.ts with the other Codex usage utilities, preserving its existing
formatting behavior.
test/codex-usage.test.ts (1)

253-302: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Good coverage for the new normalization path; consider covering the default (non-normalized) branch too.

Both new tests validate normalizeAccountErrors: true. There's no regression test confirming that omitting normalizeAccountErrors (the default for other existing callers) still falls through to sanitizeCodexApiErrorMessage on a 402/401 response, which is the behavior those callers rely on.

✅ Suggested additional test
+	it("does not normalize account errors when normalizeAccountErrors is unset", async () => {
+		const fetchMock = vi.fn().mockResolvedValue(
+			new Response(JSON.stringify({ detail: { code: "deactivated_workspace" } }), {
+				status: 402,
+			}),
+		);
+		vi.stubGlobal("fetch", fetchMock);
+
+		await expect(fetchCodexUsage({
+			accountId: "account-1",
+			accessToken: "access-1",
+			organizationId: undefined,
+			timeoutMs: 1_000,
+		})).rejects.toThrow(/^HTTP 402/);
+	});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/codex-usage.test.ts` around lines 253 - 302, Add coverage in the
“normalizes usage endpoint workspace and token failures” test for
fetchCodexUsage when normalizeAccountErrors is omitted. Assert that 402 and 401
responses follow the existing sanitizeCodexApiErrorMessage behavior, while
preserving the current normalized-error assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@index.ts`:
- Around line 3059-3078: Move the pure formatCodexQuotaLine function into
lib/codex-usage.ts alongside formatUsageLimitTitle and formatUsageLimitSummary,
exporting it with the same CodexUsageSummary signature. Remove the local
definition from authorize’s scope and import the helper in index.ts with the
other Codex usage utilities, preserving its existing formatting behavior.

In `@test/codex-usage.test.ts`:
- Around line 253-302: Add coverage in the “normalizes usage endpoint workspace
and token failures” test for fetchCodexUsage when normalizeAccountErrors is
omitted. Assert that 402 and 401 responses follow the existing
sanitizeCodexApiErrorMessage behavior, while preserving the current
normalized-error assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ede8ad9e-4c34-41ab-83fa-859539bce074

📥 Commits

Reviewing files that changed from the base of the PR and between 7e2396b and f441d30.

📒 Files selected for processing (4)
  • index.ts
  • lib/codex-usage.ts
  • test/codex-usage.test.ts
  • test/index.test.ts

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