Add example agent tool preview (#28984)
This PR adds an example of rendering previews for tools using the new Agent ToolCard style.  Release Notes: - N/A --------- Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This commit is contained in:
parent
7a95c14625
commit
acc4a5ccb3
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -703,6 +703,7 @@ dependencies = [
|
||||
"assistant_tool",
|
||||
"chrono",
|
||||
"collections",
|
||||
"component",
|
||||
"feature_flags",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
@ -711,6 +712,7 @@ dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"language",
|
||||
"language_model",
|
||||
"linkme",
|
||||
"open",
|
||||
"project",
|
||||
"rand 0.8.5",
|
||||
|
@ -16,6 +16,7 @@ anyhow.workspace = true
|
||||
assistant_tool.workspace = true
|
||||
chrono.workspace = true
|
||||
collections.workspace = true
|
||||
component.workspace = true
|
||||
feature_flags.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
@ -24,6 +25,8 @@ http_client.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
language_model.workspace = true
|
||||
linkme.workspace = true
|
||||
open.workspace = true
|
||||
project.workspace = true
|
||||
regex.workspace = true
|
||||
schemars.workspace = true
|
||||
@ -31,10 +34,9 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
worktree.workspace = true
|
||||
open = { workspace = true }
|
||||
web_search.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
worktree.workspace = true
|
||||
zed_llm_client.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -14,7 +14,7 @@ use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ui::{IconName, Tooltip, prelude::*};
|
||||
use web_search::WebSearchRegistry;
|
||||
use zed_llm_client::WebSearchResponse;
|
||||
use zed_llm_client::{WebSearchCitation, WebSearchResponse};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct WebSearchToolInput {
|
||||
@ -22,6 +22,7 @@ pub struct WebSearchToolInput {
|
||||
query: String,
|
||||
}
|
||||
|
||||
#[derive(RegisterComponent)]
|
||||
pub struct WebSearchTool;
|
||||
|
||||
impl Tool for WebSearchTool {
|
||||
@ -211,3 +212,111 @@ impl ToolCard for WebSearchToolCard {
|
||||
v_flex().my_2().gap_1().child(header).children(content)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for WebSearchTool {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::Agent
|
||||
}
|
||||
|
||||
fn sort_name() -> &'static str {
|
||||
"ToolWebSearch"
|
||||
}
|
||||
|
||||
fn preview(window: &mut Window, cx: &mut App) -> Option<AnyElement> {
|
||||
let in_progress_search = cx.new(|cx| WebSearchToolCard {
|
||||
response: None,
|
||||
_task: cx.spawn(async move |_this, cx| {
|
||||
loop {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_secs(60))
|
||||
.await
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
let successful_search = cx.new(|_cx| WebSearchToolCard {
|
||||
response: Some(Ok(example_search_response())),
|
||||
_task: Task::ready(()),
|
||||
});
|
||||
|
||||
let error_search = cx.new(|_cx| WebSearchToolCard {
|
||||
response: Some(Err(anyhow!("Failed to resolve https://google.com"))),
|
||||
_task: Task::ready(()),
|
||||
});
|
||||
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![example_group(vec![
|
||||
single_example(
|
||||
"In Progress",
|
||||
div()
|
||||
.size_full()
|
||||
.child(in_progress_search.update(cx, |tool, cx| {
|
||||
tool.render(&ToolUseStatus::Pending, window, cx)
|
||||
.into_any_element()
|
||||
}))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Successful",
|
||||
div()
|
||||
.size_full()
|
||||
.child(successful_search.update(cx, |tool, cx| {
|
||||
tool.render(&ToolUseStatus::Finished("".into()), window, cx)
|
||||
.into_any_element()
|
||||
}))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Error",
|
||||
div()
|
||||
.size_full()
|
||||
.child(error_search.update(cx, |tool, cx| {
|
||||
tool.render(&ToolUseStatus::Error("".into()), window, cx)
|
||||
.into_any_element()
|
||||
}))
|
||||
.into_any_element(),
|
||||
),
|
||||
])])
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn example_search_response() -> WebSearchResponse {
|
||||
WebSearchResponse {
|
||||
summary: r#"Toronto boasts a vibrant culinary scene with a diverse array of..."#
|
||||
.to_string(),
|
||||
citations: vec![
|
||||
WebSearchCitation {
|
||||
title: "Alo".to_string(),
|
||||
url: "https://www.google.com/maps/search/Alo%2C+Toronto%2C+Canada".to_string(),
|
||||
range: Some(147..213),
|
||||
},
|
||||
WebSearchCitation {
|
||||
title: "Edulis".to_string(),
|
||||
url: "https://www.google.com/maps/search/Edulis%2C+Toronto%2C+Canada".to_string(),
|
||||
range: Some(447..519),
|
||||
},
|
||||
WebSearchCitation {
|
||||
title: "Sushi Masaki Saito".to_string(),
|
||||
url: "https://www.google.com/maps/search/Sushi+Masaki+Saito%2C+Toronto%2C+Canada"
|
||||
.to_string(),
|
||||
range: Some(776..872),
|
||||
},
|
||||
WebSearchCitation {
|
||||
title: "Shoushin".to_string(),
|
||||
url: "https://www.google.com/maps/search/Shoushin%2C+Toronto%2C+Canada".to_string(),
|
||||
range: Some(1072..1148),
|
||||
},
|
||||
WebSearchCitation {
|
||||
title: "Restaurant 20 Victoria".to_string(),
|
||||
url:
|
||||
"https://www.google.com/maps/search/Restaurant+20+Victoria%2C+Toronto%2C+Canada"
|
||||
.to_string(),
|
||||
range: Some(1291..1395),
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ pub fn components() -> AllComponents {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ComponentScope {
|
||||
Agent,
|
||||
Collaboration,
|
||||
DataDisplay,
|
||||
Editor,
|
||||
@ -220,6 +221,7 @@ pub enum ComponentScope {
|
||||
impl Display for ComponentScope {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ComponentScope::Agent => write!(f, "Agent"),
|
||||
ComponentScope::Collaboration => write!(f, "Collaboration"),
|
||||
ComponentScope::DataDisplay => write!(f, "Data Display"),
|
||||
ComponentScope::Editor => write!(f, "Editor"),
|
||||
|
@ -19,6 +19,9 @@ extend-exclude = [
|
||||
# Some crate names are flagged as typos.
|
||||
"crates/indexed_docs/src/providers/rustdoc/popular_crates.txt",
|
||||
|
||||
# Some mock data is flagged as typos.
|
||||
"crates/assistant_tools/src/web_search_tool.rs",
|
||||
|
||||
# Stripe IDs are flagged as typos.
|
||||
"crates/collab/src/db/tests/processed_stripe_event_tests.rs",
|
||||
# Not our typos.
|
||||
|
Loading…
Reference in New Issue
Block a user