Detailed changes
@@ -402,6 +402,7 @@ dependencies = [
"indoc",
"language",
"language_model",
+ "language_model_selector",
"language_models",
"languages",
"log",
@@ -6603,6 +6604,20 @@ dependencies = [
"util",
]
+[[package]]
+name = "language_model_selector"
+version = "0.1.0"
+dependencies = [
+ "feature_flags",
+ "gpui",
+ "language_model",
+ "picker",
+ "proto",
+ "ui",
+ "workspace",
+ "zed_actions",
+]
+
[[package]]
name = "language_models"
version = "0.1.0"
@@ -58,6 +58,7 @@ members = [
"crates/language",
"crates/language_extension",
"crates/language_model",
+ "crates/language_model_selector",
"crates/language_models",
"crates/language_selector",
"crates/language_tools",
@@ -236,6 +237,7 @@ journal = { path = "crates/journal" }
language = { path = "crates/language" }
language_extension = { path = "crates/language_extension" }
language_model = { path = "crates/language_model" }
+language_model_selector = { path = "crates/language_model_selector" }
language_models = { path = "crates/language_models" }
language_selector = { path = "crates/language_selector" }
language_tools = { path = "crates/language_tools" }
@@ -50,6 +50,7 @@ indexed_docs.workspace = true
indoc.workspace = true
language.workspace = true
language_model.workspace = true
+language_model_selector.workspace = true
language_models.workspace = true
log.workspace = true
lsp.workspace = true
@@ -5,7 +5,6 @@ pub mod assistant_settings;
mod context;
pub mod context_store;
mod inline_assistant;
-mod model_selector;
mod patch;
mod prompt_library;
mod prompts;
@@ -37,7 +36,6 @@ pub(crate) use inline_assistant::*;
use language_model::{
LanguageModelId, LanguageModelProviderId, LanguageModelRegistry, LanguageModelResponseMessage,
};
-pub(crate) use model_selector::*;
pub use patch::*;
pub use prompts::PromptBuilder;
use prompts::PromptLoadingParams;
@@ -17,9 +17,9 @@ use crate::{
ContextEvent, ContextId, ContextStore, ContextStoreEvent, CopyCode, CycleMessageRole,
DeployHistory, DeployPromptLibrary, Edit, InlineAssistant, InsertDraggedFiles,
InsertIntoEditor, InvokedSlashCommandId, InvokedSlashCommandStatus, Message, MessageId,
- MessageMetadata, MessageStatus, ModelPickerDelegate, ModelSelector, NewContext,
- ParsedSlashCommand, PendingSlashCommandStatus, QuoteSelection, RemoteContextMetadata,
- RequestType, SavedContextMetadata, Split, ToggleFocus, ToggleModelSelector,
+ MessageMetadata, MessageStatus, NewContext, ParsedSlashCommand, PendingSlashCommandStatus,
+ QuoteSelection, RemoteContextMetadata, RequestType, SavedContextMetadata, Split, ToggleFocus,
+ ToggleModelSelector,
};
use anyhow::Result;
use assistant_slash_command::{SlashCommand, SlashCommandOutputSection};
@@ -55,6 +55,7 @@ use language_model::{
LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry, Role,
ZED_CLOUD_PROVIDER_ID,
};
+use language_model_selector::{LanguageModelPickerDelegate, LanguageModelSelector};
use multi_buffer::MultiBufferRow;
use picker::{Picker, PickerDelegate};
use project::lsp_store::LocalLspAdapterDelegate;
@@ -142,7 +143,7 @@ pub struct AssistantPanel {
languages: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
subscriptions: Vec<Subscription>,
- model_selector_menu_handle: PopoverMenuHandle<Picker<ModelPickerDelegate>>,
+ model_selector_menu_handle: PopoverMenuHandle<Picker<LanguageModelPickerDelegate>>,
model_summary_editor: View<Editor>,
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
configuration_subscription: Option<Subscription>,
@@ -4457,13 +4458,13 @@ pub struct ContextEditorToolbarItem {
fs: Arc<dyn Fs>,
active_context_editor: Option<WeakView<ContextEditor>>,
model_summary_editor: View<Editor>,
- model_selector_menu_handle: PopoverMenuHandle<Picker<ModelPickerDelegate>>,
+ model_selector_menu_handle: PopoverMenuHandle<Picker<LanguageModelPickerDelegate>>,
}
impl ContextEditorToolbarItem {
pub fn new(
workspace: &Workspace,
- model_selector_menu_handle: PopoverMenuHandle<Picker<ModelPickerDelegate>>,
+ model_selector_menu_handle: PopoverMenuHandle<Picker<LanguageModelPickerDelegate>>,
model_summary_editor: View<Editor>,
) -> Self {
Self {
@@ -4559,8 +4560,17 @@ impl Render for ContextEditorToolbarItem {
// .map(|remaining_items| format!("Files to scan: {}", remaining_items))
// })
.child(
- ModelSelector::new(
- self.fs.clone(),
+ LanguageModelSelector::new(
+ {
+ let fs = self.fs.clone();
+ move |model, cx| {
+ update_settings_file::<AssistantSettings>(
+ fs.clone(),
+ cx,
+ move |settings, _| settings.set_model(model.clone()),
+ );
+ }
+ },
ButtonLike::new("active-model")
.style(ButtonStyle::Subtle)
.child(
@@ -1,7 +1,7 @@
use crate::{
assistant_settings::AssistantSettings, humanize_token_count, prompts::PromptBuilder,
AssistantPanel, AssistantPanelEvent, CharOperation, CycleNextInlineAssist,
- CyclePreviousInlineAssist, LineDiff, LineOperation, ModelSelector, RequestType, StreamingDiff,
+ CyclePreviousInlineAssist, LineDiff, LineOperation, RequestType, StreamingDiff,
};
use anyhow::{anyhow, Context as _, Result};
use client::{telemetry::Telemetry, ErrorExt};
@@ -33,12 +33,13 @@ use language_model::{
LanguageModel, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
LanguageModelTextStream, Role,
};
+use language_model_selector::LanguageModelSelector;
use language_models::report_assistant_event;
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use project::{CodeAction, ProjectTransaction};
use rope::Rope;
-use settings::{Settings, SettingsStore};
+use settings::{update_settings_file, Settings, SettingsStore};
use smol::future::FutureExt;
use std::{
cmp,
@@ -1500,8 +1501,17 @@ impl Render for PromptEditor {
.justify_center()
.gap_2()
.child(
- ModelSelector::new(
- self.fs.clone(),
+ LanguageModelSelector::new(
+ {
+ let fs = self.fs.clone();
+ move |model, cx| {
+ update_settings_file::<AssistantSettings>(
+ fs.clone(),
+ cx,
+ move |settings, _| settings.set_model(model.clone()),
+ );
+ }
+ },
IconButton::new("context", IconName::SettingsAlt)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
@@ -1521,7 +1531,7 @@ impl Render for PromptEditor {
)
}),
)
- .with_info_text(
+ .info_text(
"Inline edits use context\n\
from the currently selected\n\
assistant panel tab.",
@@ -1,6 +1,7 @@
+use crate::assistant_settings::AssistantSettings;
use crate::{
- humanize_token_count, prompts::PromptBuilder, AssistantPanel, AssistantPanelEvent,
- ModelSelector, RequestType, DEFAULT_CONTEXT_LINES,
+ humanize_token_count, prompts::PromptBuilder, AssistantPanel, AssistantPanelEvent, RequestType,
+ DEFAULT_CONTEXT_LINES,
};
use anyhow::{Context as _, Result};
use client::telemetry::Telemetry;
@@ -19,8 +20,9 @@ use language::Buffer;
use language_model::{
LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage, Role,
};
+use language_model_selector::LanguageModelSelector;
use language_models::report_assistant_event;
-use settings::Settings;
+use settings::{update_settings_file, Settings};
use std::{
cmp,
sync::Arc,
@@ -612,8 +614,17 @@ impl Render for PromptEditor {
.w_12()
.justify_center()
.gap_2()
- .child(ModelSelector::new(
- self.fs.clone(),
+ .child(LanguageModelSelector::new(
+ {
+ let fs = self.fs.clone();
+ move |model, cx| {
+ update_settings_file::<AssistantSettings>(
+ fs.clone(),
+ cx,
+ move |settings, _| settings.set_model(model.clone()),
+ );
+ }
+ },
IconButton::new("context", IconName::SettingsAlt)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
@@ -0,0 +1,22 @@
+[package]
+name = "language_model_selector"
+version = "0.1.0"
+edition = "2021"
+publish = false
+license = "GPL-3.0-or-later"
+
+[lints]
+workspace = true
+
+[lib]
+path = "src/language_model_selector.rs"
+
+[dependencies]
+feature_flags.workspace = true
+gpui.workspace = true
+language_model.workspace = true
+picker.workspace = true
+proto.workspace = true
+ui.workspace = true
+workspace.workspace = true
+zed_actions.workspace = true
@@ -0,0 +1 @@
+../../LICENSE-GPL
@@ -1,30 +1,27 @@
-use feature_flags::ZedPro;
-
-use language_model::{LanguageModel, LanguageModelAvailability, LanguageModelRegistry};
-use proto::Plan;
-use workspace::ShowConfiguration;
-
use std::sync::Arc;
-use crate::assistant_settings::AssistantSettings;
-use fs::Fs;
-use gpui::{Action, AnyElement, DismissEvent, SharedString, Task};
+use feature_flags::ZedPro;
+use gpui::{Action, AnyElement, AppContext, DismissEvent, SharedString, Task};
+use language_model::{LanguageModel, LanguageModelAvailability, LanguageModelRegistry};
use picker::{Picker, PickerDelegate};
-use settings::update_settings_file;
+use proto::Plan;
use ui::{prelude::*, ListItem, ListItemSpacing, PopoverMenu, PopoverMenuHandle, PopoverTrigger};
+use workspace::ShowConfiguration;
const TRY_ZED_PRO_URL: &str = "https://zed.dev/pro";
+type OnModelChanged = Arc<dyn Fn(Arc<dyn LanguageModel>, &AppContext) + 'static>;
+
#[derive(IntoElement)]
-pub struct ModelSelector<T: PopoverTrigger> {
- handle: Option<PopoverMenuHandle<Picker<ModelPickerDelegate>>>,
- fs: Arc<dyn Fs>,
+pub struct LanguageModelSelector<T: PopoverTrigger> {
+ handle: Option<PopoverMenuHandle<Picker<LanguageModelPickerDelegate>>>,
+ on_model_changed: OnModelChanged,
trigger: T,
info_text: Option<SharedString>,
}
-pub struct ModelPickerDelegate {
- fs: Arc<dyn Fs>,
+pub struct LanguageModelPickerDelegate {
+ on_model_changed: OnModelChanged,
all_models: Vec<ModelInfo>,
filtered_models: Vec<ModelInfo>,
selected_index: usize,
@@ -38,28 +35,34 @@ struct ModelInfo {
is_selected: bool,
}
-impl<T: PopoverTrigger> ModelSelector<T> {
- pub fn new(fs: Arc<dyn Fs>, trigger: T) -> Self {
- ModelSelector {
+impl<T: PopoverTrigger> LanguageModelSelector<T> {
+ pub fn new(
+ on_model_changed: impl Fn(Arc<dyn LanguageModel>, &AppContext) + 'static,
+ trigger: T,
+ ) -> Self {
+ LanguageModelSelector {
handle: None,
- fs,
+ on_model_changed: Arc::new(on_model_changed),
trigger,
info_text: None,
}
}
- pub fn with_handle(mut self, handle: PopoverMenuHandle<Picker<ModelPickerDelegate>>) -> Self {
+ pub fn with_handle(
+ mut self,
+ handle: PopoverMenuHandle<Picker<LanguageModelPickerDelegate>>,
+ ) -> Self {
self.handle = Some(handle);
self
}
- pub fn with_info_text(mut self, text: impl Into<SharedString>) -> Self {
+ pub fn info_text(mut self, text: impl Into<SharedString>) -> Self {
self.info_text = Some(text.into());
self
}
}
-impl PickerDelegate for ModelPickerDelegate {
+impl PickerDelegate for LanguageModelPickerDelegate {
type ListItem = ListItem;
fn match_count(&self) -> usize {
@@ -137,9 +140,7 @@ impl PickerDelegate for ModelPickerDelegate {
fn confirm(&mut self, _secondary: bool, cx: &mut ViewContext<Picker<Self>>) {
if let Some(model_info) = self.filtered_models.get(self.selected_index) {
let model = model_info.model.clone();
- update_settings_file::<AssistantSettings>(self.fs.clone(), cx, move |settings, _| {
- settings.set_model(model.clone())
- });
+ (self.on_model_changed)(model.clone(), cx);
// Update the selection status
let selected_model_id = model_info.model.id();
@@ -296,7 +297,7 @@ impl PickerDelegate for ModelPickerDelegate {
}
}
-impl<T: PopoverTrigger> RenderOnce for ModelSelector<T> {
+impl<T: PopoverTrigger> RenderOnce for LanguageModelSelector<T> {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let selected_provider = LanguageModelRegistry::read_global(cx)
.active_provider()
@@ -331,8 +332,8 @@ impl<T: PopoverTrigger> RenderOnce for ModelSelector<T> {
})
.collect::<Vec<_>>();
- let delegate = ModelPickerDelegate {
- fs: self.fs.clone(),
+ let delegate = LanguageModelPickerDelegate {
+ on_model_changed: self.on_model_changed.clone(),
all_models: all_models.clone(),
filtered_models: all_models,
selected_index: 0,