@@ -977,7 +977,10 @@ impl AgentConfiguration {
} else {
AgentIcon::Name(IconName::Ai)
};
- (name, icon)
+ let display_name = agent_server_store
+ .agent_display_name(&name)
+ .unwrap_or_else(|| name.0.clone());
+ (name, icon, display_name)
})
.collect();
@@ -1084,6 +1087,7 @@ impl AgentConfiguration {
.child(self.render_agent_server(
AgentIcon::Name(IconName::AiClaude),
"Claude Code",
+ "Claude Code",
false,
cx,
))
@@ -1091,6 +1095,7 @@ impl AgentConfiguration {
.child(self.render_agent_server(
AgentIcon::Name(IconName::AiOpenAi),
"Codex CLI",
+ "Codex CLI",
false,
cx,
))
@@ -1098,16 +1103,23 @@ impl AgentConfiguration {
.child(self.render_agent_server(
AgentIcon::Name(IconName::AiGemini),
"Gemini CLI",
+ "Gemini CLI",
false,
cx,
))
.map(|mut parent| {
- for (name, icon) in user_defined_agents {
+ for (name, icon, display_name) in user_defined_agents {
parent = parent
.child(
Divider::horizontal().color(DividerColor::BorderFaded),
)
- .child(self.render_agent_server(icon, name, true, cx));
+ .child(self.render_agent_server(
+ icon,
+ name,
+ display_name,
+ true,
+ cx,
+ ));
}
parent
}),
@@ -1118,11 +1130,13 @@ impl AgentConfiguration {
fn render_agent_server(
&self,
icon: AgentIcon,
- name: impl Into<SharedString>,
+ id: impl Into<SharedString>,
+ display_name: impl Into<SharedString>,
external: bool,
cx: &mut Context<Self>,
) -> impl IntoElement {
- let name = name.into();
+ let id = id.into();
+ let display_name = display_name.into();
let icon = match icon {
AgentIcon::Name(icon_name) => Icon::new(icon_name)
.size(IconSize::Small)
@@ -1132,12 +1146,15 @@ impl AgentConfiguration {
.color(Color::Muted),
};
- let tooltip_id = SharedString::new(format!("agent-source-{}", name));
- let tooltip_message = format!("The {} agent was installed from an extension.", name);
+ let tooltip_id = SharedString::new(format!("agent-source-{}", id));
+ let tooltip_message = format!(
+ "The {} agent was installed from an extension.",
+ display_name
+ );
- let agent_server_name = ExternalAgentServerName(name.clone());
+ let agent_server_name = ExternalAgentServerName(id.clone());
- let uninstall_btn_id = SharedString::from(format!("uninstall-{}", name));
+ let uninstall_btn_id = SharedString::from(format!("uninstall-{}", id));
let uninstall_button = IconButton::new(uninstall_btn_id, IconName::Trash)
.icon_color(Color::Muted)
.icon_size(IconSize::Small)
@@ -1161,7 +1178,7 @@ impl AgentConfiguration {
h_flex()
.gap_1p5()
.child(icon)
- .child(Label::new(name))
+ .child(Label::new(display_name))
.when(external, |this| {
this.child(
div()
@@ -137,6 +137,7 @@ pub struct AgentServerStore {
state: AgentServerStoreState,
external_agents: HashMap<ExternalAgentServerName, Box<dyn ExternalAgentServer>>,
agent_icons: HashMap<ExternalAgentServerName, SharedString>,
+ agent_display_names: HashMap<ExternalAgentServerName, SharedString>,
}
pub struct AgentServersUpdated;
@@ -155,6 +156,7 @@ mod ext_agent_tests {
state: AgentServerStoreState::Collab,
external_agents: HashMap::default(),
agent_icons: HashMap::default(),
+ agent_display_names: HashMap::default(),
}
}
@@ -258,6 +260,7 @@ impl AgentServerStore {
self.external_agents.retain(|name, agent| {
if agent.downcast_mut::<LocalExtensionArchiveAgent>().is_some() {
self.agent_icons.remove(name);
+ self.agent_display_names.remove(name);
false
} else {
// Keep the hardcoded external agents that don't come from extensions
@@ -275,6 +278,12 @@ impl AgentServerStore {
for (ext_id, manifest) in manifests {
for (agent_name, agent_entry) in &manifest.agent_servers {
// Store absolute icon path if provided, resolving symlinks for dev extensions
+ // Store display name from manifest
+ self.agent_display_names.insert(
+ ExternalAgentServerName(agent_name.clone().into()),
+ SharedString::from(agent_entry.name.clone()),
+ );
+
let icon_path = if let Some(icon) = &agent_entry.icon {
let icon_path = extensions_dir.join(ext_id).join(icon);
// Canonicalize to resolve symlinks (dev extensions are symlinked)
@@ -310,6 +319,12 @@ impl AgentServerStore {
let mut agents = vec![];
for (ext_id, manifest) in manifests {
for (agent_name, agent_entry) in &manifest.agent_servers {
+ // Store display name from manifest
+ self.agent_display_names.insert(
+ ExternalAgentServerName(agent_name.clone().into()),
+ SharedString::from(agent_entry.name.clone()),
+ );
+
// Store absolute icon path if provided, resolving symlinks for dev extensions
let icon = if let Some(icon) = &agent_entry.icon {
let icon_path = extensions_dir.join(ext_id).join(icon);
@@ -369,6 +384,10 @@ impl AgentServerStore {
self.agent_icons.get(name).cloned()
}
+ pub fn agent_display_name(&self, name: &ExternalAgentServerName) -> Option<SharedString> {
+ self.agent_display_names.get(name).cloned()
+ }
+
pub fn init_remote(session: &AnyProtoClient) {
session.add_entity_message_handler(Self::handle_external_agents_updated);
session.add_entity_message_handler(Self::handle_loading_status_updated);
@@ -559,6 +578,7 @@ impl AgentServerStore {
},
external_agents: Default::default(),
agent_icons: Default::default(),
+ agent_display_names: Default::default(),
};
if let Some(_events) = extension::ExtensionEvents::try_global(cx) {}
this.agent_servers_settings_changed(cx);
@@ -609,6 +629,7 @@ impl AgentServerStore {
},
external_agents: external_agents.into_iter().collect(),
agent_icons: HashMap::default(),
+ agent_display_names: HashMap::default(),
}
}
@@ -617,6 +638,7 @@ impl AgentServerStore {
state: AgentServerStoreState::Collab,
external_agents: Default::default(),
agent_icons: Default::default(),
+ agent_display_names: Default::default(),
}
}
@@ -2040,6 +2062,7 @@ mod extension_agent_tests {
state: AgentServerStoreState::Collab,
external_agents: HashMap::default(),
agent_icons: HashMap::default(),
+ agent_display_names: HashMap::default(),
};
// Seed with extension agents (contain ": ") and custom agents (don't contain ": ")