Harden local tool execution
This commit is contained in:
@@ -75,6 +75,17 @@ impl App {
|
||||
if message.system {
|
||||
continue;
|
||||
}
|
||||
if message.tool
|
||||
&& index > 0
|
||||
&& !crate::agent::stored_tool_cards(
|
||||
self.config.model,
|
||||
&self.conversation[index - 1].content,
|
||||
None,
|
||||
)
|
||||
.is_empty()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let label = if message.user {
|
||||
"You"
|
||||
} else if message.tool {
|
||||
@@ -135,11 +146,39 @@ impl App {
|
||||
text(self.activity.as_deref().unwrap_or("Loading model…")).size(14),
|
||||
);
|
||||
}
|
||||
if !message.user && !message.tool {
|
||||
for summary in
|
||||
crate::agent::tool_summaries(self.config.model, &message.content)
|
||||
{
|
||||
body = body.push(text(summary).size(13).color(muted_text()));
|
||||
if !message.user {
|
||||
let stored_result = self
|
||||
.conversation
|
||||
.get(index + 1)
|
||||
.filter(|message| message.tool)
|
||||
.map(|message| message.content.as_str());
|
||||
let cards = if stored_result.is_none() && {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
!self.tool_cards.is_empty()
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
false
|
||||
}
|
||||
} {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
self.tool_cards.clone()
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
Vec::new()
|
||||
}
|
||||
} else {
|
||||
crate::agent::stored_tool_cards(
|
||||
self.config.model,
|
||||
&message.content,
|
||||
stored_result,
|
||||
)
|
||||
};
|
||||
if !cards.is_empty() {
|
||||
body = body.push(tool_cards(cards));
|
||||
}
|
||||
}
|
||||
let user = message.user;
|
||||
@@ -295,3 +334,80 @@ impl App {
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn tool_cards(cards: Vec<crate::agent::ToolCard>) -> Element<'static, Message> {
|
||||
let mut rows = column![].spacing(0);
|
||||
for (index, card) in cards.into_iter().enumerate() {
|
||||
if index > 0 {
|
||||
rows = rows.push(horizontal_rule(1));
|
||||
}
|
||||
let parameters = crate::agent::tool_parameters(&card.call);
|
||||
let call = crate::agent::tool_call_text(&card.call);
|
||||
let copy_call = tooltip(
|
||||
action_button(text("Copy call").size(11))
|
||||
.padding([5, 9])
|
||||
.on_press(Message::CopyToolText(call)),
|
||||
container(text("Copy tool name and all arguments").size(11))
|
||||
.padding(8)
|
||||
.style(preference_group_style),
|
||||
tooltip::Position::Top,
|
||||
)
|
||||
.gap(6);
|
||||
let copy_result = action_button(text("Copy result").size(11)).padding([5, 9]);
|
||||
let copy_result = if let Some(result) = &card.result {
|
||||
copy_result.on_press(Message::CopyToolText(result.clone()))
|
||||
} else {
|
||||
copy_result
|
||||
};
|
||||
let copy_result = tooltip(
|
||||
copy_result,
|
||||
container(text("Copy the complete tool result").size(11))
|
||||
.padding(8)
|
||||
.style(preference_group_style),
|
||||
tooltip::Position::Top,
|
||||
)
|
||||
.gap(6);
|
||||
let mut actions = row![copy_call, copy_result]
|
||||
.spacing(6)
|
||||
.align_y(Alignment::Center);
|
||||
if let Some(path) = card
|
||||
.result
|
||||
.as_deref()
|
||||
.and_then(crate::agent::tool_output_path)
|
||||
{
|
||||
actions = actions.push(
|
||||
tooltip(
|
||||
action_button(text("Open output").size(11))
|
||||
.padding([5, 9])
|
||||
.on_press(Message::OpenToolOutput(path)),
|
||||
container(text("Open the complete output file").size(11))
|
||||
.padding(8)
|
||||
.style(preference_group_style),
|
||||
tooltip::Position::Top,
|
||||
)
|
||||
.gap(6),
|
||||
);
|
||||
}
|
||||
let mut content = column![
|
||||
row![
|
||||
text(card.call.name).size(13),
|
||||
Space::with_width(Length::Fill),
|
||||
text(card.state.label()).size(11).color(muted_text()),
|
||||
actions,
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(Alignment::Center),
|
||||
text(parameters).size(12).color(muted_text()),
|
||||
]
|
||||
.spacing(5);
|
||||
if let Some(result) = card.result {
|
||||
let bounded = crate::agent::bounded_tool_text(&result, 1_200);
|
||||
content = content.push(text(bounded).size(12));
|
||||
}
|
||||
rows = rows.push(container(content).padding(10).width(Length::Fill));
|
||||
}
|
||||
container(rows)
|
||||
.width(Length::Fill)
|
||||
.style(preference_group_style)
|
||||
.into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user