This removes the `gemini-and-native` and `claude-code` feature flags. Also, I removed a bunch of unused agent1 code that we do not need anymore. Initially I wanted to remove much more of the `agent` code, but noticed some things that we need to figure out first: - The inline assistant + context strip use `Thread`/`ContextStore` directly - We need some replacement for `ToolWorkingSet`, so we can access available tools (as well as context server tools) in other places, e.g. the agent configuration and the configure profile modal Release Notes: - N/A
201 lines
7.0 KiB
Rust
201 lines
7.0 KiB
Rust
use client::{ModelRequestUsage, RequestUsage, zed_urls};
|
|
use cloud_llm_client::{Plan, PlanV1, PlanV2, UsageLimit};
|
|
use component::{empty_example, example_group_with_title, single_example};
|
|
use gpui::{AnyElement, App, IntoElement, RenderOnce, Window};
|
|
use ui::{Callout, prelude::*};
|
|
|
|
#[derive(IntoElement, RegisterComponent)]
|
|
pub struct UsageCallout {
|
|
plan: Plan,
|
|
usage: ModelRequestUsage,
|
|
}
|
|
|
|
impl UsageCallout {
|
|
pub fn new(plan: Plan, usage: ModelRequestUsage) -> Self {
|
|
Self { plan, usage }
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for UsageCallout {
|
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
|
let (is_limit_reached, is_approaching_limit, remaining) = match self.usage.limit {
|
|
UsageLimit::Limited(limit) => {
|
|
let percentage = self.usage.amount as f32 / limit as f32;
|
|
let is_limit_reached = percentage >= 1.0;
|
|
let is_near_limit = percentage >= 0.9 && percentage < 1.0;
|
|
(
|
|
is_limit_reached,
|
|
is_near_limit,
|
|
limit.saturating_sub(self.usage.amount),
|
|
)
|
|
}
|
|
UsageLimit::Unlimited => (false, false, 0),
|
|
};
|
|
|
|
if !is_limit_reached && !is_approaching_limit {
|
|
return div().into_any_element();
|
|
}
|
|
|
|
let (title, message, button_text, url) = if is_limit_reached {
|
|
match self.plan {
|
|
Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree) => (
|
|
"Out of free prompts",
|
|
"Upgrade to continue, wait for the next reset, or switch to API key."
|
|
.to_string(),
|
|
"Upgrade",
|
|
zed_urls::account_url(cx),
|
|
),
|
|
Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial) => (
|
|
"Out of trial prompts",
|
|
"Upgrade to Zed Pro to continue, or switch to API key.".to_string(),
|
|
"Upgrade",
|
|
zed_urls::account_url(cx),
|
|
),
|
|
Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro) => (
|
|
"Out of included prompts",
|
|
"Enable usage-based billing to continue.".to_string(),
|
|
"Manage",
|
|
zed_urls::account_url(cx),
|
|
),
|
|
}
|
|
} else {
|
|
match self.plan {
|
|
Plan::V1(PlanV1::ZedFree) => (
|
|
"Reaching free plan limit soon",
|
|
format!(
|
|
"{remaining} remaining - Upgrade to increase limit, or switch providers",
|
|
),
|
|
"Upgrade",
|
|
zed_urls::account_url(cx),
|
|
),
|
|
Plan::V1(PlanV1::ZedProTrial) => (
|
|
"Reaching trial limit soon",
|
|
format!(
|
|
"{remaining} remaining - Upgrade to increase limit, or switch providers",
|
|
),
|
|
"Upgrade",
|
|
zed_urls::account_url(cx),
|
|
),
|
|
Plan::V1(PlanV1::ZedPro) | Plan::V2(_) => return div().into_any_element(),
|
|
}
|
|
};
|
|
|
|
let (icon, severity) = if is_limit_reached {
|
|
(IconName::Close, Severity::Error)
|
|
} else {
|
|
(IconName::Warning, Severity::Warning)
|
|
};
|
|
|
|
Callout::new()
|
|
.icon(icon)
|
|
.severity(severity)
|
|
.icon(icon)
|
|
.title(title)
|
|
.description(message)
|
|
.actions_slot(
|
|
Button::new("upgrade", button_text)
|
|
.label_size(LabelSize::Small)
|
|
.on_click(move |_, _, cx| {
|
|
cx.open_url(&url);
|
|
}),
|
|
)
|
|
.into_any_element()
|
|
}
|
|
}
|
|
|
|
impl Component for UsageCallout {
|
|
fn scope() -> ComponentScope {
|
|
ComponentScope::Agent
|
|
}
|
|
|
|
fn sort_name() -> &'static str {
|
|
"AgentUsageCallout"
|
|
}
|
|
|
|
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
|
let free_examples = example_group_with_title(
|
|
"Free Plan",
|
|
vec![
|
|
single_example(
|
|
"Approaching limit (90%)",
|
|
UsageCallout::new(
|
|
Plan::V1(PlanV1::ZedFree),
|
|
ModelRequestUsage(RequestUsage {
|
|
limit: UsageLimit::Limited(50),
|
|
amount: 45, // 90% of limit
|
|
}),
|
|
)
|
|
.into_any_element(),
|
|
),
|
|
single_example(
|
|
"Limit reached (100%)",
|
|
UsageCallout::new(
|
|
Plan::V1(PlanV1::ZedFree),
|
|
ModelRequestUsage(RequestUsage {
|
|
limit: UsageLimit::Limited(50),
|
|
amount: 50, // 100% of limit
|
|
}),
|
|
)
|
|
.into_any_element(),
|
|
),
|
|
],
|
|
);
|
|
|
|
let trial_examples = example_group_with_title(
|
|
"Zed Pro Trial",
|
|
vec![
|
|
single_example(
|
|
"Approaching limit (90%)",
|
|
UsageCallout::new(
|
|
Plan::V1(PlanV1::ZedProTrial),
|
|
ModelRequestUsage(RequestUsage {
|
|
limit: UsageLimit::Limited(150),
|
|
amount: 135, // 90% of limit
|
|
}),
|
|
)
|
|
.into_any_element(),
|
|
),
|
|
single_example(
|
|
"Limit reached (100%)",
|
|
UsageCallout::new(
|
|
Plan::V1(PlanV1::ZedProTrial),
|
|
ModelRequestUsage(RequestUsage {
|
|
limit: UsageLimit::Limited(150),
|
|
amount: 150, // 100% of limit
|
|
}),
|
|
)
|
|
.into_any_element(),
|
|
),
|
|
],
|
|
);
|
|
|
|
let pro_examples = example_group_with_title(
|
|
"Zed Pro",
|
|
vec![
|
|
single_example(
|
|
"Limit reached (100%)",
|
|
UsageCallout::new(
|
|
Plan::V1(PlanV1::ZedPro),
|
|
ModelRequestUsage(RequestUsage {
|
|
limit: UsageLimit::Limited(500),
|
|
amount: 500, // 100% of limit
|
|
}),
|
|
)
|
|
.into_any_element(),
|
|
),
|
|
empty_example("Unlimited plan (no callout shown)"),
|
|
],
|
|
);
|
|
|
|
Some(
|
|
v_flex()
|
|
.p_4()
|
|
.gap_4()
|
|
.child(free_examples)
|
|
.child(trial_examples)
|
|
.child(pro_examples)
|
|
.into_any_element(),
|
|
)
|
|
}
|
|
}
|