mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 21:32:40 +00:00
parent
b9c1f3d558
commit
5df9a57a8b
6 changed files with 77 additions and 4 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -101,6 +101,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"client",
|
||||||
"collections",
|
"collections",
|
||||||
"ctor",
|
"ctor",
|
||||||
"editor",
|
"editor",
|
||||||
|
@ -127,6 +128,7 @@ dependencies = [
|
||||||
"theme",
|
"theme",
|
||||||
"tiktoken-rs 0.4.5",
|
"tiktoken-rs 0.4.5",
|
||||||
"util",
|
"util",
|
||||||
|
"uuid 1.4.1",
|
||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ path = "src/ai.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
client = { path = "../client" }
|
||||||
collections = { path = "../collections"}
|
collections = { path = "../collections"}
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
fs = { path = "../fs" }
|
fs = { path = "../fs" }
|
||||||
|
@ -19,6 +20,7 @@ search = { path = "../search" }
|
||||||
settings = { path = "../settings" }
|
settings = { path = "../settings" }
|
||||||
theme = { path = "../theme" }
|
theme = { path = "../theme" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
|
uuid = { version = "1.1.2", features = ["v4"] }
|
||||||
workspace = { path = "../workspace" }
|
workspace = { path = "../workspace" }
|
||||||
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct SavedMessage {
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct SavedConversation {
|
struct SavedConversation {
|
||||||
|
id: Option<String>,
|
||||||
zed: String,
|
zed: String,
|
||||||
version: String,
|
version: String,
|
||||||
text: String,
|
text: String,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
|
use client::{telemetry::AssistantKind, ClickhouseEvent, TelemetrySettings};
|
||||||
use collections::{hash_map, HashMap, HashSet, VecDeque};
|
use collections::{hash_map, HashMap, HashSet, VecDeque};
|
||||||
use editor::{
|
use editor::{
|
||||||
display_map::{
|
display_map::{
|
||||||
|
@ -48,6 +49,7 @@ use theme::{
|
||||||
AssistantStyle,
|
AssistantStyle,
|
||||||
};
|
};
|
||||||
use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt};
|
use util::{paths::CONVERSATIONS_DIR, post_inc, ResultExt, TryFutureExt};
|
||||||
|
use uuid::Uuid;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel},
|
dock::{DockPosition, Panel},
|
||||||
searchable::Direction,
|
searchable::Direction,
|
||||||
|
@ -296,6 +298,7 @@ impl AssistantPanel {
|
||||||
self.include_conversation_in_next_inline_assist,
|
self.include_conversation_in_next_inline_assist,
|
||||||
self.inline_prompt_history.clone(),
|
self.inline_prompt_history.clone(),
|
||||||
codegen.clone(),
|
codegen.clone(),
|
||||||
|
self.workspace.clone(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
cx.focus_self();
|
cx.focus_self();
|
||||||
|
@ -724,6 +727,7 @@ impl AssistantPanel {
|
||||||
self.api_key.clone(),
|
self.api_key.clone(),
|
||||||
self.languages.clone(),
|
self.languages.clone(),
|
||||||
self.fs.clone(),
|
self.fs.clone(),
|
||||||
|
self.workspace.clone(),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1059,6 +1063,7 @@ impl AssistantPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
let fs = self.fs.clone();
|
let fs = self.fs.clone();
|
||||||
|
let workspace = self.workspace.clone();
|
||||||
let api_key = self.api_key.clone();
|
let api_key = self.api_key.clone();
|
||||||
let languages = self.languages.clone();
|
let languages = self.languages.clone();
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
|
@ -1073,8 +1078,9 @@ impl AssistantPanel {
|
||||||
if let Some(ix) = this.editor_index_for_path(&path, cx) {
|
if let Some(ix) = this.editor_index_for_path(&path, cx) {
|
||||||
this.set_active_editor_index(Some(ix), cx);
|
this.set_active_editor_index(Some(ix), cx);
|
||||||
} else {
|
} else {
|
||||||
let editor = cx
|
let editor = cx.add_view(|cx| {
|
||||||
.add_view(|cx| ConversationEditor::for_conversation(conversation, fs, cx));
|
ConversationEditor::for_conversation(conversation, fs, workspace, cx)
|
||||||
|
});
|
||||||
this.add_conversation(editor, cx);
|
this.add_conversation(editor, cx);
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
@ -1348,6 +1354,7 @@ struct Summary {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Conversation {
|
struct Conversation {
|
||||||
|
id: Option<String>,
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
message_anchors: Vec<MessageAnchor>,
|
message_anchors: Vec<MessageAnchor>,
|
||||||
messages_metadata: HashMap<MessageId, MessageMetadata>,
|
messages_metadata: HashMap<MessageId, MessageMetadata>,
|
||||||
|
@ -1398,6 +1405,7 @@ impl Conversation {
|
||||||
let model = settings.default_open_ai_model.clone();
|
let model = settings.default_open_ai_model.clone();
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
id: Some(Uuid::new_v4().to_string()),
|
||||||
message_anchors: Default::default(),
|
message_anchors: Default::default(),
|
||||||
messages_metadata: Default::default(),
|
messages_metadata: Default::default(),
|
||||||
next_message_id: Default::default(),
|
next_message_id: Default::default(),
|
||||||
|
@ -1435,6 +1443,7 @@ impl Conversation {
|
||||||
|
|
||||||
fn serialize(&self, cx: &AppContext) -> SavedConversation {
|
fn serialize(&self, cx: &AppContext) -> SavedConversation {
|
||||||
SavedConversation {
|
SavedConversation {
|
||||||
|
id: self.id.clone(),
|
||||||
zed: "conversation".into(),
|
zed: "conversation".into(),
|
||||||
version: SavedConversation::VERSION.into(),
|
version: SavedConversation::VERSION.into(),
|
||||||
text: self.buffer.read(cx).text(),
|
text: self.buffer.read(cx).text(),
|
||||||
|
@ -1462,6 +1471,10 @@ impl Conversation {
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let id = match saved_conversation.id {
|
||||||
|
Some(id) => Some(id),
|
||||||
|
None => Some(Uuid::new_v4().to_string()),
|
||||||
|
};
|
||||||
let model = saved_conversation.model;
|
let model = saved_conversation.model;
|
||||||
let markdown = language_registry.language_for_name("Markdown");
|
let markdown = language_registry.language_for_name("Markdown");
|
||||||
let mut message_anchors = Vec::new();
|
let mut message_anchors = Vec::new();
|
||||||
|
@ -1491,6 +1504,7 @@ impl Conversation {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
id,
|
||||||
message_anchors,
|
message_anchors,
|
||||||
messages_metadata: saved_conversation.message_metadata,
|
messages_metadata: saved_conversation.message_metadata,
|
||||||
next_message_id,
|
next_message_id,
|
||||||
|
@ -2108,6 +2122,7 @@ struct ScrollPosition {
|
||||||
struct ConversationEditor {
|
struct ConversationEditor {
|
||||||
conversation: ModelHandle<Conversation>,
|
conversation: ModelHandle<Conversation>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
editor: ViewHandle<Editor>,
|
editor: ViewHandle<Editor>,
|
||||||
blocks: HashSet<BlockId>,
|
blocks: HashSet<BlockId>,
|
||||||
scroll_position: Option<ScrollPosition>,
|
scroll_position: Option<ScrollPosition>,
|
||||||
|
@ -2119,15 +2134,17 @@ impl ConversationEditor {
|
||||||
api_key: Rc<RefCell<Option<String>>>,
|
api_key: Rc<RefCell<Option<String>>>,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let conversation = cx.add_model(|cx| Conversation::new(api_key, language_registry, cx));
|
let conversation = cx.add_model(|cx| Conversation::new(api_key, language_registry, cx));
|
||||||
Self::for_conversation(conversation, fs, cx)
|
Self::for_conversation(conversation, fs, workspace, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_conversation(
|
fn for_conversation(
|
||||||
conversation: ModelHandle<Conversation>,
|
conversation: ModelHandle<Conversation>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let editor = cx.add_view(|cx| {
|
let editor = cx.add_view(|cx| {
|
||||||
|
@ -2150,6 +2167,7 @@ impl ConversationEditor {
|
||||||
blocks: Default::default(),
|
blocks: Default::default(),
|
||||||
scroll_position: None,
|
scroll_position: None,
|
||||||
fs,
|
fs,
|
||||||
|
workspace,
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
};
|
};
|
||||||
this.update_message_headers(cx);
|
this.update_message_headers(cx);
|
||||||
|
@ -2157,6 +2175,13 @@ impl ConversationEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assist(&mut self, _: &Assist, cx: &mut ViewContext<Self>) {
|
fn assist(&mut self, _: &Assist, cx: &mut ViewContext<Self>) {
|
||||||
|
report_assistant_event(
|
||||||
|
self.workspace.clone(),
|
||||||
|
self.conversation.read(cx).id.clone(),
|
||||||
|
AssistantKind::Panel,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
let cursors = self.cursors(cx);
|
let cursors = self.cursors(cx);
|
||||||
|
|
||||||
let user_messages = self.conversation.update(cx, |conversation, cx| {
|
let user_messages = self.conversation.update(cx, |conversation, cx| {
|
||||||
|
@ -2665,6 +2690,7 @@ enum InlineAssistantEvent {
|
||||||
struct InlineAssistant {
|
struct InlineAssistant {
|
||||||
id: usize,
|
id: usize,
|
||||||
prompt_editor: ViewHandle<Editor>,
|
prompt_editor: ViewHandle<Editor>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
confirmed: bool,
|
confirmed: bool,
|
||||||
has_focus: bool,
|
has_focus: bool,
|
||||||
include_conversation: bool,
|
include_conversation: bool,
|
||||||
|
@ -2780,6 +2806,7 @@ impl InlineAssistant {
|
||||||
include_conversation: bool,
|
include_conversation: bool,
|
||||||
prompt_history: VecDeque<String>,
|
prompt_history: VecDeque<String>,
|
||||||
codegen: ModelHandle<Codegen>,
|
codegen: ModelHandle<Codegen>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let prompt_editor = cx.add_view(|cx| {
|
let prompt_editor = cx.add_view(|cx| {
|
||||||
|
@ -2801,6 +2828,7 @@ impl InlineAssistant {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
prompt_editor,
|
prompt_editor,
|
||||||
|
workspace,
|
||||||
confirmed: false,
|
confirmed: false,
|
||||||
has_focus: false,
|
has_focus: false,
|
||||||
include_conversation,
|
include_conversation,
|
||||||
|
@ -2859,6 +2887,8 @@ impl InlineAssistant {
|
||||||
if self.confirmed {
|
if self.confirmed {
|
||||||
cx.emit(InlineAssistantEvent::Dismissed);
|
cx.emit(InlineAssistantEvent::Dismissed);
|
||||||
} else {
|
} else {
|
||||||
|
report_assistant_event(self.workspace.clone(), None, AssistantKind::Inline, cx);
|
||||||
|
|
||||||
let prompt = self.prompt_editor.read(cx).text(cx);
|
let prompt = self.prompt_editor.read(cx).text(cx);
|
||||||
self.prompt_editor.update(cx, |editor, cx| {
|
self.prompt_editor.update(cx, |editor, cx| {
|
||||||
editor.set_read_only(true);
|
editor.set_read_only(true);
|
||||||
|
@ -3347,3 +3377,30 @@ mod tests {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_assistant_event(
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
conversation_id: Option<String>,
|
||||||
|
assistant_kind: AssistantKind,
|
||||||
|
cx: &AppContext,
|
||||||
|
) {
|
||||||
|
let Some(workspace) = workspace.upgrade(cx) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = workspace.read(cx).project().read(cx).client();
|
||||||
|
let telemetry = client.telemetry();
|
||||||
|
|
||||||
|
let model = settings::get::<AssistantSettings>(cx)
|
||||||
|
.default_open_ai_model
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let event = ClickhouseEvent::Assistant {
|
||||||
|
conversation_id,
|
||||||
|
kind: assistant_kind,
|
||||||
|
model: model.full_name(),
|
||||||
|
};
|
||||||
|
let telemetry_settings = *settings::get::<TelemetrySettings>(cx);
|
||||||
|
|
||||||
|
telemetry.report_clickhouse_event(event, telemetry_settings)
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,13 @@ struct ClickhouseEventWrapper {
|
||||||
event: ClickhouseEvent,
|
event: ClickhouseEvent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum AssistantKind {
|
||||||
|
Panel,
|
||||||
|
Inline,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
#[derive(Serialize, Debug)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ClickhouseEvent {
|
pub enum ClickhouseEvent {
|
||||||
|
@ -76,6 +83,11 @@ pub enum ClickhouseEvent {
|
||||||
room_id: Option<u64>,
|
room_id: Option<u64>,
|
||||||
channel_id: Option<u64>,
|
channel_id: Option<u64>,
|
||||||
},
|
},
|
||||||
|
Assistant {
|
||||||
|
conversation_id: Option<String>,
|
||||||
|
kind: AssistantKind,
|
||||||
|
model: &'static str,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
|
|
@ -26,7 +26,6 @@ impl<C: SafeStylable> ComponentExt<C> for C {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod disclosure {
|
pub mod disclosure {
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::{Component, ContainerStyle, Empty, Flex, ParentElement, SafeStylable},
|
elements::{Component, ContainerStyle, Empty, Flex, ParentElement, SafeStylable},
|
||||||
Action, Element,
|
Action, Element,
|
||||||
|
|
Loading…
Reference in a new issue