Skip to content

feat: add Grok web usage gauge and cross-tier plan merge#34

Merged
ElbertePlinio merged 2 commits into
mainfrom
feat/web-full-gauges
Jul 10, 2026
Merged

feat: add Grok web usage gauge and cross-tier plan merge#34
ElbertePlinio merged 2 commits into
mainfrom
feat/web-full-gauges

Conversation

@ElbertePlinio

Copy link
Copy Markdown
Member

Adds the cookie-gated grok.web provider: PickGauge reads Grok's real weekly usage (the shared "Weekly SuperGrok Limit") from GET grok.com/rest/grok/credits using the opt-in managed browser profile, and gives Grok a distinct tray/float accent. Ollama's existing web scrape is untouched; both services' web rows now inherit the plan detail from their zero-setup sibling.

Refs #26 (PR 3 of the 4-PR plan; PR 4 = headless usage --json + skill remains).

Endpoint provenance: discovered from grok.com's own JS bundles (proto descriptors for grok_api_v2.GetGrokCreditsConfig embed the google.api.http annotation /rest/grok/credits); response shape is the proto3-JSON of GrokCreditsConfig (creditUsagePercent, productUsage[]{product, usagePercent}, currentPeriod.billingPeriodEnd). Verified live that the route exists and is cookie-session-gated (CLI bearer → Connect NOT_FOUND; same bearer works on /rest/subscriptions).

What changed

  • Sidecar: grok allowlisted with pinned URLs only (grok.com/ for browser passes, /rest/grok/credits for the cookie HTTP fast path); credits JSON parsed inside the sidecar; sanitized products array added to the response contract; absent creditUsagePercent = 0 used; HTML body/401/403 → logged_out; missing configunexpected_ui. Cookies and raw bodies never leave the sidecar.
  • Rust: UsageProviderId::GrokWeb (grok.web), fail-closed registration + headless override (the ollama pattern), grok managed browser profile (grokPath), login flow, weekly-only window (no 5h slot anywhere).
  • Merge: web-source snapshots now prefer percentages > parsed > newest, and the chosen row inherits plan/billingPeriodEnd from siblings — grok.web keeps grok.cli's plan, ollama.web keeps ollama.local's plan.
  • Distinct Grok accent: tray [156,163,175] neutral gray, float var(--muted) (was Claude's ember — flagged in feat: add Grok zero-setup usage provider (grok.cli) #28).
  • Frontend: grok web actions (refresh/login/official page) when web readings are on; weekly gauge card; Grok Build segment shown as a detail; Settings profile path row.
  • Docs: README privacy/web sections, parser contract doc, UNRELEASED.md.

Tested

  • cargo test --locked --all-targets: 261 passed, 1 ignored.
  • bun run check clean; bun run test: 66 Vitest + 21 sidecar Node tests (new grok cases: happy path, absent-percent, missing-config, HTML body, 401/403).

Not tested yet

  • Live cookie flow (no grok.com session exists on this machine by design — tokens/cookies are user-owned). The owner's one-tap "connect web session" is the remaining manual validation; failure modes degrade to logged_out/unexpected_ui, never wrong numbers.

Risks

@ElbertePlinio

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ee3edefd1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/usage.rs
Comment on lines +1499 to +1502
if config.providers.web_enabled {
providers.push(Box::new(FailClosedWebProvider {
service: Service::Grok,
}));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Grok sidecar refresh from being backoff-blocked

With both cliEnabled and webEnabled (the default path for merging Grok's CLI plan with web usage), this registers a fail-closed grok.web provider that runs inside engine.refresh_all(). In the Refresh now flow I checked (src-tauri/src/lib.rs::refresh_all_with_headless_web), engine.refresh_all() runs before the Grok headless sidecar refresh; this placeholder returns LoginRequired, records a 30s backoff for grok.web, and the immediate refresh_web_provider_headless(..., Service::Grok) is skipped by try_begin_refresh, so the new Grok web gauge is not fetched on refresh-now and manual official refreshes are temporarily blocked. Register the placeholder only where it will not immediately precede the sidecar refresh, or avoid backoff for this placeholder failure.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 30745d6 (pushed while this round was in flight): placeholder web providers no longer create or honor backoff — is_placeholder flows through the descriptor, refresh_all skips record_provider_failure for them, and regression tests cover grok, ollama, and the real-failure-still-backs-off case.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ee3edefd1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/usage.rs
Comment on lines +1499 to +1502
if config.providers.web_enabled {
providers.push(Box::new(FailClosedWebProvider {
service: Service::Grok,
}));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not back off Grok web before the headless refresh

When Grok web is enabled alongside the default CLI provider, registering this fail-closed grok.web provider means engine.refresh_all() refreshes it before the real headless refresh in refresh_all_with_headless_web. That synthetic provider always returns LoginRequired, which records a failure/backoff for the same grok.web key; the immediately following refresh_web_provider_headless(..., Service::Grok) then exits in try_begin_refresh while the backoff is active. In this common config, the main Refresh Now path never reads the managed Grok profile/credits endpoint and the card remains plan-only until a later due refresh/direct retry after backoff.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same finding as above — already fixed in 30745d6 (this round reviewed the pre-fix commit 7ee3edef). Re-requesting review on the current head.

@ElbertePlinio

Copy link
Copy Markdown
Member Author

@codex review

1 similar comment
@ElbertePlinio

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 30745d6ddd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ElbertePlinio ElbertePlinio force-pushed the feat/web-full-gauges branch from 30745d6 to bc561db Compare July 10, 2026 00:10
@ElbertePlinio ElbertePlinio merged commit 5213b21 into main Jul 10, 2026
1 check passed
@ElbertePlinio ElbertePlinio deleted the feat/web-full-gauges branch July 10, 2026 00:12
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