Use icon in more places

Richard Feldman created

Change summary

assets/settings/default.json                      |  7 -----
crates/acp_thread/src/connection.rs               | 11 ++++++++
crates/agent/src/agent.rs                         | 11 ++++++--
crates/agent_ui/src/acp/model_selector.rs         | 18 ++++++++++-----
crates/agent_ui/src/acp/model_selector_popover.rs | 13 +++++++---
extensions/anthropic/Cargo.lock                   | 20 ++++++++--------
6 files changed, 50 insertions(+), 30 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -1721,12 +1721,7 @@
   // If you don't want any of these extensions, add this field to your settings
   // and change the value to `false`.
   "auto_install_extensions": {
-    "anthropic": true,
-    "copilot-chat": true,
-    "google-ai": true,
-    "html": true,
-    "openai": true,
-    "open-router": true
+    "html": true
   },
   // The capabilities granted to extensions.
   //

crates/acp_thread/src/connection.rs 🔗

@@ -204,12 +204,21 @@ pub trait AgentModelSelector: 'static {
     }
 }
 
+/// Icon for a model in the model selector.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum AgentModelIcon {
+    /// A built-in icon from Zed's icon set.
+    Named(IconName),
+    /// Path to a custom SVG icon file.
+    Path(SharedString),
+}
+
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct AgentModelInfo {
     pub id: acp::ModelId,
     pub name: SharedString,
     pub description: Option<SharedString>,
-    pub icon: Option<IconName>,
+    pub icon: Option<AgentModelIcon>,
 }
 
 impl From<acp::ModelInfo> for AgentModelInfo {

crates/agent/src/agent.rs 🔗

@@ -18,7 +18,7 @@ pub use templates::*;
 pub use thread::*;
 pub use tools::*;
 
-use acp_thread::{AcpThread, AgentModelSelector};
+use acp_thread::{AcpThread, AgentModelIcon, AgentModelSelector};
 use agent_client_protocol as acp;
 use anyhow::{Context as _, Result, anyhow};
 use chrono::{DateTime, Utc};
@@ -161,11 +161,16 @@ impl LanguageModels {
         model: &Arc<dyn LanguageModel>,
         provider: &Arc<dyn LanguageModelProvider>,
     ) -> acp_thread::AgentModelInfo {
+        let icon = if let Some(path) = provider.icon_path() {
+            Some(AgentModelIcon::Path(path))
+        } else {
+            Some(AgentModelIcon::Named(provider.icon()))
+        };
         acp_thread::AgentModelInfo {
             id: Self::model_id(model),
             name: model.name().0,
             description: None,
-            icon: Some(provider.icon()),
+            icon,
         }
     }
 
@@ -1356,7 +1361,7 @@ mod internal_tests {
                     id: acp::ModelId::new("fake/fake"),
                     name: "Fake".into(),
                     description: None,
-                    icon: Some(ui::IconName::ZedAssistant),
+                    icon: Some(AgentModelIcon::Named(ui::IconName::ZedAssistant)),
                 }]
             )])
         );

crates/agent_ui/src/acp/model_selector.rs 🔗

@@ -1,6 +1,6 @@
 use std::{cmp::Reverse, rc::Rc, sync::Arc};
 
-use acp_thread::{AgentModelInfo, AgentModelList, AgentModelSelector};
+use acp_thread::{AgentModelIcon, AgentModelInfo, AgentModelList, AgentModelSelector};
 use agent_servers::AgentServer;
 use anyhow::Result;
 use collections::IndexMap;
@@ -292,12 +292,18 @@ impl PickerDelegate for AcpModelPickerDelegate {
                                     h_flex()
                                         .w_full()
                                         .gap_1p5()
-                                        .when_some(model_info.icon, |this, icon| {
-                                            this.child(
-                                                Icon::new(icon)
+                                        .map(|this| match &model_info.icon {
+                                            Some(AgentModelIcon::Path(path)) => this.child(
+                                                Icon::from_path(path.clone())
                                                     .color(model_icon_color)
-                                                    .size(IconSize::Small)
-                                            )
+                                                    .size(IconSize::Small),
+                                            ),
+                                            Some(AgentModelIcon::Named(icon)) => this.child(
+                                                Icon::new(*icon)
+                                                    .color(model_icon_color)
+                                                    .size(IconSize::Small),
+                                            ),
+                                            None => this,
                                         })
                                         .child(Label::new(model_info.name.clone()).truncate()),
                                 )

crates/agent_ui/src/acp/model_selector_popover.rs 🔗

@@ -1,7 +1,7 @@
 use std::rc::Rc;
 use std::sync::Arc;
 
-use acp_thread::{AgentModelInfo, AgentModelSelector};
+use acp_thread::{AgentModelIcon, AgentModelInfo, AgentModelSelector};
 use agent_servers::AgentServer;
 use fs::Fs;
 use gpui::{Entity, FocusHandle};
@@ -64,7 +64,7 @@ impl Render for AcpModelSelectorPopover {
             .map(|model| model.name.clone())
             .unwrap_or_else(|| SharedString::from("Select a Model"));
 
-        let model_icon = model.as_ref().and_then(|model| model.icon);
+        let model_icon = model.as_ref().and_then(|model| model.icon.clone());
 
         let focus_handle = self.focus_handle.clone();
 
@@ -78,8 +78,13 @@ impl Render for AcpModelSelectorPopover {
             self.selector.clone(),
             ButtonLike::new("active-model")
                 .selected_style(ButtonStyle::Tinted(TintColor::Accent))
-                .when_some(model_icon, |this, icon| {
-                    this.child(Icon::new(icon).color(color).size(IconSize::XSmall))
+                .when_some(model_icon, |this, icon| match icon {
+                    AgentModelIcon::Path(path) => {
+                        this.child(Icon::from_path(path).color(color).size(IconSize::XSmall))
+                    }
+                    AgentModelIcon::Named(icon_name) => {
+                        this.child(Icon::new(icon_name).color(color).size(IconSize::XSmall))
+                    }
                 })
                 .child(
                     Label::new(model_name)

extensions/anthropic/Cargo.lock 🔗

@@ -8,6 +8,15 @@ version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
 
+[[package]]
+name = "anthropic"
+version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_json",
+ "zed_extension_api",
+]
+
 [[package]]
 name = "anyhow"
 version = "1.0.100"
@@ -64,15 +73,6 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
-[[package]]
-name = "fanthropic"
-version = "0.1.0"
-dependencies = [
- "serde",
- "serde_json",
- "zed_extension_api",
-]
-
 [[package]]
 name = "flate2"
 version = "1.1.5"
@@ -761,7 +761,7 @@ dependencies = [
 
 [[package]]
 name = "zed_extension_api"
-version = "0.7.0"
+version = "0.8.0"
 dependencies = [
  "serde",
  "serde_json",