feat(quota): add wafer, synthetic, and neuralwatt quota checkers#1509
Conversation
Add Pattern B (URL-based detection) support for three new OpenAI-compatible providers: wafer.ai, synthetic.new, and neuralwatt.com. Each provider reuses TypeOpenai/TypeOpenaiResponses channel types with provider_type distinguished by URL suffix detection in the new url_detection.go module. Backend: - Add NewWaferQuotaChecker, NewSyntheticQuotaChecker, NewNeuralWattQuotaChecker - Update ProviderQuotaService to register all three providers - Refactor credential check into hasCredentialsForProvider() for API-key-only auth - Add openai channel types to quota check query filter - Add unit tests for URL-based provider detection - Update ent schema and regenerate (add enum values wafer, synthetic, neuralwatt) Frontend: - Add ProviderWaferQuotaData, ProviderSyntheticQuotaData, ProviderNeuralWattQuotaData types - Expand ProviderQuotaChannel discriminated union for providerType variants - Update filter to use providerQuotaStatus != null instead of hardcoded channel types - Add provider-specific quota display in QuotaRow component (progress bars, badges, reset timers)
…ching Add HTTP status code checks to all quota checkers before JSON parsing. Change URL matching from parsed.Host to parsed.Hostname to correctly handle ports (e.g. api.neuralwatt.com:443). Use exact match or dotted-subdomain suffix instead of HasSuffix to prevent false positives like evilwafer.ai matching *wafer.ai. Add zero-KWH exhaustion detection for NeuralWatt.
Show remaining/max credits within the weekly token limit card and display reset timing under each quota section. Add nextRegenAt and nextTickAt fields to ProviderSyntheticQuotaData type.
Provider quota backend now returns float64 for remaining/max on RollingFiveHourLimit. Frontend uses Math.round() to display clean integers in badges.
Backend: - Guard nil KwhRemaining in NeuralWatt quota checker - Add case-insensitive hostname check for Synthetic provider - Simplify Wafer exhausted check; drop unnecessary overage requirement - Validate non-empty prefix in GenerateAPIKey - Remove redundant error handling from concurrent quota check Wait - Regenerate ent schema Frontend: - Fix KWH remaining display fallback when nil - Fix MiMo family alias and add temperature flag - Fix mixed indentation in locale JSON files Docs: - Fix typos in orchestrator comments - Enable GC vacuum by default
Replace separate remaining/credits rows with inline counts.
The quota badges displayed 'Resets in Resets in X days' due to the i18n key prefix being duplicated with the time string. Extracted 'quota.label.resets_in_time' i18n key for the combined translation. Also fixed quota header counts to show (remaining/total) instead of (used/total) for clarity.
Add usedPercent parameter to formatTimeToReset() and check usage before displaying reset text.
Show 'Regenerates in' instead of 'Resets in' for Synthetic regeneration-based quotas (weekly token limit and rolling 5-hour tick limit).
Add regenerates_pct_in_time i18n key and support numeric percent value for formatTimeToReset. Displays e.g. 'Regenerates 2% in 7m' on Synthetic and Rolling Five Hour quota badges.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Code Review
This pull request introduces support for three new quota providers: Wafer, Synthetic, and NeuralWatt. The changes include backend implementations for provider-specific quota checkers, URL-based provider detection for OpenAI-compatible channels, and frontend updates to display detailed usage, limits, and regeneration times. Additionally, the PR optimizes the quota checking process by implementing concurrency with errgroup, adds validation for API key prefixes, and corrects various typos and formatting issues. Review feedback suggests improving error handling for concurrent tasks and ensuring case-insensitive hostname matching in the new checkers.
Reverts unrelated changes that were included in this branch: - config.example.yml: vacuum_enabled default change - orchestrator.go: comment typo fix (applyPassThroughBody) - pass_through.go: comment typo fix (ohter -> other) - en/models.json: indentation fix on association conditions - zh-CN/models.json: same indentation fix - providers.json: mimo family rename and temperature field
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
…tants Replace isXURL functions in wafer/synthetic/neuralwatt checkers with DetectProviderFromURL, eliminating duplicate host-pattern logic that could diverge from urlProviderMap. Add URLDetectedProviders() to url_detection.go so hasCredentialsForProvider no longer hardcodes provider type strings. Extract warning thresholds as named constants: - warningUsedPercent (wafer), warningPercentRemaining (synthetic), warningRemainingFraction (neuralwatt) - syntheticWeeklyRegenTickPct (frontend) Prefix unused kwhRemaining with _ to satisfy ESLint no-unused-vars.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Log context cancellation or group errors instead of silently discarding them.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
There are some lint issues |
Add default case to switch statement to satisfy linter exhaustiveness check. No functional change.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
The exhaustive linter in golangci-lint v2 does not treat default cases as significant, so a switch over channel.Type with only two special cases still fails. An if-statement is the correct construct here since only TypeOpenai/TypeOpenaiResponses need URL-based credential detection.
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Fixed 👍 |
Summary
Add quota monitoring support for Wafer, Synthetic, and NeuralWatt providers via URL-based detection on OpenAI-compatible channels.
Spirit/Intent
Enable operators to track usage limits and quota exhaustion for additional OpenAI-compatible providers alongside existing Claude Code, Codex, GitHub Copilot, and NanoGPT support.
Key Changes
Risks
Testing