ACP history mentions (#36551)
- **TEMP** - **Update @-mentions to use new history** Closes #ISSUE Release Notes: - N/A
This commit is contained in:
parent
159b5e9fb5
commit
5d2bb2466e
17 changed files with 581 additions and 392 deletions
|
@ -3,8 +3,9 @@ use crate::{
|
|||
context_picker::fetch_context_picker::fetch_url_content,
|
||||
};
|
||||
use acp_thread::{MentionUri, selection_name};
|
||||
use agent::{TextThreadStore, ThreadId, ThreadStore};
|
||||
use agent_client_protocol as acp;
|
||||
use agent_servers::AgentServer;
|
||||
use agent2::HistoryStore;
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use assistant_slash_commands::codeblock_fence_for_path;
|
||||
use collections::{HashMap, HashSet};
|
||||
|
@ -27,6 +28,7 @@ use gpui::{
|
|||
use language::{Buffer, Language};
|
||||
use language_model::LanguageModelImage;
|
||||
use project::{Project, ProjectPath, Worktree};
|
||||
use prompt_store::PromptStore;
|
||||
use rope::Point;
|
||||
use settings::Settings;
|
||||
use std::{
|
||||
|
@ -59,8 +61,8 @@ pub struct MessageEditor {
|
|||
editor: Entity<Editor>,
|
||||
project: Entity<Project>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
thread_store: Entity<ThreadStore>,
|
||||
text_thread_store: Entity<TextThreadStore>,
|
||||
history_store: Entity<HistoryStore>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
prevent_slash_commands: bool,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
_parse_slash_command_task: Task<()>,
|
||||
|
@ -79,8 +81,8 @@ impl MessageEditor {
|
|||
pub fn new(
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
thread_store: Entity<ThreadStore>,
|
||||
text_thread_store: Entity<TextThreadStore>,
|
||||
history_store: Entity<HistoryStore>,
|
||||
prompt_store: Option<Entity<PromptStore>>,
|
||||
placeholder: impl Into<Arc<str>>,
|
||||
prevent_slash_commands: bool,
|
||||
mode: EditorMode,
|
||||
|
@ -95,10 +97,10 @@ impl MessageEditor {
|
|||
None,
|
||||
);
|
||||
let completion_provider = ContextPickerCompletionProvider::new(
|
||||
workspace.clone(),
|
||||
thread_store.downgrade(),
|
||||
text_thread_store.downgrade(),
|
||||
cx.weak_entity(),
|
||||
workspace.clone(),
|
||||
history_store.clone(),
|
||||
prompt_store.clone(),
|
||||
);
|
||||
let semantics_provider = Rc::new(SlashCommandSemanticsProvider {
|
||||
range: Cell::new(None),
|
||||
|
@ -152,9 +154,9 @@ impl MessageEditor {
|
|||
editor,
|
||||
project,
|
||||
mention_set,
|
||||
thread_store,
|
||||
text_thread_store,
|
||||
workspace,
|
||||
history_store,
|
||||
prompt_store,
|
||||
prevent_slash_commands,
|
||||
_subscriptions: subscriptions,
|
||||
_parse_slash_command_task: Task::ready(()),
|
||||
|
@ -175,23 +177,12 @@ impl MessageEditor {
|
|||
self.editor.read(cx).is_empty(cx)
|
||||
}
|
||||
|
||||
pub fn mentioned_path_and_threads(&self) -> (HashSet<PathBuf>, HashSet<ThreadId>) {
|
||||
let mut excluded_paths = HashSet::default();
|
||||
let mut excluded_threads = HashSet::default();
|
||||
|
||||
for uri in self.mention_set.uri_by_crease_id.values() {
|
||||
match uri {
|
||||
MentionUri::File { abs_path, .. } => {
|
||||
excluded_paths.insert(abs_path.clone());
|
||||
}
|
||||
MentionUri::Thread { id, .. } => {
|
||||
excluded_threads.insert(id.clone());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
(excluded_paths, excluded_threads)
|
||||
pub fn mentions(&self) -> HashSet<MentionUri> {
|
||||
self.mention_set
|
||||
.uri_by_crease_id
|
||||
.values()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn confirm_completion(
|
||||
|
@ -529,7 +520,7 @@ impl MessageEditor {
|
|||
&mut self,
|
||||
crease_id: CreaseId,
|
||||
anchor: Anchor,
|
||||
id: ThreadId,
|
||||
id: acp::SessionId,
|
||||
name: String,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
|
@ -538,17 +529,25 @@ impl MessageEditor {
|
|||
id: id.clone(),
|
||||
name,
|
||||
};
|
||||
let open_task = self.thread_store.update(cx, |thread_store, cx| {
|
||||
thread_store.open_thread(&id, window, cx)
|
||||
let server = Rc::new(agent2::NativeAgentServer::new(
|
||||
self.project.read(cx).fs().clone(),
|
||||
self.history_store.clone(),
|
||||
));
|
||||
let connection = server.connect(Path::new(""), &self.project, cx);
|
||||
let load_summary = cx.spawn({
|
||||
let id = id.clone();
|
||||
async move |_, cx| {
|
||||
let agent = connection.await?;
|
||||
let agent = agent.downcast::<agent2::NativeAgentConnection>().unwrap();
|
||||
let summary = agent
|
||||
.0
|
||||
.update(cx, |agent, cx| agent.thread_summary(id, cx))?
|
||||
.await?;
|
||||
anyhow::Ok(summary)
|
||||
}
|
||||
});
|
||||
let task = cx
|
||||
.spawn(async move |_, cx| {
|
||||
let thread = open_task.await.map_err(|e| e.to_string())?;
|
||||
let content = thread
|
||||
.read_with(cx, |thread, _cx| thread.latest_detailed_summary_or_text())
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(content)
|
||||
})
|
||||
.spawn(async move |_, _| load_summary.await.map_err(|e| format!("{e}")))
|
||||
.shared();
|
||||
|
||||
self.mention_set.insert_thread(id.clone(), task.clone());
|
||||
|
@ -590,8 +589,8 @@ impl MessageEditor {
|
|||
path: path.clone(),
|
||||
name,
|
||||
};
|
||||
let context = self.text_thread_store.update(cx, |text_thread_store, cx| {
|
||||
text_thread_store.open_local_context(path.as_path().into(), cx)
|
||||
let context = self.history_store.update(cx, |text_thread_store, cx| {
|
||||
text_thread_store.load_text_thread(path.as_path().into(), cx)
|
||||
});
|
||||
let task = cx
|
||||
.spawn(async move |_, cx| {
|
||||
|
@ -637,7 +636,7 @@ impl MessageEditor {
|
|||
) -> Task<Result<Vec<acp::ContentBlock>>> {
|
||||
let contents =
|
||||
self.mention_set
|
||||
.contents(self.project.clone(), self.thread_store.clone(), window, cx);
|
||||
.contents(&self.project, self.prompt_store.as_ref(), window, cx);
|
||||
let editor = self.editor.clone();
|
||||
let prevent_slash_commands = self.prevent_slash_commands;
|
||||
|
||||
|
@ -1316,7 +1315,7 @@ pub struct MentionSet {
|
|||
uri_by_crease_id: HashMap<CreaseId, MentionUri>,
|
||||
fetch_results: HashMap<Url, Shared<Task<Result<String, String>>>>,
|
||||
images: HashMap<CreaseId, Shared<Task<Result<MentionImage, String>>>>,
|
||||
thread_summaries: HashMap<ThreadId, Shared<Task<Result<SharedString, String>>>>,
|
||||
thread_summaries: HashMap<acp::SessionId, Shared<Task<Result<SharedString, String>>>>,
|
||||
text_thread_summaries: HashMap<PathBuf, Shared<Task<Result<String, String>>>>,
|
||||
directories: HashMap<PathBuf, Shared<Task<Result<String, String>>>>,
|
||||
}
|
||||
|
@ -1338,7 +1337,11 @@ impl MentionSet {
|
|||
self.images.insert(crease_id, task);
|
||||
}
|
||||
|
||||
fn insert_thread(&mut self, id: ThreadId, task: Shared<Task<Result<SharedString, String>>>) {
|
||||
fn insert_thread(
|
||||
&mut self,
|
||||
id: acp::SessionId,
|
||||
task: Shared<Task<Result<SharedString, String>>>,
|
||||
) {
|
||||
self.thread_summaries.insert(id, task);
|
||||
}
|
||||
|
||||
|
@ -1358,8 +1361,8 @@ impl MentionSet {
|
|||
|
||||
pub fn contents(
|
||||
&self,
|
||||
project: Entity<Project>,
|
||||
thread_store: Entity<ThreadStore>,
|
||||
project: &Entity<Project>,
|
||||
prompt_store: Option<&Entity<PromptStore>>,
|
||||
_window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<HashMap<CreaseId, Mention>>> {
|
||||
|
@ -1484,8 +1487,7 @@ impl MentionSet {
|
|||
})
|
||||
}
|
||||
MentionUri::Rule { id: prompt_id, .. } => {
|
||||
let Some(prompt_store) = thread_store.read(cx).prompt_store().clone()
|
||||
else {
|
||||
let Some(prompt_store) = prompt_store else {
|
||||
return Task::ready(Err(anyhow!("missing prompt store")));
|
||||
};
|
||||
let text_task = prompt_store.read(cx).load(*prompt_id, cx);
|
||||
|
@ -1678,8 +1680,9 @@ impl Addon for MessageEditorAddon {
|
|||
mod tests {
|
||||
use std::{ops::Range, path::Path, sync::Arc};
|
||||
|
||||
use agent::{TextThreadStore, ThreadStore};
|
||||
use agent_client_protocol as acp;
|
||||
use agent2::HistoryStore;
|
||||
use assistant_context::ContextStore;
|
||||
use editor::{AnchorRangeExt as _, Editor, EditorMode};
|
||||
use fs::FakeFs;
|
||||
use futures::StreamExt as _;
|
||||
|
@ -1710,16 +1713,16 @@ mod tests {
|
|||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
|
||||
let thread_store = cx.new(|cx| ThreadStore::fake(project.clone(), cx));
|
||||
let text_thread_store = cx.new(|cx| TextThreadStore::fake(project.clone(), cx));
|
||||
let context_store = cx.new(|cx| ContextStore::fake(project.clone(), cx));
|
||||
let history_store = cx.new(|cx| HistoryStore::new(context_store, cx));
|
||||
|
||||
let message_editor = cx.update(|window, cx| {
|
||||
cx.new(|cx| {
|
||||
MessageEditor::new(
|
||||
workspace.downgrade(),
|
||||
project.clone(),
|
||||
thread_store.clone(),
|
||||
text_thread_store.clone(),
|
||||
history_store.clone(),
|
||||
None,
|
||||
"Test",
|
||||
false,
|
||||
EditorMode::AutoHeight {
|
||||
|
@ -1908,8 +1911,8 @@ mod tests {
|
|||
opened_editors.push(buffer);
|
||||
}
|
||||
|
||||
let thread_store = cx.new(|cx| ThreadStore::fake(project.clone(), cx));
|
||||
let text_thread_store = cx.new(|cx| TextThreadStore::fake(project.clone(), cx));
|
||||
let context_store = cx.new(|cx| ContextStore::fake(project.clone(), cx));
|
||||
let history_store = cx.new(|cx| HistoryStore::new(context_store, cx));
|
||||
|
||||
let (message_editor, editor) = workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||
let workspace_handle = cx.weak_entity();
|
||||
|
@ -1917,8 +1920,8 @@ mod tests {
|
|||
MessageEditor::new(
|
||||
workspace_handle,
|
||||
project.clone(),
|
||||
thread_store.clone(),
|
||||
text_thread_store.clone(),
|
||||
history_store.clone(),
|
||||
None,
|
||||
"Test",
|
||||
false,
|
||||
EditorMode::AutoHeight {
|
||||
|
@ -2011,12 +2014,9 @@ mod tests {
|
|||
|
||||
let contents = message_editor
|
||||
.update_in(&mut cx, |message_editor, window, cx| {
|
||||
message_editor.mention_set().contents(
|
||||
project.clone(),
|
||||
thread_store.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
message_editor
|
||||
.mention_set()
|
||||
.contents(&project, None, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -2066,12 +2066,9 @@ mod tests {
|
|||
|
||||
let contents = message_editor
|
||||
.update_in(&mut cx, |message_editor, window, cx| {
|
||||
message_editor.mention_set().contents(
|
||||
project.clone(),
|
||||
thread_store.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
message_editor
|
||||
.mention_set()
|
||||
.contents(&project, None, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -2181,7 +2178,7 @@ mod tests {
|
|||
.update_in(&mut cx, |message_editor, window, cx| {
|
||||
message_editor
|
||||
.mention_set()
|
||||
.contents(project.clone(), thread_store, window, cx)
|
||||
.contents(&project, None, window, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue