feat(sakana): surface pay-as-you-go credit balance#1825
Conversation
Sakana's existing provider only reads the Subscription tab of console.sakana.ai/billing (5-hour/weekly quota windows). Fugu Ultra's pay-as-you-go credit balance and usage total live on the same page's "Pay as you go" tab, which the server only renders when the request includes ?tab=payAsYouGo — so it's fetched as a second, best-effort GET alongside the existing subscription request. - Add SakanaPayAsYouGoSnapshot + parser for the credit balance, rolling usage total, and date-range label, matching the tab's real rendered markup (including React's <!-- --> hydration comments). - The second request never throws: any failure (network, non-200, wrong origin, unparseable markup) just omits the field so an account without PAYG access still gets its quota windows. - Wire supportsCredits + a Balance/Recent usage menu row and menu bar text, mirroring the existing MiMo balance display pattern. Verified against console.sakana.ai/billing?tab=payAsYouGo with a live account before writing the parser.
|
Codex review: needs real behavior proof before merge. Reviewed July 4, 2026, 5:54 AM ET / 09:54 UTC. Summary Reproducibility: not applicable. as a bug reproduction: this is a feature PR. Source review and tests show the intended fetch/render paths, but real menu/toggle proof is still incomplete. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land after maintainer acceptance of the extra same-origin Sakana billing request, redacted current-head app proof of the visible menu behavior, and a release-note refresh against the current unreleased version. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction: this is a feature PR. Source review and tests show the intended fetch/render paths, but real menu/toggle proof is still incomplete. Is this the best way to solve the issue? Mostly yes: the implementation follows existing provider fetch, snapshot, bounded-task, and menu-card patterns, and prior review defects appear addressed. The remaining gaps are proof, maintainer acceptance of the added optional request, and stale release-note placement rather than a broad redesign. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 93cb1233b305. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (5 earlier review cycles)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0bae5719be
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Two P2 findings from the automated review on this PR (steipete#1825): - The pay-as-you-go request ignored the "Show optional credits and extra usage" opt-out: it fired unconditionally even when context.includeOptionalUsage was false, making an extra console request users had explicitly disabled. fetchUsage now takes an includeOptionalUsage flag (default true) and skips the request entirely when it's false, mirroring the existing DeepSeek/MiniMax/ OpenCodeGo pattern for the same setting. - sakanaBalanceDisplayText treated the "secondary" menu bar metric preference as "show PAYG balance", but Sakana already has a real secondary (weekly) rate window, and .secondary is the legitimate preference for showing *that* in the menu bar. Reusing it collided with that meaning: anyone who picked "Weekly" as their menu bar metric would see the credit balance instead. Removed the menu-bar wiring rather than inventing a new preference value to disambiguate the two meanings -- the credit balance is still fully visible via the Balance/Recent usage dropdown-menu rows, which don't have this ambiguity.
|
Addressed both P2 findings from the automated review:
18/18 Sakana tests pass, |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Two P2 findings from clawsweeper's second pass on this PR: - supportsCredits: true activated the shared generic credits-card UI path (MenuCardView+Costs.swift creditsLine), which has no Sakana branch and no other consumer of Sakana's data -- it falls back to rendering the static creditsHint string instead of the actual fetched balance. Confirmed supportsCredits is read in exactly one place in the app, so reverting it to false is a zero-side-effect fix; the real balance is still fully visible via the explicit Balance/Recent usage menu rows added earlier in this PR, which don't have this ambiguity. - The optional pay-as-you-go fetch was awaited with the same timeout as the required subscription fetch, so a slow PAYG response could delay returning already-parsed 5-hour/weekly quota windows by up to the full timeout a second time. Bounded it with BoundedTaskJoin at a fixed 5s grace period, independent of the caller's webTimeout -- mirrors OpenRouterUsageFetcher's existing boundedKeyFetch pattern for its own optional /key enrichment call, down to the _forTesting entry point and the "operation that ignores cancellation" regression test shape.
|
Addressed the two new P2 findings from the re-review, plus the requested real behavior proof:
Real behavior proof — built this exact branch (with both fixes applied) into the {
"provider": "sakana",
"source": "web",
"usage": {
"identity": { "loginMethod": "Standard $20/mo", "providerID": "sakana" },
"primary": { "usedPercent": 0, "windowMinutes": 300 },
"secondary": { "usedPercent": 18, "windowMinutes": 10080, "resetsAt": "2026-07-05T18:30:00Z" },
"sakanaPayAsYouGo": { "creditBalance": 0, "periodUsageTotal": 0, "periodLabel": "Jun 02, 2026 - Jul 01, 2026" },
"updatedAt": "2026-07-01T21:08:07Z"
}
}
19/19 Sakana tests pass, lint clean. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
…you-go-credits # Conflicts: # Sources/CodexBarCore/UsageFetcher.swift # Tests/CodexBarTests/SakanaUsageFetcherTests.swift
Codex review finding on the render path: the Balance/Recent usage rows rendered solely from snapshot.sakanaPayAsYouGo without checking the "Show optional credits and extra usage" setting. Because toggling that setting off only rebuilds the menu (no immediate refetch), a previously-fetched balance lingered in the cached snapshot and the rows stayed visible until the next successful refresh cleared the field. Gate the rows on settings.showOptionalCreditsAndExtraUsage at the render layer too -- the same setting that already gates the fetch (ProviderRegistry) -- so the opt-out takes effect immediately regardless of cached snapshot contents. The required 5-hour/weekly quota windows are unaffected. Adds MenuDescriptorSakanaTests covering both the enabled (rows present) and disabled (rows hidden, quota windows still shown) paths.
|
Addressed the Codex render-path finding (and rebased on top of @steipete's concurrent-enrichment rework). Fix: the Added
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 56a01cc116
ℹ️ 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".
# Conflicts: # CHANGELOG.md # Sources/CodexBarCore/Providers/Gemini/GeminiStatusProbe.swift
# Conflicts: # CHANGELOG.md
|
Landed as 97c0035. Proof on exact PR head 89bcd85:
Subscription quota remains authoritative; optional PAYG failures are bounded and contained, and both fetch and render obey the optional-usage setting. Thanks @ss251! |
Summary
Extra usagecard in the live menu and matching text-descriptor rows; both fetch and render paths obey the optional-usage setting, so cached values disappear immediately when disabled.Proof
89bcd8552358e81612399bd9221dd5b639d01ae0.swift test --filter 'SakanaUsageFetcherTests|MenuDescriptorSakanaTests'— 27/27 passed.make check— repository guards, links, locale parity, SwiftFormat, and SwiftLint passed with zero violations.make test— all 46 sharded groups passed on the reviewed Sakana code head; exact integrated-head CI reruns the complete matrix../Scripts/compile_and_run.sh— production bundle built, signed, packaged, launched, and remained running from this exact checkout.?tab=payAsYouGoroute: feat(sakana): surface pay-as-you-go credit balance #1825 (comment).403 REGION RESTRICTEDpage in the UK and has no Sakana session; the exact bundled CLI therefore reports no available Sakana fetch strategy. No authenticated claim is inferred from synthetic data.Risk
Low to medium and provider-scoped. The required subscription result never waits more than the bounded enrichment budget, optional failures remain contained, the optional task is cancelled on required failure/caller cancellation, and cached optional rows obey the current setting at render time.