Skip to content

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

Open
warp-agent-staging[bot] wants to merge 8 commits into
masterfrom
factory/rev-1714-server-authoritative-credit-availability
Open

[REV-1714] Use server-authoritative AI credit availability in the client#14634
warp-agent-staging[bot] wants to merge 8 commits into
masterfrom
factory/rev-1714-server-authoritative-credit-availability

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Supersedes #14352 with its conflicts resolved against current master.

Consumes the server-authoritative User.aiCreditAvailability GraphQL field (warp-server #12935 / #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 (merged): shared inference-admission and availability semantics.
  • 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 Telugu (and other Indic-script) terminal output renders with wrong cell widths — squeezed/overlapping/torn text #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.

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.

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:

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.

This PR was generated with Oz.

jefflloyd and others added 6 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>
…rver-authoritative-credit-availability

# Conflicts:
#	app/src/workspaces/gql_convert.rs
#	app/src/workspaces/update_manager.rs
#	app/src/workspaces/update_manager_tests.rs
#	app/src/workspaces/user_workspaces.rs
#	app/src/workspaces/user_workspaces_tests.rs
#	crates/graphql/src/api/queries/get_workspaces_metadata_for_user.rs
Master added user-level purchase-policy tests (constructing GqlUser and
driving on_workspaces_updated) and provider-credential telemetry on
ApiKeyManager::set_provider_key. After merging the server-authoritative
credit-availability change, those test paths now exercise the availability
apply path and telemetry, so register the required singletons in the
affected test harnesses and add the new ai_credit_availability field to the
gql_user helper.

Co-Authored-By: Oz <oz-agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Aug 2, 2026
@warp-agent-staging
warp-agent-staging Bot marked this pull request as ready for review August 2, 2026 15:07
@warp-agent-staging
warp-agent-staging Bot requested a review from jefflloyd August 2, 2026 15:07
oz-agent and others added 2 commits August 2, 2026 15:50
The transcript render path now reads AIRequestUsageModel::has_any_ai_remaining
(server-authoritative availability), which panicked in transcript_tests because
the harness never registered that singleton (nor its AuthStateProvider /
ServerApiProvider deps). Production always registers AIRequestUsageModel during
app init (app/src/lib.rs), so no production path can hit this; register the
singleton (and deps) in the shared transcript-test app builder.

Co-Authored-By: Oz <oz-agent@warp.dev>
Drive the banner from the server-authoritative availability decision and
refresh it when that decision changes. Rename the legacy request-limit
helper to make its base-plan-only semantics explicit while preserving
the few quota-specific consumers.

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.

2 participants