mirror of
https://github.com/warpdotdev/warp.git
synced 2026-05-06 15:22:21 +08:00
Update Git Operations AI client billing policy (#9840)
## Description Adds the client-side follow-up for the Git Operations AI enterprise/tier policy: - Adds `isGitOperationsAiEnabled` to the client GraphQL schema and `WarpAiPolicy` fragments/models. - Converts the new policy into the app-level workspace billing model. - Gates Git Operations AI requests and the “Commit & Pull Request Generation” setting on the billing policy instead of the previous hardcoded enterprise client gate. - Removes the stale TODO that asked for this client-side gate. This is intended to pair with the server-side schema/policy change in warpdotdev/warp-server#10798. Keeping this PR as draft until the server field is available to clients. ## Linked Issue N/A — client follow-up for the server GraphQL schema/policy PR. ## Screenshots / Videos N/A — this is policy/schema wiring. The existing setting is hidden when the new billing policy disables Git Operations AI. ## Testing - `cargo fmt --manifest-path /Users/edward/Repos/edward-update-git-ops-ai-schema/Cargo.toml --all -- --check` - `cargo clippy --manifest-path /Users/edward/Repos/edward-update-git-ops-ai-schema/Cargo.toml -p warp_graphql_schema -p warp_graphql -p warp --all-targets --all-features --tests -- -D warnings` - `git --no-pager diff --check` No new integration test added; this is a small billing-policy plumbing change that reuses existing settings/request gates. ## Agent Mode - [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode Agent conversation: https://staging.warp.dev/conversation/281d784d-6c87-414f-89db-1b29f771f571 Co-Authored-By: Oz <oz-agent@warp.dev> --------- Co-authored-by: Oz <oz-agent@warp.dev> Co-authored-by: MaggieShan <sshan.maggie@gmail.com>
This commit is contained in:
@@ -1,8 +1 @@
|
||||
// TODO(edward): follow-up — gate callers of this module on both
|
||||
// 1. an `AISettings` opt-out (mirror `is_shared_block_title_generation_enabled`), and
|
||||
// 2. a customer-type guard (exclude Enterprise unless Warp plan / dogfood),
|
||||
// matching the pattern in `terminal/share_block_modal.rs::should_send_title_gen_request`.
|
||||
// `FeatureFlag::GitOperationsInCodeReview` already gates the surrounding UI,
|
||||
// but does not address AI-specific privacy / opt-out concerns for sending
|
||||
// diffs to an LLM.
|
||||
pub(crate) mod api;
|
||||
|
||||
@@ -134,8 +134,7 @@ fn show_toast(msg: impl Into<String>, ctx: &mut ViewContext<GitDialog>) {
|
||||
///
|
||||
/// Folds the parent feature flag, the user's dedicated per-feature AI toggle
|
||||
/// (which itself requires active AI / auth / remote-session org policy to
|
||||
/// allow AI), and an enterprise check with the same Warp-plan exception and
|
||||
/// dogfood override as `share_block_modal.rs::should_send_title_gen_request`.
|
||||
/// allow AI), and the current team's Git Operations AI tier policy.
|
||||
///
|
||||
/// When this returns `false`, call sites skip AI entirely: commit.rs opens
|
||||
/// with the manual-type placeholder and pr.rs goes straight to
|
||||
@@ -143,7 +142,7 @@ fn show_toast(msg: impl Into<String>, ctx: &mut ViewContext<GitDialog>) {
|
||||
fn should_send_git_ops_ai_request(app: &AppContext) -> bool {
|
||||
FeatureFlag::GitOperationsInCodeReview.is_enabled()
|
||||
&& AISettings::as_ref(app).is_git_operations_autogen_enabled(app)
|
||||
&& UserWorkspaces::as_ref(app).ai_allowed_for_current_team()
|
||||
&& UserWorkspaces::as_ref(app).is_git_operations_ai_enabled()
|
||||
}
|
||||
|
||||
/// Maps a raw git error string to a user-friendly toast message. Known
|
||||
|
||||
@@ -2454,6 +2454,9 @@ impl TypedActionView for AISettingsPageView {
|
||||
ctx.notify();
|
||||
}
|
||||
AISettingsPageAction::ToggleGitOperationsAutogen => {
|
||||
if !UserWorkspaces::as_ref(ctx).is_git_operations_ai_enabled() {
|
||||
return;
|
||||
}
|
||||
match AISettings::handle(ctx).update(ctx, |settings, ctx| {
|
||||
settings
|
||||
.git_operations_autogen_enabled_internal
|
||||
@@ -3726,7 +3729,7 @@ impl ActiveAIWidget {
|
||||
&& AISettings::as_ref(app)
|
||||
.git_operations_autogen_enabled_internal
|
||||
.is_supported_on_current_platform()
|
||||
&& UserWorkspaces::as_ref(app).ai_allowed_for_current_team()
|
||||
&& UserWorkspaces::as_ref(app).is_git_operations_ai_enabled()
|
||||
}
|
||||
|
||||
fn render_next_command_section(
|
||||
|
||||
@@ -174,6 +174,7 @@ impl From<GqlWarpAiPolicy> for WarpAiPolicy {
|
||||
is_code_suggestions_toggleable: gql_warp_ai_policy.is_code_suggestions_toggleable,
|
||||
is_prompt_suggestions_toggleable: gql_warp_ai_policy.is_prompt_suggestions_toggleable,
|
||||
is_next_command_enabled: gql_warp_ai_policy.is_next_command_enabled,
|
||||
is_git_operations_ai_enabled: gql_warp_ai_policy.is_git_operations_ai_enabled,
|
||||
is_voice_enabled: gql_warp_ai_policy.is_voice_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ impl UserWorkspaces {
|
||||
/// Returns `true` if active AI is allowed for the current workspace, based on billing config.
|
||||
///
|
||||
/// In the future, we should store active AI enablement on the policy directly. For now, we
|
||||
/// proxy whether active AI by checking if prompt suggestions, next command, or code suggestions are enabled.
|
||||
/// proxy whether active AI by checking whether any active AI feature is enabled.
|
||||
pub fn is_active_ai_allowed(&self) -> bool {
|
||||
self.current_team().is_none_or(|team| {
|
||||
team.billing_metadata
|
||||
@@ -397,6 +397,7 @@ impl UserWorkspaces {
|
||||
policy.is_prompt_suggestions_toggleable
|
||||
|| policy.is_next_command_enabled
|
||||
|| policy.is_code_suggestions_toggleable
|
||||
|| policy.is_git_operations_ai_enabled
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -454,6 +455,19 @@ impl UserWorkspaces {
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether Git Operations AI is enabled for the current user, based on the active policies.
|
||||
/// Note that the value may be incorrect if called before the team's billing metadata has been fetched.
|
||||
pub fn is_git_operations_ai_enabled(&self) -> bool {
|
||||
self.current_team()
|
||||
// If the user has no team, they can toggle Git Operations AI (no restrictions).
|
||||
.is_none_or(|team| {
|
||||
team.billing_metadata
|
||||
.tier
|
||||
.warp_ai_policy
|
||||
.is_some_and(|policy| policy.is_git_operations_ai_enabled)
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether voice input should be toggleable for the current user, based on the active policies.
|
||||
/// Note that the value may be incorrect if called before the team's billing metadata has been fetched.
|
||||
/// If voice input support is not compiled into this build, always returns `false`.
|
||||
|
||||
@@ -292,6 +292,7 @@ pub struct WarpAiPolicy {
|
||||
pub is_code_suggestions_toggleable: bool,
|
||||
pub is_prompt_suggestions_toggleable: bool,
|
||||
pub is_next_command_enabled: bool,
|
||||
pub is_git_operations_ai_enabled: bool,
|
||||
pub is_voice_enabled: bool,
|
||||
}
|
||||
#[derive(Clone, Debug, Copy, Serialize, Deserialize)]
|
||||
|
||||
@@ -147,6 +147,7 @@ pub struct WarpAiPolicy {
|
||||
pub is_code_suggestions_toggleable: bool,
|
||||
pub is_prompt_suggestions_toggleable: bool,
|
||||
pub is_next_command_enabled: bool,
|
||||
pub is_git_operations_ai_enabled: bool,
|
||||
pub is_voice_enabled: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ mutation CreateTeam($input: CreateTeamInput!, $request_context: RequestContext!)
|
||||
isCodeSuggestionsToggleable
|
||||
isPromptSuggestionsToggleable
|
||||
isNextCommandEnabled
|
||||
isGitOperationsAiEnabled
|
||||
isVoiceEnabled
|
||||
}
|
||||
teamSizePolicy {
|
||||
|
||||
@@ -36,6 +36,7 @@ query GetWorkspacesMetadataForUser($requestContext: RequestContext!) {
|
||||
isCodeSuggestionsToggleable
|
||||
isPromptSuggestionsToggleable
|
||||
isNextCommandEnabled
|
||||
isGitOperationsAiEnabled
|
||||
isVoiceEnabled
|
||||
}
|
||||
teamSizePolicy {
|
||||
|
||||
@@ -3967,6 +3967,7 @@ type WarpAiPolicy {
|
||||
acceptedAutosuggestionsLimit: Int!
|
||||
disablePremiumModels: Boolean!
|
||||
isCodeSuggestionsToggleable: Boolean!
|
||||
isGitOperationsAiEnabled: Boolean!
|
||||
isNextCommandEnabled: Boolean!
|
||||
isPromptSuggestionsToggleable: Boolean!
|
||||
isUnlimited: Boolean!
|
||||
|
||||
Reference in New Issue
Block a user