- Show resets held (sum of resets_left) on the count button, matching the
Codex count; flag "not usable now" when none is redeemable yet, instead
of showing 0 while a grant exists.
- Pick the redeemable (next) grant for the expiry chip, falling back to
the earliest expiry, rather than assuming credits[0] is next.
- Render a single ClaudeResetCreditsCell across usage states so a query
started while usage loads is not lost on remount.
- Drop an unrelated google/subcommands go.sum entry.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Claude reset credit query rendered as a bare "Claude 重置额度" link,
which reads like a redeem action, and dumped raw ISO timestamps and
window keys. Render it like OpenAIQuotaResetCell instead: a read-only
"次数 N" button sharing one row with the local query button via a
#pre-actions slot, plus an expiry chip whose tooltip carries the grant
label, cleared windows and limit requirement.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- only consult account mappings after primary/channel candidates fail to price (or composite)
- source mappings from the scheduler snapshot (same pool as account selection), no direct DB query and no per-model cache
- ungrouped API keys use the scheduler's ungrouped pool
- no negative caching: new mappings take effect on the next request
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Inflight estimate now mirrors billableModelWithFallback: when the primary
billing model has no price, fall back to the channel-mapped model (also for
billing_model_source=requested) and to account-level mapped models (max over
schedulable accounts in the group, cached 30s).
- Composite groups also consider concrete account-mapped models (max) so the
alias' family fuzzy price cannot underestimate.
- Renew Lua refuses (and purges) members whose score <= now.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Address gaps found in adversarial verification of the in-flight balance
reservation:
- Early release: the reservation is now a ref-counted handle carried on the
request context. Billing tasks submitted via submit*UsageRecordTask take a
ref and return it only after RecordUsage has run; with reservation enabled
the balance cache is deducted synchronously inside the billing task, so the
reservation is released only after admission can see the deduction. Dropped
tasks return their ref immediately. The reservation is renewed every ttl/3
while the handler runs; after the handler returns it is no longer renewed,
so the post-handler hold is bounded by one TTL.
- Estimate: use the same billing model (channel mapping + BillingModelSource,
max over requested/mapped when ambiguous) and ModelPricingResolver (group
ModelPricing incl. wildcards, channel per_request/image/video/token
overrides), default/group/user rate + peak multiplier, plus image, video,
audio and search surcharge kinds. Unpriced requests fail open with a
throttled log; new billing.inflight_reservation.fail_closed_on_unpriced
(default false) rejects them instead.
- Wire images, embeddings, web/x search, alpha search, grok media generation,
grok realtime/voice, OpenAI-platform /v1/messages and ResponsesWebSocket
(session-level reservation with renewal).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Balance-mode admission only checked cached balance > threshold, so N
concurrent expensive requests could all pass and overdraw the user.
Add a Redis in-flight reservation: at admission estimate a conservative
per-request cost (input estimate + output price x max_tokens, times rate
multiplier) and atomically require cached_balance - inflight >= estimate
(first in-flight request always admitted). Reservations are released via
defer on every path and expire by TTL. Fails open on estimation / Redis
errors. Configurable via billing.inflight_reservation (enabled by default).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Verification code attempts (register + notify email) are now reserved via
an atomic Redis INCR (Lua) before comparing, so concurrent wrong guesses
cannot exceed the 5-attempt cap.
- Password reset tokens are stored as SHA-256 hashes and consumed with an
atomic Lua compare-and-delete, so a token can only be used once even under
concurrent requests.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The antigravity Gemini forward path returned the raw upstream Google error
body to end users, which can contain consumer project numbers, GCP project
IDs and service account emails. Return a Gemini-style error body with only
code/status and a scrubbed message; raw body stays in ops logging.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
POST /api/v1/payment/public/orders/verify is unauthenticated and still used
by PaymentResultView as a fallback, so keep it but cap it at 20 req/min per
client IP (fail-open on Redis errors) to make out_trade_no enumeration
impractical without affecting users mid-payment.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hosted image_generation tool is OpenAI-only. With the global switch or
a channel's openai bridge flag enabled, isCodexImageGenerationBridgeEnabled
also returned true for Kimi / DeepSeek / MiniMax accounts that forward
natively over Responses, so their upstream requests carried the tool,
tool_choice and the bridge instructions and were rejected with 400.
Return false for nil and non-OpenAI accounts before evaluating the
account / channel / global settings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>