@@ -5,18 +5,21 @@ mod tool_picker;
55
66use std:: { sync:: Arc , time:: Duration } ;
77
8- use agent_servers:: { AgentServerCommand , AllAgentServersSettings , Gemini } ;
8+ use agent_servers:: { AgentServerCommand , AgentServerSettings , AllAgentServersSettings , Gemini } ;
99use agent_settings:: AgentSettings ;
10+ use anyhow:: Result ;
1011use assistant_tool:: { ToolSource , ToolWorkingSet } ;
1112use cloud_llm_client:: Plan ;
1213use collections:: HashMap ;
1314use context_server:: ContextServerId ;
15+ use editor:: { Editor , SelectionEffects , scroll:: Autoscroll } ;
1416use extension:: ExtensionManifest ;
1517use extension_host:: ExtensionStore ;
1618use fs:: Fs ;
1719use 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} ;
2124use language:: LanguageRegistry ;
2225use language_model:: {
@@ -34,7 +37,7 @@ use ui::{
3437 Scrollbar , ScrollbarState , Switch , SwitchColor , SwitchField , Tooltip , prelude:: * ,
3538} ;
3639use util:: ResultExt as _;
37- use workspace:: Workspace ;
40+ use workspace:: { Workspace , create_and_open_local_file } ;
3841use zed_actions:: ExtensionCategoryFilter ;
3942
4043pub ( 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