Port terminal tool to agent2 (#35918)

Release Notes:

- N/A

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This commit is contained in:
Antonio Scandurra 2025-08-11 12:31:13 +02:00 committed by GitHub
parent 422e0a2eb7
commit 086ea3c619
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 882 additions and 112 deletions

View file

@ -1,8 +1,10 @@
mod connection;
mod diff;
mod terminal;
pub use connection::*;
pub use diff::*;
pub use terminal::*;
use action_log::ActionLog;
use agent_client_protocol as acp;
@ -147,6 +149,14 @@ impl AgentThreadEntry {
}
}
pub fn terminals(&self) -> impl Iterator<Item = &Entity<Terminal>> {
if let AgentThreadEntry::ToolCall(call) = self {
itertools::Either::Left(call.terminals())
} else {
itertools::Either::Right(std::iter::empty())
}
}
pub fn locations(&self) -> Option<&[acp::ToolCallLocation]> {
if let AgentThreadEntry::ToolCall(ToolCall { locations, .. }) = self {
Some(locations)
@ -250,8 +260,17 @@ impl ToolCall {
pub fn diffs(&self) -> impl Iterator<Item = &Entity<Diff>> {
self.content.iter().filter_map(|content| match content {
ToolCallContent::ContentBlock { .. } => None,
ToolCallContent::Diff { diff } => Some(diff),
ToolCallContent::Diff(diff) => Some(diff),
ToolCallContent::ContentBlock(_) => None,
ToolCallContent::Terminal(_) => None,
})
}
pub fn terminals(&self) -> impl Iterator<Item = &Entity<Terminal>> {
self.content.iter().filter_map(|content| match content {
ToolCallContent::Terminal(terminal) => Some(terminal),
ToolCallContent::ContentBlock(_) => None,
ToolCallContent::Diff(_) => None,
})
}
@ -387,8 +406,9 @@ impl ContentBlock {
#[derive(Debug)]
pub enum ToolCallContent {
ContentBlock { content: ContentBlock },
Diff { diff: Entity<Diff> },
ContentBlock(ContentBlock),
Diff(Entity<Diff>),
Terminal(Entity<Terminal>),
}
impl ToolCallContent {
@ -398,19 +418,20 @@ impl ToolCallContent {
cx: &mut App,
) -> Self {
match content {
acp::ToolCallContent::Content { content } => Self::ContentBlock {
content: ContentBlock::new(content, &language_registry, cx),
},
acp::ToolCallContent::Diff { diff } => Self::Diff {
diff: cx.new(|cx| Diff::from_acp(diff, language_registry, cx)),
},
acp::ToolCallContent::Content { content } => {
Self::ContentBlock(ContentBlock::new(content, &language_registry, cx))
}
acp::ToolCallContent::Diff { diff } => {
Self::Diff(cx.new(|cx| Diff::from_acp(diff, language_registry, cx)))
}
}
}
pub fn to_markdown(&self, cx: &App) -> String {
match self {
Self::ContentBlock { content } => content.to_markdown(cx).to_string(),
Self::Diff { diff } => diff.read(cx).to_markdown(cx),
Self::ContentBlock(content) => content.to_markdown(cx).to_string(),
Self::Diff(diff) => diff.read(cx).to_markdown(cx),
Self::Terminal(terminal) => terminal.read(cx).to_markdown(cx),
}
}
}
@ -419,6 +440,7 @@ impl ToolCallContent {
pub enum ToolCallUpdate {
UpdateFields(acp::ToolCallUpdate),
UpdateDiff(ToolCallUpdateDiff),
UpdateTerminal(ToolCallUpdateTerminal),
}
impl ToolCallUpdate {
@ -426,6 +448,7 @@ impl ToolCallUpdate {
match self {
Self::UpdateFields(update) => &update.id,
Self::UpdateDiff(diff) => &diff.id,
Self::UpdateTerminal(terminal) => &terminal.id,
}
}
}
@ -448,6 +471,18 @@ pub struct ToolCallUpdateDiff {
pub diff: Entity<Diff>,
}
impl From<ToolCallUpdateTerminal> for ToolCallUpdate {
fn from(terminal: ToolCallUpdateTerminal) -> Self {
Self::UpdateTerminal(terminal)
}
}
#[derive(Debug, PartialEq)]
pub struct ToolCallUpdateTerminal {
pub id: acp::ToolCallId,
pub terminal: Entity<Terminal>,
}
#[derive(Debug, Default)]
pub struct Plan {
pub entries: Vec<PlanEntry>,
@ -760,7 +795,13 @@ impl AcpThread {
current_call.content.clear();
current_call
.content
.push(ToolCallContent::Diff { diff: update.diff });
.push(ToolCallContent::Diff(update.diff));
}
ToolCallUpdate::UpdateTerminal(update) => {
current_call.content.clear();
current_call
.content
.push(ToolCallContent::Terminal(update.terminal));
}
}