More progress
This commit is contained in:
parent
eebe425c1d
commit
fa6c0a1a49
4 changed files with 158 additions and 22 deletions
|
@ -31,6 +31,16 @@ pub trait AgentConnection {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_thread(
|
||||||
|
self: Rc<Self>,
|
||||||
|
_project: Entity<Project>,
|
||||||
|
_cwd: &Path,
|
||||||
|
_session_id: acp::SessionId,
|
||||||
|
_cx: &mut App,
|
||||||
|
) -> Task<Result<Entity<AcpThread>>> {
|
||||||
|
Task::ready(Err(anyhow::anyhow!("load thread not implemented")))
|
||||||
|
}
|
||||||
|
|
||||||
fn auth_methods(&self) -> &[acp::AuthMethod];
|
fn auth_methods(&self) -> &[acp::AuthMethod];
|
||||||
|
|
||||||
fn authenticate(&self, method: acp::AuthMethodId, cx: &mut App) -> Task<Result<()>>;
|
fn authenticate(&self, method: acp::AuthMethodId, cx: &mut App) -> Task<Result<()>>;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::ThreadsDatabase;
|
|
||||||
use crate::native_agent_server::NATIVE_AGENT_SERVER_NAME;
|
use crate::native_agent_server::NATIVE_AGENT_SERVER_NAME;
|
||||||
use crate::{
|
use crate::{
|
||||||
AgentResponseEvent, ContextServerRegistry, CopyPathTool, CreateDirectoryTool, DeletePathTool,
|
AgentResponseEvent, ContextServerRegistry, CopyPathTool, CreateDirectoryTool, DeletePathTool,
|
||||||
|
@ -6,7 +5,8 @@ use crate::{
|
||||||
MovePathTool, NowTool, OpenTool, ReadFileTool, TerminalTool, ThinkingTool, Thread,
|
MovePathTool, NowTool, OpenTool, ReadFileTool, TerminalTool, ThinkingTool, Thread,
|
||||||
ToolCallAuthorization, UserMessageContent, WebSearchTool, templates::Templates,
|
ToolCallAuthorization, UserMessageContent, WebSearchTool, templates::Templates,
|
||||||
};
|
};
|
||||||
use acp_thread::{AcpThreadMetadata, AgentModelSelector};
|
use crate::{DbThread, ThreadsDatabase};
|
||||||
|
use acp_thread::{AcpThread, AcpThreadMetadata, AgentModelSelector};
|
||||||
use agent_client_protocol as acp;
|
use agent_client_protocol as acp;
|
||||||
use agent_settings::AgentSettings;
|
use agent_settings::AgentSettings;
|
||||||
use anyhow::{Context as _, Result, anyhow};
|
use anyhow::{Context as _, Result, anyhow};
|
||||||
|
@ -18,7 +18,7 @@ use futures::{SinkExt, StreamExt, future};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, AsyncApp, Context, Entity, SharedString, Subscription, Task, WeakEntity,
|
App, AppContext, AsyncApp, Context, Entity, SharedString, Subscription, Task, WeakEntity,
|
||||||
};
|
};
|
||||||
use language_model::{LanguageModel, LanguageModelProvider, LanguageModelRegistry};
|
use language_model::{LanguageModel, LanguageModelProvider, LanguageModelRegistry, SelectedModel};
|
||||||
use project::{Project, ProjectItem, ProjectPath, Worktree};
|
use project::{Project, ProjectItem, ProjectPath, Worktree};
|
||||||
use prompt_store::{
|
use prompt_store::{
|
||||||
ProjectContext, PromptId, PromptStore, RulesFileContext, UserRulesContext, WorktreeContext,
|
ProjectContext, PromptId, PromptStore, RulesFileContext, UserRulesContext, WorktreeContext,
|
||||||
|
@ -759,7 +759,6 @@ impl acp_thread::AgentConnection for NativeAgentConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_threads(&self, cx: &mut App) -> Option<UnboundedReceiver<Vec<AcpThreadMetadata>>> {
|
fn list_threads(&self, cx: &mut App) -> Option<UnboundedReceiver<Vec<AcpThreadMetadata>>> {
|
||||||
dbg!("listing!");
|
|
||||||
let (mut tx, rx) = futures::channel::mpsc::unbounded();
|
let (mut tx, rx) = futures::channel::mpsc::unbounded();
|
||||||
let database = self.0.update(cx, |this, _| {
|
let database = self.0.update(cx, |this, _| {
|
||||||
this.history_listeners.push(tx.clone());
|
this.history_listeners.push(tx.clone());
|
||||||
|
@ -790,6 +789,114 @@ impl acp_thread::AgentConnection for NativeAgentConnection {
|
||||||
Some(rx)
|
Some(rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_thread(
|
||||||
|
self: Rc<Self>,
|
||||||
|
project: Entity<Project>,
|
||||||
|
cwd: &Path,
|
||||||
|
session_id: acp::SessionId,
|
||||||
|
cx: &mut App,
|
||||||
|
) -> Task<Result<Entity<acp_thread::AcpThread>>> {
|
||||||
|
let database = self.0.update(cx, |this, _| this.thread_database.clone());
|
||||||
|
cx.spawn(async move |cx| {
|
||||||
|
let database = database.await.map_err(|e| anyhow!(e))?;
|
||||||
|
let db_thread = database
|
||||||
|
.load_thread(session_id.clone())
|
||||||
|
.await?
|
||||||
|
.context("no such thread found")?;
|
||||||
|
|
||||||
|
let acp_thread = cx.update(|cx| {
|
||||||
|
cx.new(|cx| {
|
||||||
|
acp_thread::AcpThread::new(
|
||||||
|
db_thread.title,
|
||||||
|
self.clone(),
|
||||||
|
project.clone(),
|
||||||
|
session_id.clone(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
let action_log = cx.update(|cx| acp_thread.read(cx).action_log().clone())?;
|
||||||
|
let agent = self.0.clone();
|
||||||
|
|
||||||
|
// Create Thread
|
||||||
|
let thread = agent.update(
|
||||||
|
cx,
|
||||||
|
|agent, cx: &mut gpui::Context<NativeAgent>| -> Result<_> {
|
||||||
|
let configured_model = LanguageModelRegistry::global(cx)
|
||||||
|
.update(cx, |registry, cx| {
|
||||||
|
db_thread
|
||||||
|
.model
|
||||||
|
.and_then(|model| {
|
||||||
|
let model = SelectedModel {
|
||||||
|
provider: model.provider.clone().into(),
|
||||||
|
model: model.model.clone().into(),
|
||||||
|
};
|
||||||
|
registry.select_model(&model, cx)
|
||||||
|
})
|
||||||
|
.or_else(|| registry.default_model())
|
||||||
|
})
|
||||||
|
.context("no default model configured")?;
|
||||||
|
|
||||||
|
let model = agent
|
||||||
|
.models
|
||||||
|
.model_from_id(&LanguageModels::model_id(&configured_model.model))
|
||||||
|
.context("no model by id")?;
|
||||||
|
|
||||||
|
let thread = cx.new(|cx| {
|
||||||
|
let mut thread = Thread::new(
|
||||||
|
project.clone(),
|
||||||
|
agent.project_context.clone(),
|
||||||
|
agent.context_server_registry.clone(),
|
||||||
|
action_log.clone(),
|
||||||
|
agent.templates.clone(),
|
||||||
|
model,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
// todo!() factor this out
|
||||||
|
thread.add_tool(CopyPathTool::new(project.clone()));
|
||||||
|
thread.add_tool(CreateDirectoryTool::new(project.clone()));
|
||||||
|
thread.add_tool(DeletePathTool::new(project.clone(), action_log.clone()));
|
||||||
|
thread.add_tool(DiagnosticsTool::new(project.clone()));
|
||||||
|
thread.add_tool(EditFileTool::new(cx.entity()));
|
||||||
|
thread.add_tool(FetchTool::new(project.read(cx).client().http_client()));
|
||||||
|
thread.add_tool(FindPathTool::new(project.clone()));
|
||||||
|
thread.add_tool(GrepTool::new(project.clone()));
|
||||||
|
thread.add_tool(ListDirectoryTool::new(project.clone()));
|
||||||
|
thread.add_tool(MovePathTool::new(project.clone()));
|
||||||
|
thread.add_tool(NowTool);
|
||||||
|
thread.add_tool(OpenTool::new(project.clone()));
|
||||||
|
thread.add_tool(ReadFileTool::new(project.clone(), action_log));
|
||||||
|
thread.add_tool(TerminalTool::new(project.clone(), cx));
|
||||||
|
thread.add_tool(ThinkingTool);
|
||||||
|
thread.add_tool(WebSearchTool); // TODO: Enable this only if it's a zed model.
|
||||||
|
thread
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(thread)
|
||||||
|
},
|
||||||
|
)??;
|
||||||
|
|
||||||
|
// Store the session
|
||||||
|
agent.update(cx, |agent, cx| {
|
||||||
|
agent.sessions.insert(
|
||||||
|
session_id,
|
||||||
|
Session {
|
||||||
|
thread,
|
||||||
|
acp_thread: acp_thread.downgrade(),
|
||||||
|
_subscription: cx.observe_release(&acp_thread, |this, acp_thread, _cx| {
|
||||||
|
this.sessions.remove(acp_thread.session_id());
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// we need to actually deserialize the DbThread.
|
||||||
|
todo!()
|
||||||
|
|
||||||
|
Ok(acp_thread)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn model_selector(&self) -> Option<Rc<dyn AgentModelSelector>> {
|
fn model_selector(&self) -> Option<Rc<dyn AgentModelSelector>> {
|
||||||
Some(Rc::new(self.clone()) as Rc<dyn AgentModelSelector>)
|
Some(Rc::new(self.clone()) as Rc<dyn AgentModelSelector>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ use ui::{
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
pub struct AcpThreadHistory {
|
pub struct AcpThreadHistory {
|
||||||
agent_panel: WeakEntity<AgentPanel>,
|
|
||||||
history_store: Entity<HistoryStore>,
|
history_store: Entity<HistoryStore>,
|
||||||
scroll_handle: UniformListScrollHandle,
|
scroll_handle: UniformListScrollHandle,
|
||||||
selected_index: usize,
|
selected_index: usize,
|
||||||
|
@ -473,16 +472,17 @@ impl AcpThreadHistory {
|
||||||
let Some(entry) = self.get_match(ix) else {
|
let Some(entry) = self.get_match(ix) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let task_result = match entry {
|
todo!();
|
||||||
HistoryEntry::Thread(thread) => todo!(),
|
// let task_result = match entry {
|
||||||
HistoryEntry::Context(context) => self
|
// HistoryEntry::Thread(thread) => todo!(),
|
||||||
.agent_panel
|
// HistoryEntry::Context(context) => self
|
||||||
.update(cx, |this, cx| this.delete_context(context.path.clone(), cx)),
|
// .agent_panel
|
||||||
};
|
// .update(cx, |this, cx| this.delete_context(context.path.clone(), cx)),
|
||||||
|
// };
|
||||||
|
|
||||||
if let Some(task) = task_result.log_err() {
|
// if let Some(task) = task_result.log_err() {
|
||||||
task.detach_and_log_err(cx);
|
// task.detach_and_log_err(cx);
|
||||||
};
|
// };
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,14 @@ impl AcpThreadView {
|
||||||
project: project.clone(),
|
project: project.clone(),
|
||||||
thread_store,
|
thread_store,
|
||||||
text_thread_store,
|
text_thread_store,
|
||||||
thread_state: Self::initial_state(agent, workspace, project, window, cx),
|
thread_state: Self::initial_state(
|
||||||
|
agent,
|
||||||
|
restore_thread,
|
||||||
|
workspace,
|
||||||
|
project,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
),
|
||||||
message_editor,
|
message_editor,
|
||||||
model_selector: None,
|
model_selector: None,
|
||||||
notifications: Vec::new(),
|
notifications: Vec::new(),
|
||||||
|
@ -193,6 +200,7 @@ impl AcpThreadView {
|
||||||
|
|
||||||
fn initial_state(
|
fn initial_state(
|
||||||
agent: Rc<dyn AgentServer>,
|
agent: Rc<dyn AgentServer>,
|
||||||
|
restore_thread: Option<AcpThreadMetadata>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
project: Entity<Project>,
|
project: Entity<Project>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
|
@ -232,19 +240,27 @@ impl AcpThreadView {
|
||||||
// .detach();
|
// .detach();
|
||||||
// })
|
// })
|
||||||
// .ok();
|
// .ok();
|
||||||
|
//
|
||||||
let Some(result) = cx
|
let task = cx.update(|_, cx| {
|
||||||
.update(|_, cx| {
|
if let Some(restore_thread) = restore_thread {
|
||||||
|
connection.clone().load_thread(
|
||||||
|
project.clone(),
|
||||||
|
&root_dir,
|
||||||
|
restore_thread.id,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
connection
|
connection
|
||||||
.clone()
|
.clone()
|
||||||
.new_thread(project.clone(), &root_dir, cx)
|
.new_thread(project.clone(), &root_dir, cx)
|
||||||
})
|
}
|
||||||
.log_err()
|
});
|
||||||
else {
|
|
||||||
|
let Ok(task) = task else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = match result.await {
|
let result = match task.await {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let mut cx = cx.clone();
|
let mut cx = cx.clone();
|
||||||
if e.is::<acp_thread::AuthRequired>() {
|
if e.is::<acp_thread::AuthRequired>() {
|
||||||
|
@ -618,6 +634,7 @@ impl AcpThreadView {
|
||||||
} else {
|
} else {
|
||||||
this.thread_state = Self::initial_state(
|
this.thread_state = Self::initial_state(
|
||||||
agent,
|
agent,
|
||||||
|
None, // todo!()
|
||||||
this.workspace.clone(),
|
this.workspace.clone(),
|
||||||
project.clone(),
|
project.clone(),
|
||||||
window,
|
window,
|
||||||
|
@ -3733,6 +3750,7 @@ pub(crate) mod tests {
|
||||||
project,
|
project,
|
||||||
thread_store.clone(),
|
thread_store.clone(),
|
||||||
text_thread_store.clone(),
|
text_thread_store.clone(),
|
||||||
|
None,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
@ -3884,6 +3902,7 @@ pub(crate) mod tests {
|
||||||
project.clone(),
|
project.clone(),
|
||||||
thread_store.clone(),
|
thread_store.clone(),
|
||||||
text_thread_store.clone(),
|
text_thread_store.clone(),
|
||||||
|
None,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue