Skip to content

[REV-1714] Use server-authoritative AI credit availability in the client - #14352

Draft
jefflloyd wants to merge 4 commits into
masterfrom
jlloyd/rev-1714-server-authoritative-credit-availability
Draft

[REV-1714] Use server-authoritative AI credit availability in the client#14352
jefflloyd wants to merge 4 commits into
masterfrom
jlloyd/rev-1714-server-authoritative-credit-availability

Conversation

@jefflloyd

@jefflloyd jefflloyd commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Description

Consumes the server-authoritative User.aiCreditAvailability GraphQL 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:

  • GraphQL: mirrors the AICreditAvailability types into the client schema, adds cynic bindings (with fallback variants for unknown future enum values), a focused GetAICreditAvailability query, and piggybacks the selection onto GetWorkspacesMetadataForUser so every metadata refresh carries the decision.
  • Shared state: AIRequestUsageModel holds the server decision with last-known-good semantics — refresh failures never flip availability in either direction, and the legacy locally derived has_any_ai_remaining calculation only applies before the first successful fetch (rollout compatibility with servers lacking the field).
  • Feed paths (exactly two, per spec): the workspace metadata refresh piggyback (primary cadence, including all team mutations which re-query metadata), plus coalesced single-shot targeted fetches on meaningful state changes: auth completion, API-key/credential changes, workspace selection changes, and add-on credit/overage changes. No fixed-interval timer, no AI-surface-open or request-completion triggers. State resets on logout.
  • Consumers: prompt alerts map server denial reasons (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 of num_remaining_reqs; Agent Mode input, prompt suggestions, and code review inherit it via has_any_ai_remaining. Request-limit counts remain display-only.
  • Local-key refinement: per the reworked server contract, available=true means the server knows for a fact requests can run (a Warp credit source or a configured server-managed BYO path) and is trusted outright. An OUT_OF_CREDITS denial 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 AdmitsInference decision for the request middleware and the availability endpoint, with available reporting only definite access. The server change must deploy before this client change ships — against the original endpoint semantics, available=true was 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 --check and both presubmit clippy invocations — passed.

  • I have manually tested my changes locally with ./script/run

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent 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.

@cla-bot cla-bot Bot added the cla-signed label Jul 27, 2026
jefflloyd and others added 4 commits July 30, 2026 10:51
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
jefflloyd force-pushed the jlloyd/rev-1714-server-authoritative-credit-availability branch from f8735c5 to 97a665a Compare July 30, 2026 15:27
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

![The Warp OSS client rendered a terminal UI with a "bash" tab, top bar
icons, black terminal area, and a command input prompt at the bottom
showing a "~" home directory indicator and a blinking
cursor.](https://staging.warp.dev/api/v1/agent/artifacts/019fc300-9e89-7554-a02d-6cbdb75b84a2/download)
<!-- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant