[REV-1714] Use server-authoritative AI credit availability in the client - #14352
Draft
jefflloyd wants to merge 4 commits into
Draft
[REV-1714] Use server-authoritative AI credit availability in the client#14352jefflloyd wants to merge 4 commits into
jefflloyd wants to merge 4 commits into
Conversation
Consume the new User.aiCreditAvailability GraphQL field (warp-server - Mirror the AICreditAvailability schema types and add cynic bindings, a focused GetAICreditAvailability query, and a piggybacked selection on the workspace metadata query. - Hold the shared server decision on AIRequestUsageModel with last-known-good semantics on refresh failures; has_any_ai_remaining now returns the server decision once one exists and only falls back to the legacy local derivation before the first successful fetch. - Feed the state from exactly two paths: the workspace metadata refresh piggyback and coalesced targeted fetches on auth completion, API-key/credential changes, workspace selection changes, and add-on credit/overage changes. Reset on logout. - Map server denial reasons to prompt alert presentation and gate the AI Assistant zero-state/prepared prompts on the shared availability. Co-Authored-By: Oz <oz-agent@warp.dev>
…out of credits The server reports BYO capability at the policy level because personal API keys are stored only on the client. Since nearly every tier allows BYOK, capability-only availability (available with no credit source) would otherwise suppress out-of-credits messaging for everyone. Pair the server's capability-only answer with the one fact only the client knows: whether a usable BYO path actually exists (a stored key/custom endpoint/Grok subscription permitted by policy, or a team-managed custom LLM). Without one, capability-only availability is treated as out of credits for gating and prompt-alert presentation. An explicit server denial is never overridden by local key presence. Pairs with the server-side denial precedence fix in warpdotdev/warp-server#13369. Co-Authored-By: Oz <oz-agent@warp.dev>
…with local keys Follows the server-side semantics rework (warp-server#13369): available now means the server knows for a fact requests can run (a Warp credit source or a configured server-managed BYO path), so the client trusts it outright. An OUT_OF_CREDITS denial means the server found no path it can see - locally stored API keys are request-level parameters invisible to it - so the client supplies that one fact and permits AI when a usable local key exists (policy permitting). Delinquency and spend-limit denials are hard rejections that local keys never bypass. The team-custom-LLM client check is dropped: server-managed BYO paths are now reflected directly in the server's availability decision. Co-Authored-By: Oz <oz-agent@warp.dev>
The server now only vouches for BYO configs it can operate itself, so Bedrock local-chain setups (region-only, credentials resolved on the client) surface as OUT_OF_CREDITS. Refine that denial locally by treating loaded AWS credentials with Bedrock enabled as a usable inference path. Co-Authored-By: Oz <oz-agent@warp.dev>
jefflloyd
force-pushed
the
jlloyd/rev-1714-server-authoritative-credit-availability
branch
from
July 30, 2026 15:27
f8735c5 to
97a665a
Compare
jefflloyd
added a commit
that referenced
this pull request
Aug 3, 2026
…ent (#14634) ## Summary Supersedes #14352 with its conflicts resolved against current `master`. Consumes the server-authoritative `User.aiCreditAvailability` GraphQL field (warp-server [#12935](warpdotdev/warp-server#12935) / [#13369](warpdotdev/warp-server#13369)) so the client no longer infers overall AI availability from stale request limits, grants, or workspace metadata. `AIRequestUsageModel` holds the server decision with last-known-good semantics. Prompt alerts, the buy-credits banner, AI Assistant, Agent Mode, and code review use the shared availability. An `OUT_OF_CREDITS` denial is refined by usable local API keys or loaded local-chain Bedrock credentials when policy permits; delinquency and spend-limit denials are hard rejections. ## Client behavior - Mirrors `AICreditAvailability` GraphQL types with forward-compatible unknown enum handling. - Receives availability through workspace metadata and coalesced targeted refreshes after auth, credential, workspace, add-on credit, and overage changes. - Resets availability on logout and keeps the last successful decision across transient refresh failures. - Maps delinquency and enterprise spend-limit reasons to existing presentation states. - Uses authoritative availability for the buy-credits banner and re-renders it on `CreditAvailabilityUpdated`. - Renames the legacy helper to `has_base_plan_requests_remaining()` and narrows it to `pub(crate)`. Its remaining consumers are intentionally base-quota-specific: anonymous request-limit gates, overage refresh heuristics, default-model-switch presentation, and the pre-fetch fallback. ## Server dependency Requires: - [warp-server#13369](warpdotdev/warp-server#13369) (merged): shared inference-admission and availability semantics. - [warp-server#13719](warpdotdev/warp-server#13719): direct-federation Gemini Enterprise availability and post-model GEAP/Bedrock credential recognition. The server follow-up must deploy before this client change ships. Without it, a valid direct-federation Gemini Enterprise configuration can be reported as out of credits, or the client can be enabled and then receive an out-of-credits response when submitting. ## Conflict resolution Merged `origin/master` into the source branch. Six files conflicted, all mechanical "both sides added a field / test" collisions between this change (`ai_credit_availability`) and master's user-level add-on-credits purchase policy (`user_purchase_policy`)—both were kept: - `app/src/workspaces/user_workspaces.rs` - `app/src/workspaces/gql_convert.rs` - `app/src/workspaces/update_manager.rs` - `crates/graphql/src/api/queries/get_workspaces_metadata_for_user.rs` - `app/src/workspaces/update_manager_tests.rs` - `app/src/workspaces/user_workspaces_tests.rs` Master's new `gql_user` helper was extended with `ai_credit_availability`, and affected workspace test harnesses register the telemetry and request-usage models required by the combined changes. ## Verification - `cargo nextest run -p warp -E 'test(request_usage_model) + test(prompt_alert)' --no-fail-fast` — 56 passed. - `cargo nextest run -p warp -E 'test(credit_availability) + test(request_usage_model) + test(prompt_alert) + test(update_manager) + test(user_workspaces)'` — 171 passed after the master merge. - `cargo nextest run -p warp_graphql` — 7 passed. - `./script/format` - `cargo clippy -p warp --all-targets --tests -- -D warnings` - `cargo clippy --workspace --exclude warp_completer --all-targets --tests -- -D warnings` ## Manual decision-matrix validation Validated with the client connected to a live local warp-server while forcing only the `aiCreditAvailability` resolver response. Request middleware and admission logic remained production-identical. - **Warp credits available, no local BYO:** no prompt restriction, no buy-credits banner, normal model controls. - **No credits or BYO:** buy-credits banner and composer out-of-credits state shown with the expected add-credits CTA. - **OUT_OF_CREDITS + local API key:** both restrictions disappear; a real request succeeds through the production admission path. - **OUT_OF_CREDITS + local-chain Bedrock:** restrictions remain before `aws login`; after credentials load, both disappear. - **Server-managed availability (`available=true`, null credit source):** trusted without local credentials. - **DELINQUENT + local key:** remains blocked with "Restricted due to payment issue." - **Enterprise spend limit + local key:** remains blocked with the spend-limit presentation. The first live case exposed that the buy-credits banner still used base request counts even though the composer used authoritative availability. This PR now drives both from the same decision and includes focused banner coverage. ## Gemini Enterprise end-to-end control Using the real production resolver and an enterprise direct-federation Gemini configuration: 1. Removed Warp inference credit sources while keeping Gemini configured. 2. Reproduced the out-of-credits availability mismatch. 3. Applied server PR #13719; the client restriction disappeared. 4. Reproduced and fixed the downstream request credit guard; the Gemini request succeeded. 5. Restored WARP_PLAN and repeated the request: provider-inference cost remained zero and the local Oz task recorded 0.250051 platform credits (displayed as 0.3), confirming customer-inference billing. <!-- oz:computer-use-screenshots start --> ### Computer-use screenshots  <!-- oz:computer-use-screenshots end --> Originating thread: https://warp-dev.slack.com/archives/C0BDQDW8V5E/p1785680392740989 _Conversation: https://staging.warp.dev/conversation/e786e128-f77e-4ff6-9a41-528e9eb60953_ _Run: https://oz.staging.warp.dev/runs/019fc2e3-2949-72e9-808f-7f6e05af09e9_ _Plans:_ - _[Client: server-authoritative AI credit availability (REV-1714)](https://staging.warp.dev/drive/notebook/CuLVyr2mh4mGV0EVEQzBqP)_ Co-Authored-By: Oz <oz-agent@warp.dev> CHANGELOG-IMPROVEMENT: Out-of-credits, delinquency, and spend-limit states across AI surfaces now reflect the server's authoritative credit availability, so they stay accurate as your plan, credits, or API keys change. <!-- factory-agent: {"source":"factory-agent","task_id":"REV-1714","task_source":"linear","task_url":"https://linear.app/warpdotdev/issue/REV-1714/add-gql-api-endpoint-for-server-authoritative-credit-availability","linear_issue_id":"REV-1714","oz_run_id":"019fc2e3-2949-72e9-808f-7f6e05af09e9","repo":"warpdotdev/warp","review_rework_attempts":1,"ci_fix_attempts":1} --> _This PR was generated with [Oz](https://warp.dev/oz)._ --------- Co-authored-by: Jeff Lloyd <jeff@warp.dev> Co-authored-by: Oz <oz-agent@warp.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Consumes the server-authoritative
User.aiCreditAvailabilityGraphQL field (added in warp-server#12935) so Warp clients no longer infer AI availability from stale request limits, grants, workspace metadata, or local BYO settings. Implements the "Proposed client changes" section of the REV-1714 spec (warp-server/agents/specs/REV-1714: server-authoritative credit availability.md).What / How:
AICreditAvailabilitytypes into the client schema, adds cynic bindings (with fallback variants for unknown future enum values), a focusedGetAICreditAvailabilityquery, and piggybacks the selection ontoGetWorkspacesMetadataForUserso every metadata refresh carries the decision.AIRequestUsageModelholds the server decision with last-known-good semantics — refresh failures never flip availability in either direction, and the legacy locally derivedhas_any_ai_remainingcalculation only applies before the first successful fetch (rollout compatibility with servers lacking the field).DELINQUENT, enterprise spend limits,OUT_OF_CREDITS) to existing presentation states — workspace policy only picks CTA copy; AI Assistant zero-state/prepared prompts gate on the shared availability instead ofnum_remaining_reqs; Agent Mode input, prompt suggestions, and code review inherit it viahas_any_ai_remaining. Request-limit counts remain display-only.available=truemeans the server knows for a fact requests can run (a Warp credit source or a configured server-managed BYO path) and is trusted outright. AnOUT_OF_CREDITSdenial means the server found no path it can see — locally stored API keys and locally resolved Bedrock credentials are request-level parameters invisible to it — so the client supplies that one fact and permits AI when a usable local key/custom endpoint/Grok subscription/loaded local-chain Bedrock credentials exist (policy permitting). Delinquency and spend-limit denials are hard rejections that local keys never bypass.Depends on warp-server#13369 (now merged), which defines this contract: one shared
AdmitsInferencedecision for the request middleware and the availability endpoint, withavailablereporting only definite access. The server change must deploy before this client change ships — against the original endpoint semantics,available=truewas near-universal (BYOK capability on every tier) and would suppress out-of-credits/delinquency alerts.Linked Issue
Linear: REV-1714 (client-side follow-up to the server endpoint).
Testing
New unit tests: gql→domain conversions (every reason/source + unknown-value tolerance), server-decision-overrides-local, last-known-good on transient failure, no legacy fallback after first success, legacy fallback before first success, targeted-fetch coalescing (exactly one in-flight request), logged-out no-op, logout reset, metadata piggyback feed, and prompt-alert mapping for each server reason.
Local-key refinement tests: OUT_OF_CREDITS + no local key → gated (model + prompt alert); OUT_OF_CREDITS + stored key → available/no alert; OUT_OF_CREDITS + loaded local-chain Bedrock credentials (Bedrock enabled by policy) → available; server-managed availability (
available, null source) trusted without local keys; hard denials (delinquency) never overridden by a local key.cargo nextest run -p warp -E 'test(credit_availability) + test(request_usage_model) + test(prompt_alert) + test(update_manager) + test(user_workspaces)'— 142 passed.cargo nextest run -p warp_graphql— passed../script/format --checkand both presubmit clippy invocations — passed.I have manually tested my changes locally with
./script/runAgent Mode
Co-Authored-By: Oz oz-agent@warp.dev
CHANGELOG-IMPROVEMENT: Out-of-credits, delinquency, and spend-limit states across AI surfaces now reflect the server's authoritative credit availability, so they stay accurate as your plan, credits, or API keys change.