- 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>
MALFORMED_FUNCTION_CALL responses from upstream contain only
thoughtSignature without any text, thinking, or tool calls.
The previous fix still treated delta.Signature and block.Signature
as meaningful data, so the empty-stream failover was never triggered.
- Remove Signature from isMeaningfulAntigravityCompatEvent checks
- Let hasMeaningfulData() also consult processor.HasContent() as
a secondary guard for edge cases
RecordUsage treats a missing price as zero cost on the first pass, but
the Free Fast Standard re-evaluation returned the same pricing error.
Requests in a free_openai_fast group sent at priority/fast tier to a
model without pricing therefore lost their usage log entirely.
Ignore pricing-unavailable errors on the Standard pass and keep the
zero-cost entry, matching the first pass.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With the credit config now visible to the scheduler, every scheduling pass
notifies the auto-reset worker for paused credit-enabled accounts.
evaluateAccount forced an upstream query whenever the reset threshold was
reached, regardless of the last result. Accounts with no credits left and
7d >= 95% were therefore polled on /wham/usage every ~15-20s across
instances (previously once a minute by the scanner), and during upstream
outages the failed state caused the same storm.
- At the reset threshold, skip the forced query while a no_credit result is
still within the state TTL (10 min); re-query once it expires so newly
granted credits are still picked up.
- After a query-stage failure (RESET_CREDIT_QUERY_FAILED,
USAGE_SNAPSHOT_WRITE_FAILED, RESET_CREDIT_DETAILS_UNAVAILABLE), wait one
minute before querying again, including snapshot-staleness triggers.
- Redemption-stage failures are unaffected and still retry immediately with
the same idempotency key; accounts with available credits still query and
redeem immediately.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>