;
-
- fn render(&mut self, cx: &mut ViewContext
) -> Self::Element {
- let content = self.content_to_render(cx);
-
- let mut result = h_stack()
- .id("activity-indicator")
- .on_action(cx.listener(Self::show_error_message))
- .on_action(cx.listener(Self::dismiss_error_message));
-
- if let Some(on_click) = content.on_click {
- result = result
- .cursor(CursorStyle::PointingHand)
- .on_click(cx.listener(move |this, _, cx| {
- on_click(this, cx);
- }))
- }
-
- result
- .children(content.icon.map(|icon| svg().path(icon)))
- .child(SharedString::from(content.message))
- }
-}
-
-impl StatusItemView for ActivityIndicator {
- fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, _: &mut ViewContext) {}
-}
diff --git a/crates/ai/src/auth.rs b/crates/ai/src/auth.rs
index c6256df216..1ea49bd615 100644
--- a/crates/ai/src/auth.rs
+++ b/crates/ai/src/auth.rs
@@ -9,7 +9,7 @@ pub enum ProviderCredential {
pub trait CredentialProvider: Send + Sync {
fn has_credentials(&self) -> bool;
- fn retrieve_credentials(&self, cx: &AppContext) -> ProviderCredential;
- fn save_credentials(&self, cx: &AppContext, credential: ProviderCredential);
- fn delete_credentials(&self, cx: &AppContext);
+ fn retrieve_credentials(&self, cx: &mut AppContext) -> ProviderCredential;
+ fn save_credentials(&self, cx: &mut AppContext, credential: ProviderCredential);
+ fn delete_credentials(&self, cx: &mut AppContext);
}
diff --git a/crates/ai/src/prompts/repository_context.rs b/crates/ai/src/prompts/repository_context.rs
index c21b0f995c..0d831c2cb2 100644
--- a/crates/ai/src/prompts/repository_context.rs
+++ b/crates/ai/src/prompts/repository_context.rs
@@ -2,7 +2,7 @@ use crate::prompts::base::{PromptArguments, PromptTemplate};
use std::fmt::Write;
use std::{ops::Range, path::PathBuf};
-use gpui::{AsyncAppContext, ModelHandle};
+use gpui::{AsyncAppContext, Model};
use language::{Anchor, Buffer};
#[derive(Clone)]
@@ -13,8 +13,12 @@ pub struct PromptCodeSnippet {
}
impl PromptCodeSnippet {
- pub fn new(buffer: ModelHandle, range: Range, cx: &AsyncAppContext) -> Self {
- let (content, language_name, file_path) = buffer.read_with(cx, |buffer, _| {
+ pub fn new(
+ buffer: Model,
+ range: Range,
+ cx: &mut AsyncAppContext,
+ ) -> anyhow::Result {
+ let (content, language_name, file_path) = buffer.update(cx, |buffer, _| {
let snapshot = buffer.snapshot();
let content = snapshot.text_for_range(range.clone()).collect::();
@@ -27,13 +31,13 @@ impl PromptCodeSnippet {
.and_then(|file| Some(file.path().to_path_buf()));
(content, language_name, file_path)
- });
+ })?;
- PromptCodeSnippet {
+ anyhow::Ok(PromptCodeSnippet {
path: file_path,
language_name,
content,
- }
+ })
}
}
diff --git a/crates/ai/src/providers/open_ai/completion.rs b/crates/ai/src/providers/open_ai/completion.rs
index 94685fd233..c9a2abd0c8 100644
--- a/crates/ai/src/providers/open_ai/completion.rs
+++ b/crates/ai/src/providers/open_ai/completion.rs
@@ -3,7 +3,7 @@ use futures::{
future::BoxFuture, io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, FutureExt,
Stream, StreamExt,
};
-use gpui::{executor::Background, AppContext};
+use gpui::{AppContext, BackgroundExecutor};
use isahc::{http::StatusCode, Request, RequestExt};
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
@@ -104,7 +104,7 @@ pub struct OpenAIResponseStreamEvent {
pub async fn stream_completion(
credential: ProviderCredential,
- executor: Arc,
+ executor: BackgroundExecutor,
request: Box,
) -> Result>> {
let api_key = match credential {
@@ -197,11 +197,11 @@ pub async fn stream_completion(
pub struct OpenAICompletionProvider {
model: OpenAILanguageModel,
credential: Arc>,
- executor: Arc,
+ executor: BackgroundExecutor,
}
impl OpenAICompletionProvider {
- pub fn new(model_name: &str, executor: Arc) -> Self {
+ pub fn new(model_name: &str, executor: BackgroundExecutor) -> Self {
let model = OpenAILanguageModel::load(model_name);
let credential = Arc::new(RwLock::new(ProviderCredential::NoCredentials));
Self {
@@ -219,46 +219,45 @@ impl CredentialProvider for OpenAICompletionProvider {
_ => false,
}
}
- fn retrieve_credentials(&self, cx: &AppContext) -> ProviderCredential {
- let mut credential = self.credential.write();
- match *credential {
- ProviderCredential::Credentials { .. } => {
- return credential.clone();
- }
+
+ fn retrieve_credentials(&self, cx: &mut AppContext) -> ProviderCredential {
+ let existing_credential = self.credential.read().clone();
+ let retrieved_credential = match existing_credential {
+ ProviderCredential::Credentials { .. } => existing_credential.clone(),
_ => {
- if let Ok(api_key) = env::var("OPENAI_API_KEY") {
- *credential = ProviderCredential::Credentials { api_key };
- } else if let Some((_, api_key)) = cx
- .platform()
- .read_credentials(OPENAI_API_URL)
- .log_err()
- .flatten()
+ if let Some(api_key) = env::var("OPENAI_API_KEY").log_err() {
+ ProviderCredential::Credentials { api_key }
+ } else if let Some(Some((_, api_key))) =
+ cx.read_credentials(OPENAI_API_URL).log_err()
{
if let Some(api_key) = String::from_utf8(api_key).log_err() {
- *credential = ProviderCredential::Credentials { api_key };
+ ProviderCredential::Credentials { api_key }
+ } else {
+ ProviderCredential::NoCredentials
}
} else {
- };
+ ProviderCredential::NoCredentials
+ }
}
- }
-
- credential.clone()
+ };
+ *self.credential.write() = retrieved_credential.clone();
+ retrieved_credential
}
- fn save_credentials(&self, cx: &AppContext, credential: ProviderCredential) {
- match credential.clone() {
+ fn save_credentials(&self, cx: &mut AppContext, credential: ProviderCredential) {
+ *self.credential.write() = credential.clone();
+ let credential = credential.clone();
+ match credential {
ProviderCredential::Credentials { api_key } => {
- cx.platform()
- .write_credentials(OPENAI_API_URL, "Bearer", api_key.as_bytes())
+ cx.write_credentials(OPENAI_API_URL, "Bearer", api_key.as_bytes())
.log_err();
}
_ => {}
}
-
- *self.credential.write() = credential;
}
- fn delete_credentials(&self, cx: &AppContext) {
- cx.platform().delete_credentials(OPENAI_API_URL).log_err();
+
+ fn delete_credentials(&self, cx: &mut AppContext) {
+ cx.delete_credentials(OPENAI_API_URL).log_err();
*self.credential.write() = ProviderCredential::NoCredentials;
}
}
diff --git a/crates/ai/src/providers/open_ai/embedding.rs b/crates/ai/src/providers/open_ai/embedding.rs
index fbfd0028f9..0a9b6ba969 100644
--- a/crates/ai/src/providers/open_ai/embedding.rs
+++ b/crates/ai/src/providers/open_ai/embedding.rs
@@ -1,8 +1,8 @@
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures::AsyncReadExt;
-use gpui::executor::Background;
-use gpui::{serde_json, AppContext};
+use gpui::AppContext;
+use gpui::BackgroundExecutor;
use isahc::http::StatusCode;
use isahc::prelude::Configurable;
use isahc::{AsyncBody, Response};
@@ -11,6 +11,7 @@ use parking_lot::{Mutex, RwLock};
use parse_duration::parse;
use postage::watch;
use serde::{Deserialize, Serialize};
+use serde_json;
use std::env;
use std::ops::Add;
use std::sync::Arc;
@@ -35,7 +36,7 @@ pub struct OpenAIEmbeddingProvider {
model: OpenAILanguageModel,
credential: Arc>,
pub client: Arc,
- pub executor: Arc,
+ pub executor: BackgroundExecutor,
rate_limit_count_rx: watch::Receiver