diff --git a/Cargo.lock b/Cargo.lock
index 2ab8ee9169732eafc2bbc1a52a86be4964612e7d..1bedec094f7d5a45cda5c25462a24f4b94cde9c3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1380,6 +1380,7 @@ dependencies = [
"schemars",
"serde",
"serde_derive",
+ "serde_json",
"settings",
"smol",
"sum_tree",
@@ -1545,6 +1546,7 @@ dependencies = [
"schemars",
"serde",
"serde_derive",
+ "serde_json",
"settings",
"smallvec",
"theme",
@@ -2490,6 +2492,7 @@ dependencies = [
"regex",
"serde",
"serde_derive",
+ "serde_json",
"settings",
"smallvec",
"smol",
@@ -3784,6 +3787,7 @@ dependencies = [
"lsp",
"project",
"serde",
+ "serde_json",
"settings",
"theme",
"tree-sitter",
@@ -5511,6 +5515,7 @@ dependencies = [
"picker",
"postage",
"project",
+ "serde_json",
"settings",
"smol",
"text",
@@ -7764,6 +7769,7 @@ dependencies = [
"search",
"serde",
"serde_derive",
+ "serde_json",
"settings",
"shellexpand",
"smallvec",
@@ -7844,6 +7850,7 @@ dependencies = [
"pathfinder_color",
"rust-embed",
"serde",
+ "serde_json",
"simplelog",
"strum",
"theme",
diff --git a/assets/icons/arrow_circle.svg b/assets/icons/arrow_circle.svg
index 750e349e2b8c73ef0c78b9974ea100f70ae37abe..90e352bdea7a208356139bed8af5bb3c1301b5ce 100644
--- a/assets/icons/arrow_circle.svg
+++ b/assets/icons/arrow_circle.svg
@@ -1 +1,6 @@
-
+
diff --git a/crates/ai/src/providers/open_ai/embedding.rs b/crates/ai/src/providers/open_ai/embedding.rs
index d5fe4e8c5842709c587b9898862e0a2461461ed2..0a9b6ba969c7c519d337ae27db45af12252efa0b 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::AppContext;
use gpui::BackgroundExecutor;
-use gpui::{serde_json, AppContext};
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;
diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs
index 452538b9103e99f1f8dd281ffcfb26f35e2f9540..f53343531af09083999e04f1d3dce92eafe34850 100644
--- a/crates/assistant/src/assistant_panel.rs
+++ b/crates/assistant/src/assistant_panel.rs
@@ -2298,11 +2298,10 @@ impl ConversationEditor {
move |_cx| {
let message_id = message.id;
let sender = ButtonLike::new("role")
+ .style(ButtonStyle::Filled)
.child(match message.role {
Role::User => Label::new("You").color(Color::Default),
- Role::Assistant => {
- Label::new("Assistant").color(Color::Modified)
- }
+ Role::Assistant => Label::new("Assistant").color(Color::Info),
Role::System => Label::new("System").color(Color::Warning),
})
.tooltip(|cx| {
@@ -2325,11 +2324,12 @@ impl ConversationEditor {
}
});
- h_stack()
+ div()
+ .h_flex()
.id(("message_header", message_id.0))
.h_11()
+ .relative()
.gap_1()
- .p_1()
.child(sender)
// TODO: Only show this if the message if the message has been sent
.child(
@@ -2538,7 +2538,7 @@ impl Render for ConversationEditor {
.child(
div()
.size_full()
- .pl_2()
+ .pl_4()
.bg(cx.theme().colors().editor_background)
.child(self.editor.clone()),
)
@@ -3538,5 +3538,5 @@ fn report_assistant_event(
.default_open_ai_model
.clone();
- telemetry.report_assistant_event(conversation_id, assistant_kind, model.full_name(), cx)
+ telemetry.report_assistant_event(conversation_id, assistant_kind, model.full_name())
}
diff --git a/crates/call/src/call.rs b/crates/call/src/call.rs
index c419043a722b35fb34f33a224502057e53f3a16b..3561cc33852a84d78ed21371432743d9dc540862 100644
--- a/crates/call/src/call.rs
+++ b/crates/call/src/call.rs
@@ -310,14 +310,14 @@ impl ActiveCall {
})
}
- pub fn decline_incoming(&mut self, cx: &mut ModelContext) -> Result<()> {
+ pub fn decline_incoming(&mut self, _: &mut ModelContext) -> Result<()> {
let call = self
.incoming_call
.0
.borrow_mut()
.take()
.ok_or_else(|| anyhow!("no incoming call"))?;
- report_call_event_for_room("decline incoming", call.room_id, None, &self.client, cx);
+ report_call_event_for_room("decline incoming", call.room_id, None, &self.client);
self.client.send(proto::DeclineCall {
room_id: call.room_id,
})?;
@@ -467,7 +467,7 @@ impl ActiveCall {
pub fn report_call_event(&self, operation: &'static str, cx: &mut AppContext) {
if let Some(room) = self.room() {
let room = room.read(cx);
- report_call_event_for_room(operation, room.id(), room.channel_id(), &self.client, cx);
+ report_call_event_for_room(operation, room.id(), room.channel_id(), &self.client);
}
}
}
@@ -477,11 +477,10 @@ pub fn report_call_event_for_room(
room_id: u64,
channel_id: Option,
client: &Arc,
- cx: &mut AppContext,
) {
let telemetry = client.telemetry();
- telemetry.report_call_event(operation, Some(room_id), channel_id, cx)
+ telemetry.report_call_event(operation, Some(room_id), channel_id)
}
pub fn report_call_event_for_channel(
@@ -494,12 +493,7 @@ pub fn report_call_event_for_channel(
let telemetry = client.telemetry();
- telemetry.report_call_event(
- operation,
- room.map(|r| r.read(cx).id()),
- Some(channel_id),
- cx,
- )
+ telemetry.report_call_event(operation, room.map(|r| r.read(cx).id()), Some(channel_id))
}
#[cfg(test)]
diff --git a/crates/channel/src/channel_store_tests.rs b/crates/channel/src/channel_store_tests.rs
index 20413d7a76ff96a1052a828c1b08f1b884d56ed7..0b07918acfba7b9fe3ad87ef001f5fb7c5eafb30 100644
--- a/crates/channel/src/channel_store_tests.rs
+++ b/crates/channel/src/channel_store_tests.rs
@@ -343,12 +343,13 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
}
fn init_test(cx: &mut AppContext) -> Model {
+ let settings_store = SettingsStore::test(cx);
+ cx.set_global(settings_store);
+
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
- let settings_store = SettingsStore::test(cx);
- cx.set_global(settings_store);
client::init(&client, cx);
crate::init(&client, user_store, cx);
diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml
index c24cbca35be25aeca198cd9178467bfb93db2969..03d6c06fe399842cad6a6de6057503d5f43a5bbb 100644
--- a/crates/client/Cargo.toml
+++ b/crates/client/Cargo.toml
@@ -36,6 +36,7 @@ rand.workspace = true
schemars.workspace = true
serde.workspace = true
serde_derive.workspace = true
+serde_json.workspace = true
smol.workspace = true
sysinfo.workspace = true
tempfile = "3"
diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs
index 2f1e234b7303c1787fe2e6ec806ad94218e9e196..3eae9d92bb9f8d75cbf7ddb63eab26fdd70ecdc4 100644
--- a/crates/client/src/client.rs
+++ b/crates/client/src/client.rs
@@ -15,8 +15,8 @@ use futures::{
TryFutureExt as _, TryStreamExt,
};
use gpui::{
- actions, serde_json, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Model,
- SemanticVersion, Task, WeakModel,
+ actions, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Model, SemanticVersion, Task,
+ WeakModel,
};
use lazy_static::lazy_static;
use parking_lot::RwLock;
@@ -25,6 +25,7 @@ use rand::prelude::*;
use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, RequestMessage};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
+use serde_json;
use settings::Settings;
use std::{
any::TypeId,
@@ -45,7 +46,7 @@ use util::http::HttpClient;
use util::{ResultExt, TryFutureExt};
pub use rpc::*;
-pub use telemetry::ClickhouseEvent;
+pub use telemetry::Event;
pub use user::*;
lazy_static! {
@@ -501,8 +502,7 @@ impl Client {
}));
}
Status::SignedOut | Status::UpgradeRequired => {
- cx.update(|cx| self.telemetry.set_authenticated_user_info(None, false, cx))
- .log_err();
+ self.telemetry.set_authenticated_user_info(None, false);
state._reconnect_task.take();
}
_ => {}
@@ -1405,11 +1405,13 @@ mod tests {
use gpui::{BackgroundExecutor, Context, TestAppContext};
use parking_lot::Mutex;
+ use settings::SettingsStore;
use std::future;
use util::http::FakeHttpClient;
#[gpui::test(iterations = 10)]
async fn test_reconnection(cx: &mut TestAppContext) {
+ init_test(cx);
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
@@ -1444,6 +1446,7 @@ mod tests {
#[gpui::test(iterations = 10)]
async fn test_connection_timeout(executor: BackgroundExecutor, cx: &mut TestAppContext) {
+ init_test(cx);
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let mut status = client.status();
@@ -1515,6 +1518,7 @@ mod tests {
cx: &mut TestAppContext,
executor: BackgroundExecutor,
) {
+ init_test(cx);
let auth_count = Arc::new(Mutex::new(0));
let dropped_auth_count = Arc::new(Mutex::new(0));
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
@@ -1563,6 +1567,7 @@ mod tests {
#[gpui::test]
async fn test_subscribing_to_entity(cx: &mut TestAppContext) {
+ init_test(cx);
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
@@ -1616,6 +1621,7 @@ mod tests {
#[gpui::test]
async fn test_subscribing_after_dropping_subscription(cx: &mut TestAppContext) {
+ init_test(cx);
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
@@ -1644,6 +1650,7 @@ mod tests {
#[gpui::test]
async fn test_dropping_subscription_in_handler(cx: &mut TestAppContext) {
+ init_test(cx);
let user_id = 5;
let client = cx.update(|cx| Client::new(FakeHttpClient::with_404_response(), cx));
let server = FakeServer::for_client(user_id, &client, cx).await;
@@ -1672,4 +1679,11 @@ mod tests {
id: usize,
subscription: Option,
}
+
+ fn init_test(cx: &mut TestAppContext) {
+ cx.update(|cx| {
+ let settings_store = SettingsStore::test(cx);
+ cx.set_global(settings_store);
+ });
+ }
}
diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs
index 2391c5f3b55a0c96133ed82ae964ecd969cc68e2..26b5748187ff735ebedf2cdb38753bdb6d9fcedc 100644
--- a/crates/client/src/telemetry.rs
+++ b/crates/client/src/telemetry.rs
@@ -1,11 +1,12 @@
use crate::{TelemetrySettings, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
use chrono::{DateTime, Utc};
use futures::Future;
-use gpui::{serde_json, AppContext, AppMetadata, BackgroundExecutor, Task};
+use gpui::{AppContext, AppMetadata, BackgroundExecutor, Task};
use lazy_static::lazy_static;
use parking_lot::Mutex;
use serde::Serialize;
-use settings::Settings;
+use serde_json;
+use settings::{Settings, SettingsStore};
use std::{env, io::Write, mem, path::PathBuf, sync::Arc, time::Duration};
use sysinfo::{
CpuRefreshKind, Pid, PidExt, ProcessExt, ProcessRefreshKind, RefreshKind, System, SystemExt,
@@ -17,32 +18,32 @@ use util::{channel::ReleaseChannel, TryFutureExt};
pub struct Telemetry {
http_client: Arc,
executor: BackgroundExecutor,
- state: Mutex,
+ state: Arc>,
}
struct TelemetryState {
+ settings: TelemetrySettings,
metrics_id: Option>, // Per logged-in user
installation_id: Option>, // Per app installation (different for dev, nightly, preview, and stable)
session_id: Option>, // Per app launch
release_channel: Option<&'static str>,
app_metadata: AppMetadata,
architecture: &'static str,
- clickhouse_events_queue: Vec,
- flush_clickhouse_events_task: Option>,
+ events_queue: Vec,
+ flush_events_task: Option>,
log_file: Option,
is_staff: Option,
first_event_datetime: Option>,
}
-const CLICKHOUSE_EVENTS_URL_PATH: &'static str = "/api/events";
+const EVENTS_URL_PATH: &'static str = "/api/events";
lazy_static! {
- static ref CLICKHOUSE_EVENTS_URL: String =
- format!("{}{}", *ZED_SERVER_URL, CLICKHOUSE_EVENTS_URL_PATH);
+ static ref EVENTS_URL: String = format!("{}{}", *ZED_SERVER_URL, EVENTS_URL_PATH);
}
#[derive(Serialize, Debug)]
-struct ClickhouseEventRequestBody {
+struct EventRequestBody {
token: &'static str,
installation_id: Option>,
session_id: Option>,
@@ -52,14 +53,14 @@ struct ClickhouseEventRequestBody {
os_version: Option,
architecture: &'static str,
release_channel: Option<&'static str>,
- events: Vec,
+ events: Vec,
}
#[derive(Serialize, Debug)]
-struct ClickhouseEventWrapper {
+struct EventWrapper {
signed_in: bool,
#[serde(flatten)]
- event: ClickhouseEvent,
+ event: Event,
}
#[derive(Serialize, Debug)]
@@ -71,7 +72,7 @@ pub enum AssistantKind {
#[derive(Serialize, Debug)]
#[serde(tag = "type")]
-pub enum ClickhouseEvent {
+pub enum Event {
Editor {
operation: &'static str,
file_extension: Option,
@@ -139,45 +140,61 @@ impl Telemetry {
None
};
+ TelemetrySettings::register(cx);
+
+ let state = Arc::new(Mutex::new(TelemetryState {
+ settings: TelemetrySettings::get_global(cx).clone(),
+ app_metadata: cx.app_metadata(),
+ architecture: env::consts::ARCH,
+ release_channel,
+ installation_id: None,
+ metrics_id: None,
+ session_id: None,
+ events_queue: Default::default(),
+ flush_events_task: Default::default(),
+ log_file: None,
+ is_staff: None,
+ first_event_datetime: None,
+ }));
+
+ cx.observe_global::({
+ let state = state.clone();
+
+ move |cx| {
+ let mut state = state.lock();
+ state.settings = TelemetrySettings::get_global(cx).clone();
+ }
+ })
+ .detach();
+
// TODO: Replace all hardware stuff with nested SystemSpecs json
let this = Arc::new(Self {
http_client: client,
executor: cx.background_executor().clone(),
- state: Mutex::new(TelemetryState {
- app_metadata: cx.app_metadata(),
- architecture: env::consts::ARCH,
- release_channel,
- installation_id: None,
- metrics_id: None,
- session_id: None,
- clickhouse_events_queue: Default::default(),
- flush_clickhouse_events_task: Default::default(),
- log_file: None,
- is_staff: None,
- first_event_datetime: None,
- }),
+ state,
});
// We should only ever have one instance of Telemetry, leak the subscription to keep it alive
// rather than store in TelemetryState, complicating spawn as subscriptions are not Send
std::mem::forget(cx.on_app_quit({
let this = this.clone();
- move |cx| this.shutdown_telemetry(cx)
+ move |_| this.shutdown_telemetry()
}));
this
}
#[cfg(any(test, feature = "test-support"))]
- fn shutdown_telemetry(self: &Arc, _: &mut AppContext) -> impl Future