Upstream returns 400 INVALID_ARGUMENT when toolConfig is absent. The guard
`if !isReasoning || len(tools) > 0` skipped it for reasoning models called
without tools, contradicting the intent stated in the comment above it.
Set toolConfig unconditionally and cover the three cases with a unit test.
Payment and admin fulfillment shared the public Redeem entry point, so
fulfillment retries were blocked by, and contributed to, the user's
public redeem failure counter, and lookup errors were silently treated as
"code does not exist" on a partial re-run.
- resolveRedeemAction now distinguishes a genuine not-found lookup from
other lookup errors (which now fail the fulfillment instead of being
swallowed and re-created).
- Add validatePaymentRedeemCode: before reusing an existing code during
fulfillment, verify it belongs to the order (code id, balance type,
amount, user, status), so a stale or foreign code can never be
credited against the wrong order/user.
- Split Redeem into a policy-based core: public redemption enforces the
failure counter; payment fulfillment (redeemForPaymentFulfillment) and
admin fulfillment (RedeemForAdminFulfillment) bypass it, while all code
validation and transactional updates remain identical. Admin
fulfillment keeps the normal redeem-level affiliate rebate.
- The admin CreateAndRedeem endpoint now uses RedeemForAdminFulfillment.
Tests: updated resolveRedeemAction cases, new TestValidatePaymentRedeemCode,
code-used-by-another-user rejection, payment/admin rate-limit bypass
coverage, and public-path regression coverage.
The Antigravity native Gemini route (generateContent) expects each
contents entry to carry an explicit "user" role, matching the request
shape used by the established Antigravity account-test flow. Without it
the probe body is rejected with 400 INVALID_ARGUMENT, so Gemini channel
monitors report false failures.
Add the explicit role to the Gemini provider adapter body and cover it
with a regression test that parses the generated request body.
The Antigravity service fingerprints clients by the version embedded in the User-Agent header. The built-in default (1.23.2) had drifted far behind current real client builds, so requests using the default UA started failing OAuth and probe flows.
Bump DefaultUserAgentVersion from 1.23.2 to 2.9.1 (current client build) and update the constant test accordingly. The default remains overridable via ANTIGRAVITY_USER_AGENT_VERSION and the admin setting.
The Grok cross-client model mapping is enabled by default: InitializeDefaultSettings writes "true", and the parser treats a missing/empty value as enabled ("Default true (missing/empty -> enabled)"). However the comment above the defaults and the admin settings UI hint (EN and ZH) both claimed "disabled by default", contradicting the actual behavior.
Align the comment and both UI hints with the real default. No behavior change.
Cyber-policy detection only inspected response.failed, and the ingress check ran after error-specific early returns. As a result, error-shaped failures and the connection-pool, HTTP-bridge, and WSv2 paths could miss cyber-policy hits.
Centralize event marking and invoke it before retry and failover returns across the WebSocket implementations. Preserve the recorded guard during account failover and defer connection blocking until the logical failover chain completes, avoiding duplicate records while ensuring subsequent turns are blocked.