Introduce the ability to cycle between alternative inline assists (#18098)
Release Notes: - Added a new `assistant.inline_alternatives` setting to configure additional models that will be used to perform inline assists in parallel. --------- Co-authored-by: Nathan <nathan@zed.dev> Co-authored-by: Roy <roy@anthropic.com> Co-authored-by: Adam <wolffiex@anthropic.com>
This commit is contained in:
parent
ae34872f73
commit
15b4130fa5
8 changed files with 642 additions and 178 deletions
|
@ -520,6 +520,13 @@
|
|||
"alt-enter": "editor::Newline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "PromptEditor",
|
||||
"bindings": {
|
||||
"ctrl-[": "assistant::CyclePreviousInlineAssist",
|
||||
"ctrl-]": "assistant::CycleNextInlineAssist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProjectSearchBar && !in_replace",
|
||||
"bindings": {
|
||||
|
|
|
@ -527,6 +527,13 @@
|
|||
"ctrl-enter": "assistant::InlineAssist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "PromptEditor",
|
||||
"bindings": {
|
||||
"ctrl-[": "assistant::CyclePreviousInlineAssist",
|
||||
"ctrl-]": "assistant::CycleNextInlineAssist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProjectSearchBar && !in_replace",
|
||||
"bindings": {
|
||||
|
|
|
@ -69,6 +69,8 @@ actions!(
|
|||
ConfirmCommand,
|
||||
NewContext,
|
||||
ToggleModelSelector,
|
||||
CycleNextInlineAssist,
|
||||
CyclePreviousInlineAssist
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -359,8 +361,19 @@ fn update_active_language_model_from_settings(cx: &mut AppContext) {
|
|||
let settings = AssistantSettings::get_global(cx);
|
||||
let provider_name = LanguageModelProviderId::from(settings.default_model.provider.clone());
|
||||
let model_id = LanguageModelId::from(settings.default_model.model.clone());
|
||||
let inline_alternatives = settings
|
||||
.inline_alternatives
|
||||
.iter()
|
||||
.map(|alternative| {
|
||||
(
|
||||
LanguageModelProviderId::from(alternative.provider.clone()),
|
||||
LanguageModelId::from(alternative.model.clone()),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
LanguageModelRegistry::global(cx).update(cx, |registry, cx| {
|
||||
registry.select_active_model(&provider_name, &model_id, cx);
|
||||
registry.select_inline_alternative_models(inline_alternatives, cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ pub struct AssistantSettings {
|
|||
pub default_width: Pixels,
|
||||
pub default_height: Pixels,
|
||||
pub default_model: LanguageModelSelection,
|
||||
pub inline_alternatives: Vec<LanguageModelSelection>,
|
||||
pub using_outdated_settings_version: bool,
|
||||
}
|
||||
|
||||
|
@ -236,6 +237,7 @@ impl AssistantSettingsContent {
|
|||
})
|
||||
}
|
||||
}),
|
||||
inline_alternatives: None,
|
||||
},
|
||||
VersionedAssistantSettingsContent::V2(settings) => settings.clone(),
|
||||
},
|
||||
|
@ -254,6 +256,7 @@ impl AssistantSettingsContent {
|
|||
.id()
|
||||
.to_string(),
|
||||
}),
|
||||
inline_alternatives: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -369,6 +372,7 @@ impl Default for VersionedAssistantSettingsContent {
|
|||
default_width: None,
|
||||
default_height: None,
|
||||
default_model: None,
|
||||
inline_alternatives: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -397,6 +401,8 @@ pub struct AssistantSettingsContentV2 {
|
|||
default_height: Option<f32>,
|
||||
/// The default model to use when creating new contexts.
|
||||
default_model: Option<LanguageModelSelection>,
|
||||
/// Additional models with which to generate alternatives when performing inline assists.
|
||||
inline_alternatives: Option<Vec<LanguageModelSelection>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
|
@ -517,10 +523,8 @@ impl Settings for AssistantSettings {
|
|||
&mut settings.default_height,
|
||||
value.default_height.map(Into::into),
|
||||
);
|
||||
merge(
|
||||
&mut settings.default_model,
|
||||
value.default_model.map(Into::into),
|
||||
);
|
||||
merge(&mut settings.default_model, value.default_model);
|
||||
merge(&mut settings.inline_alternatives, value.inline_alternatives);
|
||||
// merge(&mut settings.infer_context, value.infer_context); TODO re-enable this once we ship context inference
|
||||
}
|
||||
|
||||
|
@ -574,6 +578,7 @@ mod tests {
|
|||
provider: "test-provider".into(),
|
||||
model: "gpt-99".into(),
|
||||
}),
|
||||
inline_alternatives: None,
|
||||
enabled: None,
|
||||
button: None,
|
||||
dock: None,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -76,6 +76,7 @@ impl Global for GlobalLanguageModelRegistry {}
|
|||
pub struct LanguageModelRegistry {
|
||||
active_model: Option<ActiveModel>,
|
||||
providers: BTreeMap<LanguageModelProviderId, Arc<dyn LanguageModelProvider>>,
|
||||
inline_alternatives: Vec<Arc<dyn LanguageModel>>,
|
||||
}
|
||||
|
||||
pub struct ActiveModel {
|
||||
|
@ -229,6 +230,37 @@ impl LanguageModelRegistry {
|
|||
pub fn active_model(&self) -> Option<Arc<dyn LanguageModel>> {
|
||||
self.active_model.as_ref()?.model.clone()
|
||||
}
|
||||
|
||||
/// Selects and sets the inline alternatives for language models based on
|
||||
/// provider name and id.
|
||||
pub fn select_inline_alternative_models(
|
||||
&mut self,
|
||||
alternatives: impl IntoIterator<Item = (LanguageModelProviderId, LanguageModelId)>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let mut selected_alternatives = Vec::new();
|
||||
|
||||
for (provider_id, model_id) in alternatives {
|
||||
if let Some(provider) = self.providers.get(&provider_id) {
|
||||
if let Some(model) = provider
|
||||
.provided_models(cx)
|
||||
.iter()
|
||||
.find(|m| m.id() == model_id)
|
||||
{
|
||||
selected_alternatives.push(model.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.inline_alternatives = selected_alternatives;
|
||||
}
|
||||
|
||||
/// The models to use for inline assists. Returns the union of the active
|
||||
/// model and all inline alternatives. When there are multiple models, the
|
||||
/// user will be able to cycle through results.
|
||||
pub fn inline_alternative_models(&self) -> &[Arc<dyn LanguageModel>] {
|
||||
&self.inline_alternatives
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1106,6 +1106,26 @@ impl MultiBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn forget_transaction(
|
||||
&mut self,
|
||||
transaction_id: TransactionId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
if let Some(buffer) = self.as_singleton() {
|
||||
buffer.update(cx, |buffer, _| {
|
||||
buffer.forget_transaction(transaction_id);
|
||||
});
|
||||
} else if let Some(transaction) = self.history.forget(transaction_id) {
|
||||
for (buffer_id, buffer_transaction_id) in transaction.buffer_transactions {
|
||||
if let Some(state) = self.buffers.borrow_mut().get_mut(&buffer_id) {
|
||||
state.buffer.update(cx, |buffer, _| {
|
||||
buffer.forget_transaction(buffer_transaction_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stream_excerpts_with_context_lines(
|
||||
&mut self,
|
||||
buffer: Model<Buffer>,
|
||||
|
|
|
@ -20,6 +20,7 @@ To further customize providers, you can use `settings.json` to do that as follow
|
|||
- [Configuring endpoints](#custom-endpoint)
|
||||
- [Configuring timeouts](#provider-timeout)
|
||||
- [Configuring default model](#default-model)
|
||||
- [Configuring alternative models for inline assists](#alternative-assists)
|
||||
|
||||
### Zed AI {#zed-ai}
|
||||
|
||||
|
@ -264,6 +265,31 @@ You can also manually edit the `default_model` object in your settings:
|
|||
}
|
||||
```
|
||||
|
||||
#### Configuring alternative models for inline assists {#alternative-assists}
|
||||
|
||||
You can configure additional models that will be used to perform inline assists in parallel. When you do this,
|
||||
the inline assist UI will surface controls to cycle between the alternatives generated by each model. The models
|
||||
you specify here are always used in _addition_ to your default model. For example, the following configuration
|
||||
will generate two outputs for every assist. One with Claude 3.5 Sonnet, and one with GPT-4o.
|
||||
|
||||
```json
|
||||
{
|
||||
"assistant": {
|
||||
"default_model": {
|
||||
"provider": "zed.dev",
|
||||
"model": "claude-3-5-sonnet"
|
||||
},
|
||||
"inline_alternatives": [
|
||||
{
|
||||
"provider": "zed.dev",
|
||||
"model": "gpt-4o"
|
||||
}
|
||||
],
|
||||
"version": "2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Common Panel Settings
|
||||
|
||||
| key | type | default | description |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue