Compare commits
9 Commits
main
...
thomas/add
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77931bafa1 | ||
|
|
f81c2a9abf | ||
|
|
b447eb19ca | ||
|
|
7ec2ee943c | ||
|
|
d5c83baa02 | ||
|
|
efcd97f1d9 | ||
|
|
c768cb022b | ||
|
|
85acace7b2 | ||
|
|
0292f64416 |
@@ -1561,14 +1561,18 @@ impl AssistantPanel {
|
||||
cx: &mut Context<Self>,
|
||||
) -> AnyElement {
|
||||
let error_message = match plan {
|
||||
Plan::Free => "Model request limit reached. Upgrade to Zed Pro for more requests.",
|
||||
Plan::ZedPro => {
|
||||
"Model request limit reached. Upgrade to usage-based billing for more requests."
|
||||
}
|
||||
Plan::ZedProTrial => {
|
||||
"Model request limit reached. Upgrade to Zed Pro for more requests."
|
||||
}
|
||||
Plan::Free => "Model request limit reached. Upgrade to Zed Pro for more requests.",
|
||||
};
|
||||
let call_to_action = match plan {
|
||||
Plan::Free => "Upgrade to Zed Pro",
|
||||
Plan::ZedPro => "Upgrade to usage-based billing",
|
||||
Plan::ZedProTrial => "Upgrade to Zed Pro",
|
||||
Plan::Free => "Upgrade to Zed Pro",
|
||||
};
|
||||
|
||||
v_flex()
|
||||
@@ -1788,10 +1792,27 @@ impl AssistantPanelDelegate for ConcreteAssistantPanelDelegate {
|
||||
|
||||
fn quote_selection(
|
||||
&self,
|
||||
_workspace: &mut Workspace,
|
||||
_creases: Vec<(String, String)>,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Workspace>,
|
||||
workspace: &mut Workspace,
|
||||
creases: Vec<(String, String)>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let Some(panel) = workspace.panel::<AssistantPanel>(cx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !panel.focus_handle(cx).contains_focused(window, cx) {
|
||||
workspace.toggle_panel_focus::<AssistantPanel>(window, cx);
|
||||
}
|
||||
|
||||
panel.update(cx, |_, cx| {
|
||||
// Wait to create a new context until the workspace is no longer
|
||||
// being updated.
|
||||
cx.defer_in(window, move |panel, window, cx| {
|
||||
if let Some(context) = panel.active_context_editor() {
|
||||
context.update(cx, |context, cx| context.quote_creases(creases, window, cx));
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
alter table subscription_usages
|
||||
add column plan text not null;
|
||||
|
||||
create index ix_subscription_usages_on_plan on subscription_usages (plan);
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::db::UserId;
|
||||
use crate::db::billing_subscription::SubscriptionKind;
|
||||
use sea_orm::entity::prelude::*;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
@@ -10,6 +11,7 @@ pub struct Model {
|
||||
pub user_id: UserId,
|
||||
pub period_start_at: PrimitiveDateTime,
|
||||
pub period_end_at: PrimitiveDateTime,
|
||||
pub plan: SubscriptionKind,
|
||||
pub model_requests: i32,
|
||||
pub edit_predictions: i32,
|
||||
}
|
||||
|
||||
@@ -3707,7 +3707,9 @@ async fn count_language_model_tokens(
|
||||
|
||||
let rate_limit: Box<dyn RateLimit> = match session.current_plan(&session.db().await).await? {
|
||||
proto::Plan::ZedPro => Box::new(ZedProCountLanguageModelTokensRateLimit),
|
||||
proto::Plan::Free => Box::new(FreeCountLanguageModelTokensRateLimit),
|
||||
proto::Plan::Free | proto::Plan::ZedProTrial => {
|
||||
Box::new(FreeCountLanguageModelTokensRateLimit)
|
||||
}
|
||||
};
|
||||
|
||||
session
|
||||
@@ -3827,7 +3829,7 @@ async fn compute_embeddings(
|
||||
|
||||
let rate_limit: Box<dyn RateLimit> = match session.current_plan(&session.db().await).await? {
|
||||
proto::Plan::ZedPro => Box::new(ZedProComputeEmbeddingsRateLimit),
|
||||
proto::Plan::Free => Box::new(FreeComputeEmbeddingsRateLimit),
|
||||
proto::Plan::Free | proto::Plan::ZedProTrial => Box::new(FreeComputeEmbeddingsRateLimit),
|
||||
};
|
||||
|
||||
session
|
||||
|
||||
@@ -271,12 +271,12 @@ fn main() {
|
||||
match judge_result {
|
||||
Ok(judge_output) => {
|
||||
const SCORES: [&str; 6] = ["💀", "😭", "😔", "😐", "🙂", "🤩"];
|
||||
let score: u32 = judge_output.score;
|
||||
let score_index = (score.min(5)) as usize;
|
||||
|
||||
println!(
|
||||
"{} {}{}",
|
||||
SCORES[judge_output.score.min(5) as usize],
|
||||
example.log_prefix,
|
||||
judge_output.score,
|
||||
SCORES[score_index], example.log_prefix, judge_output.score,
|
||||
);
|
||||
judge_scores.push(judge_output.score);
|
||||
}
|
||||
@@ -304,7 +304,6 @@ fn main() {
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
|
||||
// Flush telemetry events before exiting
|
||||
app_state.client.telemetry().flush_events();
|
||||
|
||||
cx.update(|cx| cx.quit())
|
||||
@@ -330,7 +329,6 @@ async fn run_example(
|
||||
for round in 0..judge_repetitions {
|
||||
let judge_result = example.judge(model.clone(), diff.clone(), round, cx).await;
|
||||
|
||||
// Log telemetry for this judge result
|
||||
if let Ok(judge_output) = &judge_result {
|
||||
let cohort_id = example
|
||||
.output_file_path
|
||||
@@ -339,6 +337,9 @@ async fn run_example(
|
||||
.map(|name| name.to_string_lossy().to_string())
|
||||
.unwrap_or(chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string());
|
||||
|
||||
let path = std::path::Path::new(".");
|
||||
let commit_id = get_current_commit_id(path).await.unwrap_or_default();
|
||||
|
||||
telemetry::event!(
|
||||
"Agent Eval Completed",
|
||||
cohort_id = cohort_id,
|
||||
@@ -353,7 +354,8 @@ async fn run_example(
|
||||
model_provider = model.provider_id().to_string(),
|
||||
repository_url = example.base.url.clone(),
|
||||
repository_revision = example.base.revision.clone(),
|
||||
diagnostics_summary = run_output.diagnostics
|
||||
diagnostics_summary = run_output.diagnostics,
|
||||
commit_id = commit_id
|
||||
);
|
||||
}
|
||||
|
||||
@@ -524,3 +526,13 @@ pub fn authenticate_model_provider(
|
||||
let model_provider = model_registry.provider(&provider_id).unwrap();
|
||||
model_provider.authenticate(cx)
|
||||
}
|
||||
|
||||
pub async fn get_current_commit_id(repo_path: &Path) -> Option<String> {
|
||||
(run_git(repo_path, &["rev-parse", "HEAD"]).await).ok()
|
||||
}
|
||||
|
||||
pub fn get_current_commit_id_sync(repo_path: &Path) -> String {
|
||||
futures::executor::block_on(async {
|
||||
get_current_commit_id(repo_path).await.unwrap_or_default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -154,6 +154,9 @@ impl fmt::Display for ModelRequestLimitReachedError {
|
||||
Plan::ZedPro => {
|
||||
"Model request limit reached. Upgrade to usage-based billing for more requests."
|
||||
}
|
||||
Plan::ZedProTrial => {
|
||||
"Model request limit reached. Upgrade to Zed Pro for more requests."
|
||||
}
|
||||
};
|
||||
|
||||
write!(f, "{message}")
|
||||
|
||||
@@ -546,7 +546,6 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||
use feature_flags::FeatureFlagAppExt;
|
||||
|
||||
let plan = proto::Plan::ZedPro;
|
||||
let is_trial = false;
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
@@ -558,7 +557,6 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||
.justify_between()
|
||||
.when(cx.has_flag::<ZedPro>(), |this| {
|
||||
this.child(match plan {
|
||||
// Already a Zed Pro subscriber
|
||||
Plan::ZedPro => Button::new("zed-pro", "Zed Pro")
|
||||
.icon(IconName::ZedAssistant)
|
||||
.icon_size(IconSize::Small)
|
||||
@@ -568,10 +566,9 @@ impl PickerDelegate for LanguageModelPickerDelegate {
|
||||
window
|
||||
.dispatch_action(Box::new(zed_actions::OpenAccountSettings), cx)
|
||||
}),
|
||||
// Free user
|
||||
Plan::Free => Button::new(
|
||||
Plan::Free | Plan::ZedProTrial => Button::new(
|
||||
"try-pro",
|
||||
if is_trial {
|
||||
if plan == Plan::ZedProTrial {
|
||||
"Upgrade to Pro"
|
||||
} else {
|
||||
"Try Pro"
|
||||
|
||||
@@ -5170,6 +5170,7 @@ impl MultiBufferSnapshot {
|
||||
excerpt_id: ExcerptId,
|
||||
text_anchor: text::Anchor,
|
||||
) -> Option<Anchor> {
|
||||
let excerpt_id = self.latest_excerpt_id(excerpt_id);
|
||||
let locator = self.excerpt_locator_for_id(excerpt_id);
|
||||
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&());
|
||||
cursor.seek(locator, Bias::Left, &());
|
||||
|
||||
@@ -18,6 +18,7 @@ message GetPrivateUserInfoResponse {
|
||||
enum Plan {
|
||||
Free = 0;
|
||||
ZedPro = 1;
|
||||
ZedProTrial = 2;
|
||||
}
|
||||
|
||||
message UpdateUserPlan {
|
||||
|
||||
@@ -36,7 +36,7 @@ use ui::{
|
||||
IconWithIndicator, Indicator, PopoverMenu, Tooltip, h_flex, prelude::*,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use workspace::{BottomDockLayout, Workspace, notifications::NotifyResultExt};
|
||||
use workspace::{Workspace, notifications::NotifyResultExt};
|
||||
use zed_actions::{OpenBrowser, OpenRecent, OpenRemote};
|
||||
|
||||
pub use onboarding_banner::restore_banner;
|
||||
@@ -210,7 +210,6 @@ impl Render for TitleBar {
|
||||
.pr_1()
|
||||
.on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
|
||||
.children(self.render_call_controls(window, cx))
|
||||
.child(self.render_bottom_dock_layout_menu(cx))
|
||||
.map(|el| {
|
||||
let status = self.client.status();
|
||||
let status = &*status.borrow();
|
||||
@@ -623,101 +622,6 @@ impl TitleBar {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_bottom_dock_layout_menu(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let workspace = self.workspace.upgrade().unwrap();
|
||||
let current_layout = workspace.update(cx, |workspace, _cx| workspace.bottom_dock_layout());
|
||||
|
||||
PopoverMenu::new("layout-menu")
|
||||
.trigger(
|
||||
IconButton::new("toggle_layout", IconName::Layout)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(Tooltip::text("Toggle Layout Menu")),
|
||||
)
|
||||
.anchor(gpui::Corner::TopRight)
|
||||
.menu(move |window, cx| {
|
||||
ContextMenu::build(window, cx, {
|
||||
let workspace = workspace.clone();
|
||||
move |menu, _, _| {
|
||||
menu.label("Bottom Dock")
|
||||
.separator()
|
||||
.toggleable_entry(
|
||||
"Contained",
|
||||
current_layout == BottomDockLayout::Contained,
|
||||
ui::IconPosition::End,
|
||||
None,
|
||||
{
|
||||
let workspace = workspace.clone();
|
||||
move |window, cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.set_bottom_dock_layout(
|
||||
BottomDockLayout::Contained,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
.toggleable_entry(
|
||||
"Full",
|
||||
current_layout == BottomDockLayout::Full,
|
||||
ui::IconPosition::End,
|
||||
None,
|
||||
{
|
||||
let workspace = workspace.clone();
|
||||
move |window, cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.set_bottom_dock_layout(
|
||||
BottomDockLayout::Full,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
.toggleable_entry(
|
||||
"Left Aligned",
|
||||
current_layout == BottomDockLayout::LeftAligned,
|
||||
ui::IconPosition::End,
|
||||
None,
|
||||
{
|
||||
let workspace = workspace.clone();
|
||||
move |window, cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.set_bottom_dock_layout(
|
||||
BottomDockLayout::LeftAligned,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
.toggleable_entry(
|
||||
"Right Aligned",
|
||||
current_layout == BottomDockLayout::RightAligned,
|
||||
ui::IconPosition::End,
|
||||
None,
|
||||
{
|
||||
let workspace = workspace.clone();
|
||||
move |window, cx| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.set_bottom_dock_layout(
|
||||
BottomDockLayout::RightAligned,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_sign_in_button(&mut self, _: &mut Context<Self>) -> Button {
|
||||
let client = self.client.clone();
|
||||
Button::new("sign_in", "Sign in")
|
||||
@@ -751,6 +655,7 @@ impl TitleBar {
|
||||
None => "",
|
||||
Some(proto::Plan::Free) => "Free",
|
||||
Some(proto::Plan::ZedPro) => "Pro",
|
||||
Some(proto::Plan::ZedProTrial) => "Pro (Trial)",
|
||||
}
|
||||
),
|
||||
zed_actions::OpenAccountSettings.boxed_clone(),
|
||||
|
||||
@@ -75,6 +75,46 @@ Non-negative `float` values
|
||||
|
||||
`float` values
|
||||
|
||||
## Bottom Dock Layout
|
||||
|
||||
- Description: Control the layout of the bottom dock, relative to the left and right docks
|
||||
- Setting: `bottom_dock_layout`
|
||||
- Default: `"contained"`
|
||||
|
||||
**Options**
|
||||
|
||||
1. Contain the bottom dock, giving the full height of the window to the left and right docks
|
||||
|
||||
```json
|
||||
{
|
||||
"bottom_dock_layout": "contained"
|
||||
}
|
||||
```
|
||||
|
||||
2. Give the bottom dock the full width of the window, truncating the left and right docks
|
||||
|
||||
```json
|
||||
{
|
||||
"bottom_dock_layout": "full"
|
||||
}
|
||||
```
|
||||
|
||||
3. Left align the bottom dock, truncating the left dock and giving the right dock the full height of the window
|
||||
|
||||
```json
|
||||
{
|
||||
"bottom_dock_layout": "left_aligned"
|
||||
}
|
||||
```
|
||||
|
||||
3. Right align the bottom dock, giving the left dock the full height of the window and truncating the right dock.
|
||||
|
||||
```json
|
||||
{
|
||||
"bottom_dock_layout": "right_aligned"
|
||||
}
|
||||
```
|
||||
|
||||
## Auto Install extensions
|
||||
|
||||
- Description: Define extensions to be autoinstalled or never be installed.
|
||||
|
||||
Reference in New Issue
Block a user