mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
provider configuration: Use SingleLineInput instead of Editor (#38814)
Release Notes: - N/A
This commit is contained in:
parent
d83d7d35cb
commit
67984d5e49
16 changed files with 116 additions and 462 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -8706,7 +8706,6 @@ dependencies = [
|
|||
"settings",
|
||||
"smol",
|
||||
"strum 0.27.1",
|
||||
"theme",
|
||||
"thiserror 2.0.12",
|
||||
"tiktoken-rs",
|
||||
"tokio",
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ convert_case.workspace = true
|
|||
copilot.workspace = true
|
||||
credentials_provider.workspace = true
|
||||
deepseek = { workspace = true, features = ["schemars"] }
|
||||
editor.workspace = true
|
||||
fs.workspace = true
|
||||
futures.workspace = true
|
||||
google_ai = { workspace = true, features = ["schemars"] }
|
||||
|
|
@ -52,7 +51,6 @@ serde_json.workspace = true
|
|||
settings.workspace = true
|
||||
smol.workspace = true
|
||||
strum.workspace = true
|
||||
theme.workspace = true
|
||||
thiserror.workspace = true
|
||||
tiktoken-rs.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
use crate::api_key::ApiKeyState;
|
||||
use crate::ui::InstructionListItem;
|
||||
use anthropic::{
|
||||
ANTHROPIC_API_URL, AnthropicError, AnthropicModelMode, ContentDelta, Event, ResponseContent,
|
||||
ToolResultContent, ToolResultPart, Usage,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{FutureExt, Stream, StreamExt, future, future::BoxFuture, stream::BoxStream};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, FontStyle, Task, TextStyle, WhiteSpace};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, Task};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, ConfigurationViewTargetAgent, LanguageModel,
|
||||
|
|
@ -23,11 +20,14 @@ use std::pin::Pin;
|
|||
use std::str::FromStr;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use strum::IntoEnumIterator;
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Icon, IconName, List, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::{ResultExt, truncate_and_trailoff};
|
||||
use zed_env_vars::{EnvVar, env_var};
|
||||
|
||||
use crate::api_key::ApiKeyState;
|
||||
use crate::ui::InstructionListItem;
|
||||
|
||||
pub use settings::AnthropicAvailableModel as AvailableModel;
|
||||
|
||||
const PROVIDER_ID: LanguageModelProviderId = language_model::ANTHROPIC_PROVIDER_ID;
|
||||
|
|
@ -42,7 +42,7 @@ pub struct AnthropicSettings {
|
|||
|
||||
pub struct AnthropicLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
const API_KEY_ENV_VAR_NAME: &str = "ANTHROPIC_API_KEY";
|
||||
|
|
@ -123,7 +123,7 @@ impl AnthropicLanguageModelProvider {
|
|||
impl LanguageModelProviderState for AnthropicLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -226,7 +226,7 @@ impl LanguageModelProvider for AnthropicLanguageModelProvider {
|
|||
pub struct AnthropicModel {
|
||||
id: LanguageModelId,
|
||||
model: anthropic::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -823,8 +823,8 @@ fn convert_usage(usage: &Usage) -> language_model::TokenUsage {
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
target_agent: ConfigurationViewTargetAgent,
|
||||
}
|
||||
|
|
@ -833,7 +833,7 @@ impl ConfigurationView {
|
|||
const PLACEHOLDER_TEXT: &'static str = "sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
|
||||
fn new(
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
target_agent: ConfigurationViewTargetAgent,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
|
@ -862,11 +862,7 @@ impl ConfigurationView {
|
|||
}));
|
||||
|
||||
Self {
|
||||
api_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_TEXT, window, cx);
|
||||
editor
|
||||
}),
|
||||
api_key_editor: cx.new(|cx| SingleLineInput::new(window, cx, Self::PLACEHOLDER_TEXT)),
|
||||
state,
|
||||
load_credentials_task,
|
||||
target_agent,
|
||||
|
|
@ -905,31 +901,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -962,18 +933,7 @@ impl Render for ConfigurationView {
|
|||
InstructionListItem::text_only("Paste your API key below and hit enter to start using the agent")
|
||||
)
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.rounded_sm()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(self.api_key_editor.clone())
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {API_KEY_ENV_VAR_NAME} environment variable and restart Zed."),
|
||||
|
|
|
|||
|
|
@ -23,12 +23,8 @@ use bedrock::{
|
|||
};
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use credentials_provider::CredentialsProvider;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{FutureExt, Stream, StreamExt, future::BoxFuture, stream::BoxStream};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, FontWeight, Subscription, Task, TextStyle,
|
||||
WhiteSpace,
|
||||
};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, FontWeight, Subscription, Task};
|
||||
use gpui_tokio::Tokio;
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
|
|
@ -45,8 +41,8 @@ use serde_json::Value;
|
|||
use settings::{BedrockAvailableModel as AvailableModel, Settings, SettingsStore};
|
||||
use smol::lock::OnceCell;
|
||||
use strum::{EnumIter, IntoEnumIterator, IntoStaticStr};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Icon, IconName, List, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::ResultExt;
|
||||
|
||||
use crate::AllLanguageModelSettings;
|
||||
|
|
@ -243,7 +239,7 @@ impl State {
|
|||
pub struct BedrockLanguageModelProvider {
|
||||
http_client: AwsHttpClient,
|
||||
handle: tokio::runtime::Handle,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
impl BedrockLanguageModelProvider {
|
||||
|
|
@ -366,7 +362,7 @@ impl LanguageModelProvider for BedrockLanguageModelProvider {
|
|||
impl LanguageModelProviderState for BedrockLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -377,7 +373,7 @@ struct BedrockModel {
|
|||
http_client: AwsHttpClient,
|
||||
handle: tokio::runtime::Handle,
|
||||
client: OnceCell<BedrockClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
||||
|
|
@ -1010,11 +1006,11 @@ pub fn map_to_language_model_completion_events(
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
access_key_id_editor: Entity<Editor>,
|
||||
secret_access_key_editor: Entity<Editor>,
|
||||
session_token_editor: Entity<Editor>,
|
||||
region_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
access_key_id_editor: Entity<SingleLineInput>,
|
||||
secret_access_key_editor: Entity<SingleLineInput>,
|
||||
session_token_editor: Entity<SingleLineInput>,
|
||||
region_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
|
|
@ -1025,7 +1021,7 @@ impl ConfigurationView {
|
|||
const PLACEHOLDER_SESSION_TOKEN_TEXT: &'static str = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
||||
const PLACEHOLDER_REGION: &'static str = "us-east-1";
|
||||
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
cx.observe(&state, |_, _, cx| {
|
||||
cx.notify();
|
||||
})
|
||||
|
|
@ -1051,24 +1047,19 @@ impl ConfigurationView {
|
|||
|
||||
Self {
|
||||
access_key_id_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_ACCESS_KEY_ID_TEXT, window, cx);
|
||||
editor
|
||||
SingleLineInput::new(window, cx, Self::PLACEHOLDER_ACCESS_KEY_ID_TEXT)
|
||||
.label("Access Key ID")
|
||||
}),
|
||||
secret_access_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SECRET_ACCESS_KEY_TEXT, window, cx);
|
||||
editor
|
||||
SingleLineInput::new(window, cx, Self::PLACEHOLDER_SECRET_ACCESS_KEY_TEXT)
|
||||
.label("Secret Access Key")
|
||||
}),
|
||||
session_token_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SESSION_TOKEN_TEXT, window, cx);
|
||||
editor
|
||||
SingleLineInput::new(window, cx, Self::PLACEHOLDER_SESSION_TOKEN_TEXT)
|
||||
.label("Session Token (Optional)")
|
||||
}),
|
||||
region_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_REGION, window, cx);
|
||||
editor
|
||||
SingleLineInput::new(window, cx, Self::PLACEHOLDER_REGION).label("Region")
|
||||
}),
|
||||
state,
|
||||
load_credentials_task,
|
||||
|
|
@ -1148,41 +1139,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn make_text_style(&self, cx: &Context<Self>) -> TextStyle {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
text_overflow: None,
|
||||
text_align: Default::default(),
|
||||
line_clamp: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn make_input_styles(&self, cx: &Context<Self>) -> Div {
|
||||
let bg_color = cx.theme().colors().editor_background;
|
||||
let border_color = cx.theme().colors().border;
|
||||
|
||||
h_flex()
|
||||
.w_full()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(bg_color)
|
||||
.border_1()
|
||||
.border_color(border_color)
|
||||
.rounded_sm()
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &Context<Self>) -> bool {
|
||||
self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -1265,8 +1221,8 @@ impl Render for ConfigurationView {
|
|||
)
|
||||
)
|
||||
)
|
||||
.child(self.render_static_credentials_ui(cx))
|
||||
.child(self.render_common_fields(cx))
|
||||
.child(self.render_static_credentials_ui())
|
||||
.child(self.region_editor.clone())
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {ZED_BEDROCK_ACCESS_KEY_ID_VAR}, {ZED_BEDROCK_SECRET_ACCESS_KEY_VAR} AND {ZED_BEDROCK_REGION_VAR} environment variables and restart Zed."),
|
||||
|
|
@ -1287,63 +1243,7 @@ impl Render for ConfigurationView {
|
|||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn render_access_key_id_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let text_style = self.make_text_style(cx);
|
||||
|
||||
EditorElement::new(
|
||||
&self.access_key_id_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn render_secret_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let text_style = self.make_text_style(cx);
|
||||
|
||||
EditorElement::new(
|
||||
&self.secret_access_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn render_session_token_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let text_style = self.make_text_style(cx);
|
||||
|
||||
EditorElement::new(
|
||||
&self.session_token_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn render_region_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let text_style = self.make_text_style(cx);
|
||||
|
||||
EditorElement::new(
|
||||
&self.region_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn render_static_credentials_ui(&self, cx: &mut Context<Self>) -> AnyElement {
|
||||
fn render_static_credentials_ui(&self) -> AnyElement {
|
||||
v_flex()
|
||||
.my_2()
|
||||
.gap_1p5()
|
||||
|
|
@ -1376,41 +1276,10 @@ impl ConfigurationView {
|
|||
"Enter these credentials below",
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new("Access Key ID").size(LabelSize::Small))
|
||||
.child(
|
||||
self.make_input_styles(cx)
|
||||
.child(self.render_access_key_id_editor(cx)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new("Secret Access Key").size(LabelSize::Small))
|
||||
.child(self.make_input_styles(cx).child(self.render_secret_key_editor(cx))),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new("Session Token (Optional)").size(LabelSize::Small))
|
||||
.child(
|
||||
self.make_input_styles(cx)
|
||||
.child(self.render_session_token_editor(cx)),
|
||||
),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn render_common_fields(&self, cx: &mut Context<Self>) -> AnyElement {
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new("Region").size(LabelSize::Small))
|
||||
.child(
|
||||
self.make_input_styles(cx)
|
||||
.child(self.render_region_editor(cx)),
|
||||
)
|
||||
.child(self.access_key_id_editor.clone())
|
||||
.child(self.secret_access_key_editor.clone())
|
||||
.child(self.session_token_editor.clone())
|
||||
.child(self.region_editor.clone())
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl From<ModelMode> for AnthropicModelMode {
|
|||
|
||||
pub struct CloudLanguageModelProvider {
|
||||
client: Arc<Client>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
_maintain_client_status: Task<()>,
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ impl CloudLanguageModelProvider {
|
|||
impl LanguageModelProviderState for CloudLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ impl CopilotChatLanguageModelProvider {
|
|||
impl LanguageModelProviderState for CopilotChatLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
use anyhow::{Result, anyhow};
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use deepseek::DEEPSEEK_API_URL;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
|
||||
use futures::Stream;
|
||||
use futures::{FutureExt, StreamExt, future, future::BoxFuture, stream::BoxStream};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, SharedString, Task, TextStyle, WhiteSpace,
|
||||
Window,
|
||||
};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task, Window};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||
|
|
@ -21,8 +18,9 @@ use settings::{Settings, SettingsStore};
|
|||
use std::pin::Pin;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use theme::ThemeSettings;
|
||||
|
||||
use ui::{Icon, IconName, List, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::{ResultExt, truncate_and_trailoff};
|
||||
use zed_env_vars::{EnvVar, env_var};
|
||||
|
||||
|
|
@ -527,18 +525,15 @@ impl DeepSeekEventMapper {
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("sk-00000000000000000000000000000000", window, cx);
|
||||
editor
|
||||
});
|
||||
let api_key_editor =
|
||||
cx.new(|cx| SingleLineInput::new(window, cx, "sk-00000000000000000000000000000000"));
|
||||
|
||||
cx.observe(&state, |_, _, cx| {
|
||||
cx.notify();
|
||||
|
|
@ -598,34 +593,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
background_color: None,
|
||||
underline: None,
|
||||
strikethrough: None,
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -653,18 +620,7 @@ impl Render for ConfigurationView {
|
|||
"Paste your API key below and hit enter to start using the assistant",
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.rounded_sm()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(self.api_key_editor.clone())
|
||||
.child(
|
||||
Label::new(format!(
|
||||
"Or set the {API_KEY_ENV_VAR_NAME} environment variable."
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
use anyhow::{Context as _, Result, anyhow};
|
||||
use collections::BTreeMap;
|
||||
use credentials_provider::CredentialsProvider;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{FutureExt, Stream, StreamExt, future, future::BoxFuture};
|
||||
use google_ai::{
|
||||
FunctionDeclaration, GenerateContentResponse, GoogleModelMode, Part, SystemInstruction,
|
||||
ThinkingConfig, UsageMetadata,
|
||||
};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, SharedString, Task, TextStyle, WhiteSpace,
|
||||
Window,
|
||||
};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task, Window};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, ConfigurationViewTargetAgent, LanguageModelCompletionError,
|
||||
|
|
@ -32,8 +28,8 @@ use std::sync::{
|
|||
atomic::{self, AtomicU64},
|
||||
};
|
||||
use strum::IntoEnumIterator;
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Icon, IconName, List, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::{ResultExt, truncate_and_trailoff};
|
||||
use zed_env_vars::EnvVar;
|
||||
|
||||
|
|
@ -63,7 +59,7 @@ pub enum ModelMode {
|
|||
|
||||
pub struct GoogleLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -165,7 +161,7 @@ impl GoogleLanguageModelProvider {
|
|||
impl LanguageModelProviderState for GoogleLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +251,7 @@ impl LanguageModelProvider for GoogleLanguageModelProvider {
|
|||
pub struct GoogleLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: google_ai::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -755,15 +751,15 @@ fn convert_usage(usage: &UsageMetadata) -> language_model::TokenUsage {
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
target_agent: language_model::ConfigurationViewTargetAgent,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
target_agent: language_model::ConfigurationViewTargetAgent,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
|
@ -792,11 +788,7 @@ impl ConfigurationView {
|
|||
}));
|
||||
|
||||
Self {
|
||||
api_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("AIzaSy...", window, cx);
|
||||
editor
|
||||
}),
|
||||
api_key_editor: cx.new(|cx| SingleLineInput::new(window, cx, "AIzaSy...")),
|
||||
target_agent,
|
||||
state,
|
||||
load_credentials_task,
|
||||
|
|
@ -835,31 +827,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -890,18 +857,7 @@ impl Render for ConfigurationView {
|
|||
"Paste your API key below and hit enter to start using the assistant",
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.rounded_sm()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(self.api_key_editor.clone())
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {GEMINI_API_KEY_VAR_NAME} environment variable and restart Zed."),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{Result, anyhow};
|
|||
use collections::HashMap;
|
||||
use futures::Stream;
|
||||
use futures::{FutureExt, StreamExt, future::BoxFuture, stream::BoxStream};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Subscription, Task};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, Subscription, Task};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||
|
|
@ -41,7 +41,7 @@ pub struct LmStudioSettings {
|
|||
|
||||
pub struct LmStudioLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -162,7 +162,7 @@ impl LmStudioLanguageModelProvider {
|
|||
impl LanguageModelProviderState for LmStudioLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -635,12 +635,12 @@ fn add_message_content_part(
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
loading_models_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
pub fn new(state: gpui::Entity<State>, cx: &mut Context<Self>) -> Self {
|
||||
pub fn new(state: Entity<State>, cx: &mut Context<Self>) -> Self {
|
||||
let loading_models_task = Some(cx.spawn({
|
||||
let state = state.clone();
|
||||
async move |this, cx| {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
use anyhow::{Result, anyhow};
|
||||
use collections::BTreeMap;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{FutureExt, Stream, StreamExt, future, future::BoxFuture, stream::BoxStream};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, SharedString, Task, TextStyle, WhiteSpace,
|
||||
Window,
|
||||
};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task, Window};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||
|
|
@ -22,8 +18,8 @@ use std::pin::Pin;
|
|||
use std::str::FromStr;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use strum::IntoEnumIterator;
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Icon, IconName, List, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::{ResultExt, truncate_and_trailoff};
|
||||
use zed_env_vars::{EnvVar, env_var};
|
||||
|
||||
|
|
@ -43,7 +39,7 @@ pub struct MistralSettings {
|
|||
|
||||
pub struct MistralLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -121,7 +117,7 @@ impl MistralLanguageModelProvider {
|
|||
impl LanguageModelProviderState for MistralLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +211,7 @@ impl LanguageModelProvider for MistralLanguageModelProvider {
|
|||
pub struct MistralLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: mistral::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -694,18 +690,15 @@ struct RawToolCall {
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("0aBCDEFGhIjKLmNOpqrSTUVwxyzabCDE1f2", window, cx);
|
||||
editor
|
||||
});
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor =
|
||||
cx.new(|cx| SingleLineInput::new(window, cx, "0aBCDEFGhIjKLmNOpqrSTUVwxyzabCDE1f2"));
|
||||
|
||||
cx.observe(&state, |_, _, cx| {
|
||||
cx.notify();
|
||||
|
|
@ -770,31 +763,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -825,18 +793,7 @@ impl Render for ConfigurationView {
|
|||
"Paste your API key below and hit enter to start using the assistant",
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.rounded_sm()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(self.api_key_editor.clone())
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {API_KEY_ENV_VAR_NAME} environment variable and restart Zed."),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{Result, anyhow};
|
|||
use fs::Fs;
|
||||
use futures::{FutureExt, StreamExt, future::BoxFuture, stream::BoxStream};
|
||||
use futures::{Stream, TryFutureExt, stream};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Task};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, CursorStyle, Entity, Task};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||
|
|
@ -48,7 +48,7 @@ pub struct OllamaSettings {
|
|||
|
||||
pub struct OllamaLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -209,7 +209,7 @@ impl OllamaLanguageModelProvider {
|
|||
impl LanguageModelProviderState for OllamaLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ pub struct OllamaLanguageModel {
|
|||
model: ollama::Model,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
impl OllamaLanguageModel {
|
||||
|
|
@ -623,13 +623,13 @@ fn map_to_language_model_completion_events(
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: gpui::Entity<SingleLineInput>,
|
||||
api_url_editor: gpui::Entity<SingleLineInput>,
|
||||
state: gpui::Entity<State>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
api_url_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
pub fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
pub fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor =
|
||||
cx.new(|cx| SingleLineInput::new(window, cx, "63e02e...").label("API key"));
|
||||
|
||||
|
|
@ -900,7 +900,7 @@ impl Render for ConfigurationView {
|
|||
this.child(
|
||||
ButtonLike::new("connected")
|
||||
.disabled(true)
|
||||
.cursor_style(gpui::CursorStyle::Arrow)
|
||||
.cursor_style(CursorStyle::Arrow)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub struct OpenAiSettings {
|
|||
|
||||
pub struct OpenAiLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -119,7 +119,7 @@ impl OpenAiLanguageModelProvider {
|
|||
impl LanguageModelProviderState for OpenAiLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +203,7 @@ impl LanguageModelProvider for OpenAiLanguageModelProvider {
|
|||
pub struct OpenAiLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: open_ai::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -676,12 +676,12 @@ pub fn count_open_ai_tokens(
|
|||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
SingleLineInput::new(
|
||||
window,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub struct OpenAiCompatibleLanguageModelProvider {
|
|||
id: LanguageModelProviderId,
|
||||
name: LanguageModelProviderName,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -125,7 +125,7 @@ impl OpenAiCompatibleLanguageModelProvider {
|
|||
impl LanguageModelProviderState for OpenAiCompatibleLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ pub struct OpenAiCompatibleLanguageModel {
|
|||
provider_id: LanguageModelProviderId,
|
||||
provider_name: LanguageModelProviderName,
|
||||
model: AvailableModel,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -341,12 +341,12 @@ impl LanguageModel for OpenAiCompatibleLanguageModel {
|
|||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
SingleLineInput::new(
|
||||
window,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
use anyhow::{Result, anyhow};
|
||||
use collections::HashMap;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{FutureExt, Stream, StreamExt, future, future::BoxFuture};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, SharedString, Task, TextStyle, WhiteSpace,
|
||||
};
|
||||
use gpui::{AnyView, App, AsyncApp, Context, Entity, SharedString, Task};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModel, LanguageModelCompletionError, LanguageModelCompletionEvent,
|
||||
|
|
@ -20,8 +17,8 @@ use settings::{OpenRouterAvailableModel as AvailableModel, Settings, SettingsSto
|
|||
use std::pin::Pin;
|
||||
use std::str::FromStr as _;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{Icon, IconName, List, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use util::{ResultExt, truncate_and_trailoff};
|
||||
use zed_env_vars::{EnvVar, env_var};
|
||||
|
||||
|
|
@ -41,7 +38,7 @@ pub struct OpenRouterSettings {
|
|||
|
||||
pub struct OpenRouterLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -174,7 +171,7 @@ impl OpenRouterLanguageModelProvider {
|
|||
impl LanguageModelProviderState for OpenRouterLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -260,7 +257,7 @@ impl LanguageModelProvider for OpenRouterLanguageModelProvider {
|
|||
pub struct OpenRouterLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: open_router::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -695,21 +692,19 @@ pub fn count_open_router_tokens(
|
|||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(
|
||||
"sk_or_000000000000000000000000000000000000000000000000",
|
||||
SingleLineInput::new(
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
"sk_or_000000000000000000000000000000000000000000000000",
|
||||
)
|
||||
});
|
||||
|
||||
cx.observe(&state, |_, _, cx| {
|
||||
|
|
@ -774,31 +769,6 @@ impl ConfigurationView {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
|
@ -829,18 +799,7 @@ impl Render for ConfigurationView {
|
|||
"Paste your API key below and hit enter to start using the assistant",
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.rounded_sm()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(self.api_key_editor.clone())
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {API_KEY_ENV_VAR_NAME} environment variable and restart Zed."),
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub struct VercelSettings {
|
|||
|
||||
pub struct VercelLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -114,7 +114,7 @@ impl VercelLanguageModelProvider {
|
|||
impl LanguageModelProviderState for VercelLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ impl LanguageModelProvider for VercelLanguageModelProvider {
|
|||
pub struct VercelLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: vercel::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -363,12 +363,12 @@ pub fn count_vercel_tokens(
|
|||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
SingleLineInput::new(
|
||||
window,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub struct XAiSettings {
|
|||
|
||||
pub struct XAiLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
@ -114,7 +114,7 @@ impl XAiLanguageModelProvider {
|
|||
impl LanguageModelProviderState for XAiLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
fn observable_entity(&self) -> Option<Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ impl LanguageModelProvider for XAiLanguageModelProvider {
|
|||
pub struct XAiLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: x_ai::Model,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
|
@ -357,12 +357,12 @@ pub fn count_xai_tokens(
|
|||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<SingleLineInput>,
|
||||
state: gpui::Entity<State>,
|
||||
state: Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
SingleLineInput::new(
|
||||
window,
|
||||
|
|
|
|||
Loading…
Reference in a new issue