Skip to content

Commit c14d84c

Browse files
authored
acp: Add button to configure custom agent in the configuration view (#36923)
Release Notes: - N/A
1 parent 428fc6d commit c14d84c

File tree

1 file changed

+102
-5
lines changed

1 file changed

+102
-5
lines changed

crates/agent_ui/src/agent_configuration.rs

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@ mod tool_picker;
55

66
use std::{sync::Arc, time::Duration};
77

8-
use agent_servers::{AgentServerCommand, AllAgentServersSettings, Gemini};
8+
use agent_servers::{AgentServerCommand, AgentServerSettings, AllAgentServersSettings, Gemini};
99
use agent_settings::AgentSettings;
10+
use anyhow::Result;
1011
use assistant_tool::{ToolSource, ToolWorkingSet};
1112
use cloud_llm_client::Plan;
1213
use collections::HashMap;
1314
use context_server::ContextServerId;
15+
use editor::{Editor, SelectionEffects, scroll::Autoscroll};
1416
use extension::ExtensionManifest;
1517
use extension_host::ExtensionStore;
1618
use fs::Fs;
1719
use gpui::{
18-
Action, Animation, AnimationExt as _, AnyView, App, Corner, Entity, EventEmitter, FocusHandle,
19-
Focusable, Hsla, ScrollHandle, Subscription, Task, Transformation, WeakEntity, percentage,
20+
Action, Animation, AnimationExt as _, AnyView, App, AsyncWindowContext, Corner, Entity,
21+
EventEmitter, FocusHandle, Focusable, Hsla, ScrollHandle, Subscription, Task, Transformation,
22+
WeakEntity, percentage,
2023
};
2124
use language::LanguageRegistry;
2225
use language_model::{
@@ -34,7 +37,7 @@ use ui::{
3437
Scrollbar, ScrollbarState, Switch, SwitchColor, SwitchField, Tooltip, prelude::*,
3538
};
3639
use util::ResultExt as _;
37-
use workspace::Workspace;
40+
use workspace::{Workspace, create_and_open_local_file};
3841
use zed_actions::ExtensionCategoryFilter;
3942

4043
pub(crate) use configure_context_server_modal::ConfigureContextServerModal;
@@ -1058,7 +1061,36 @@ impl AgentConfiguration {
10581061
.child(
10591062
v_flex()
10601063
.gap_0p5()
1061-
.child(Headline::new("External Agents"))
1064+
.child(
1065+
h_flex()
1066+
.w_full()
1067+
.gap_2()
1068+
.justify_between()
1069+
.child(Headline::new("External Agents"))
1070+
.child(
1071+
Button::new("add-agent", "Add Agent")
1072+
.icon_position(IconPosition::Start)
1073+
.icon(IconName::Plus)
1074+
.icon_size(IconSize::Small)
1075+
.icon_color(Color::Muted)
1076+
.label_size(LabelSize::Small)
1077+
.on_click(
1078+
move |_, window, cx| {
1079+
if let Some(workspace) = window.root().flatten() {
1080+
let workspace = workspace.downgrade();
1081+
window
1082+
.spawn(cx, async |cx| {
1083+
open_new_agent_servers_entry_in_settings_editor(
1084+
workspace,
1085+
cx,
1086+
).await
1087+
})
1088+
.detach_and_log_err(cx);
1089+
}
1090+
}
1091+
),
1092+
)
1093+
)
10621094
.child(
10631095
Label::new(
10641096
"Use the full power of Zed's UI with your favorite agent, connected via the Agent Client Protocol.",
@@ -1324,3 +1356,68 @@ fn show_unable_to_uninstall_extension_with_context_server(
13241356

13251357
workspace.toggle_status_toast(status_toast, cx);
13261358
}
1359+
1360+
async fn open_new_agent_servers_entry_in_settings_editor(
1361+
workspace: WeakEntity<Workspace>,
1362+
cx: &mut AsyncWindowContext,
1363+
) -> Result<()> {
1364+
let settings_editor = workspace
1365+
.update_in(cx, |_, window, cx| {
1366+
create_and_open_local_file(paths::settings_file(), window, cx, || {
1367+
settings::initial_user_settings_content().as_ref().into()
1368+
})
1369+
})?
1370+
.await?
1371+
.downcast::<Editor>()
1372+
.unwrap();
1373+
1374+
settings_editor
1375+
.downgrade()
1376+
.update_in(cx, |item, window, cx| {
1377+
let text = item.buffer().read(cx).snapshot(cx).text();
1378+
1379+
let settings = cx.global::<SettingsStore>();
1380+
1381+
let edits = settings.edits_for_update::<AllAgentServersSettings>(&text, |file| {
1382+
let unique_server_name = (0..u8::MAX)
1383+
.map(|i| {
1384+
if i == 0 {
1385+
"your_agent".into()
1386+
} else {
1387+
format!("your_agent_{}", i).into()
1388+
}
1389+
})
1390+
.find(|name| !file.custom.contains_key(name));
1391+
if let Some(server_name) = unique_server_name {
1392+
file.custom.insert(
1393+
server_name,
1394+
AgentServerSettings {
1395+
command: AgentServerCommand {
1396+
path: "path_to_executable".into(),
1397+
args: vec![],
1398+
env: Some(HashMap::default()),
1399+
},
1400+
},
1401+
);
1402+
}
1403+
});
1404+
1405+
if !edits.is_empty() {
1406+
let ranges = edits
1407+
.iter()
1408+
.map(|(range, _)| range.clone())
1409+
.collect::<Vec<_>>();
1410+
1411+
item.edit(edits, cx);
1412+
1413+
item.change_selections(
1414+
SelectionEffects::scroll(Autoscroll::newest()),
1415+
window,
1416+
cx,
1417+
|selections| {
1418+
selections.select_ranges(ranges);
1419+
},
1420+
);
1421+
}
1422+
})
1423+
}

0 commit comments

Comments
 (0)