Push request and insert further
This commit is contained in:
parent
c3e4f3800d
commit
cea8e61fd9
1 changed files with 51 additions and 122 deletions
|
@ -180,6 +180,31 @@ pub struct ToolCall {
|
|||
}
|
||||
|
||||
impl ToolCall {
|
||||
fn from_acp(
|
||||
tool_call: acp::ToolCall,
|
||||
status: ToolCallStatus,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: tool_call.id,
|
||||
label: cx.new(|cx| {
|
||||
Markdown::new(
|
||||
tool_call.label.into(),
|
||||
Some(language_registry.clone()),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
kind: tool_call.kind,
|
||||
// todo! Do we assume there is either a coalesced content OR diff?
|
||||
content: ToolCallContent::from_acp_contents(tool_call.content, language_registry, cx)
|
||||
.into_iter()
|
||||
.next(),
|
||||
locations: tool_call.locations,
|
||||
status,
|
||||
}
|
||||
}
|
||||
fn to_markdown(&self, cx: &App) -> String {
|
||||
let mut markdown = format!(
|
||||
"**Tool Call: {}**\nStatus: {}\n\n",
|
||||
|
@ -780,98 +805,46 @@ impl AcpThread {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Result<()> {
|
||||
let language_registry = self.project.read(cx).languages().clone();
|
||||
|
||||
let new_tool_call = ToolCall {
|
||||
id: tool_call.id,
|
||||
label: cx.new(|cx| {
|
||||
Markdown::new(
|
||||
tool_call.label.into(),
|
||||
Some(language_registry.clone()),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
kind: tool_call.kind,
|
||||
// todo! Do we assume there is either a coalesced content OR diff?
|
||||
content: ToolCallContent::from_acp_contents(tool_call.content, language_registry, cx)
|
||||
.into_iter()
|
||||
.next(),
|
||||
locations: tool_call.locations,
|
||||
status: ToolCallStatus::Allowed {
|
||||
let status = ToolCallStatus::Allowed {
|
||||
status: tool_call.status,
|
||||
},
|
||||
};
|
||||
let call = ToolCall::from_acp(tool_call, status, language_registry, cx);
|
||||
|
||||
if let Some((ix, current_call)) = self.tool_call_mut(tool_call.id) {
|
||||
match &mut current_call.status {
|
||||
ToolCallStatus::Allowed { status } => {
|
||||
*status = tool_call.status;
|
||||
}
|
||||
let location = call.locations.last().cloned();
|
||||
|
||||
if let Some((ix, current_call)) = self.tool_call_mut(&call.id) {
|
||||
match ¤t_call.status {
|
||||
ToolCallStatus::WaitingForConfirmation { .. } => {
|
||||
anyhow::bail!("Tool call hasn't been authorized yet")
|
||||
}
|
||||
ToolCallStatus::Rejected => {
|
||||
anyhow::bail!("Tool call was rejected and therefore can't be updated")
|
||||
}
|
||||
ToolCallStatus::Canceled => {
|
||||
current_call.status = ToolCallStatus::Allowed { status: new_status };
|
||||
}
|
||||
ToolCallStatus::Allowed { .. } | ToolCallStatus::Canceled => {}
|
||||
}
|
||||
|
||||
*current_call = new_tool_call;
|
||||
|
||||
let location = current_call.locations.last().cloned();
|
||||
if let Some(location) = location {
|
||||
self.set_project_location(location, cx)
|
||||
}
|
||||
*current_call = call;
|
||||
|
||||
cx.emit(AcpThreadEvent::EntryUpdated(ix));
|
||||
} else {
|
||||
let language_registry = self.project.read(cx).languages().clone();
|
||||
let call = ToolCall {
|
||||
id: tool_call.id,
|
||||
label: cx.new(|cx| {
|
||||
Markdown::new(
|
||||
tool_call.label.into(),
|
||||
Some(language_registry.clone()),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
kind: tool_call.kind,
|
||||
// todo! Do we assume there is either a coalesced content OR diff?
|
||||
content: ToolCallContent::from_acp_contents(
|
||||
tool_call.content,
|
||||
language_registry,
|
||||
cx,
|
||||
)
|
||||
.into_iter()
|
||||
.next(),
|
||||
locations: tool_call.locations,
|
||||
status: ToolCallStatus::Allowed {
|
||||
status: tool_call.status,
|
||||
},
|
||||
};
|
||||
|
||||
let location = call.locations.last().cloned();
|
||||
if let Some(location) = location {
|
||||
self.set_project_location(location, cx)
|
||||
self.push_entry(AgentThreadEntry::ToolCall(call), cx);
|
||||
}
|
||||
|
||||
self.push_entry(AgentThreadEntry::ToolCall(call), cx);
|
||||
if let Some(location) = location {
|
||||
self.set_project_location(location, cx)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn tool_call_mut(&mut self, id: acp::ToolCallId) -> Option<(usize, &mut ToolCall)> {
|
||||
fn tool_call_mut(&mut self, id: &acp::ToolCallId) -> Option<(usize, &mut ToolCall)> {
|
||||
self.entries
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find_map(|(index, tool_call)| {
|
||||
if let AgentThreadEntry::ToolCall(tool_call) = tool_call
|
||||
&& tool_call.id == id
|
||||
&& &tool_call.id == id
|
||||
{
|
||||
Some((index, tool_call))
|
||||
} else {
|
||||
|
@ -885,7 +858,7 @@ impl AcpThread {
|
|||
tool_call: acp::ToolCall,
|
||||
possible_grants: Vec<acp::Grant>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> ToolCallRequest {
|
||||
) -> oneshot::Receiver<acp::GrantId> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
let status = ToolCallStatus::WaitingForConfirmation {
|
||||
|
@ -893,61 +866,18 @@ impl AcpThread {
|
|||
respond_tx: tx,
|
||||
};
|
||||
|
||||
let id = self.insert_tool_call(tool_call, status, cx);
|
||||
ToolCallRequest { id, outcome: rx }
|
||||
}
|
||||
|
||||
pub fn request_tool_call_confirmation(
|
||||
&mut self,
|
||||
tool_call_id: ToolCallId,
|
||||
confirmation: acp_old::ToolCallConfirmation,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<ToolCallRequest> {
|
||||
let project = self.project.read(cx).languages().clone();
|
||||
let Some((idx, call)) = self.tool_call_mut(tool_call_id) else {
|
||||
anyhow::bail!("Tool call not found");
|
||||
};
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
call.status = ToolCallStatus::WaitingForConfirmation {
|
||||
confirmation: ToolCallConfirmation::from_acp(confirmation, project, cx),
|
||||
respond_tx: tx,
|
||||
};
|
||||
|
||||
cx.emit(AcpThreadEvent::EntryUpdated(idx));
|
||||
|
||||
Ok(ToolCallRequest {
|
||||
id: tool_call_id,
|
||||
outcome: rx,
|
||||
})
|
||||
self.insert_tool_call(tool_call, status, cx);
|
||||
rx
|
||||
}
|
||||
|
||||
fn insert_tool_call(
|
||||
&mut self,
|
||||
tool_call: acp_old::PushToolCallParams,
|
||||
tool_call: acp::ToolCall,
|
||||
status: ToolCallStatus,
|
||||
cx: &mut Context<Self>,
|
||||
) -> acp_old::ToolCallId {
|
||||
) {
|
||||
let language_registry = self.project.read(cx).languages().clone();
|
||||
let id = acp_old::ToolCallId(self.entries.len() as u64);
|
||||
let call = ToolCall {
|
||||
id,
|
||||
label: cx.new(|cx| {
|
||||
Markdown::new(
|
||||
tool_call.label.into(),
|
||||
Some(language_registry.clone()),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
icon: acp_icon_to_ui_icon(tool_call.icon),
|
||||
content: tool_call
|
||||
.content
|
||||
.map(|content| ToolCallContent::from_acp(content, language_registry, cx)),
|
||||
locations: tool_call.locations,
|
||||
status,
|
||||
};
|
||||
let call = ToolCall::from_acp(tool_call, status, language_registry, cx);
|
||||
|
||||
let location = call.locations.last().cloned();
|
||||
if let Some(location) = location {
|
||||
|
@ -955,8 +885,6 @@ impl AcpThread {
|
|||
}
|
||||
|
||||
self.push_entry(AgentThreadEntry::ToolCall(call), cx);
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub fn authorize_tool_call(
|
||||
|
@ -965,7 +893,7 @@ impl AcpThread {
|
|||
grant: acp::Grant,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some((ix, call)) = self.tool_call_mut(id) else {
|
||||
let Some((ix, call)) = self.tool_call_mut(&id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -1135,7 +1063,7 @@ impl AcpThread {
|
|||
call.status,
|
||||
ToolCallStatus::WaitingForConfirmation { .. }
|
||||
| ToolCallStatus::Allowed {
|
||||
status: acp_old::ToolCallStatus::Running
|
||||
status: acp::ToolCallStatus::InProgress
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1147,6 +1075,7 @@ impl AcpThread {
|
|||
respond_tx, ..
|
||||
} = curr_status
|
||||
{
|
||||
// todo! do we need a way to cancel rather than reject?
|
||||
respond_tx
|
||||
.send(acp_old::ToolCallConfirmationOutcome::Cancel)
|
||||
.ok();
|
||||
|
@ -1698,7 +1627,7 @@ mod tests {
|
|||
thread.entries[1],
|
||||
AgentThreadEntry::ToolCall(ToolCall {
|
||||
status: ToolCallStatus::Allowed {
|
||||
status: acp_old::ToolCallStatus::Running,
|
||||
status: acp::ToolCallStatus::InProgress,
|
||||
..
|
||||
},
|
||||
..
|
||||
|
@ -1742,7 +1671,7 @@ mod tests {
|
|||
thread.entries[1],
|
||||
AgentThreadEntry::ToolCall(ToolCall {
|
||||
status: ToolCallStatus::Allowed {
|
||||
status: acp_old::ToolCallStatus::Finished,
|
||||
status: acp::ToolCallStatus::Completed,
|
||||
..
|
||||
},
|
||||
..
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue