Detailed changes
@@ -0,0 +1,11 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1896_18)">
+<path d="M11.094 3.09999H8.952L12.858 12.9H15L11.094 3.09999Z" fill="#1F1F1E"/>
+<path d="M4.906 3.09999L1 12.9H3.184L3.98284 10.842H8.06915L8.868 12.9H11.052L7.146 3.09999H4.906ZM4.68928 9.02199L6.026 5.57799L7.3627 9.02199H4.68928Z" fill="#1F1F1E"/>
+</g>
+<defs>
+<clipPath id="clip0_1896_18">
+<rect width="14" height="9.8" fill="white" transform="translate(1 3.09999)"/>
+</clipPath>
+</defs>
+</svg>
@@ -4135,7 +4135,7 @@ impl Render for ContextEditorToolbarItem {
(Some(provider), Some(model)) => h_flex()
.gap_1()
.child(
- Icon::new(provider.icon())
+ Icon::new(model.icon().unwrap_or_else(|| provider.icon()))
.color(Color::Muted)
.size(IconSize::XSmall),
)
@@ -36,7 +36,7 @@ pub struct ModelPickerDelegate {
#[derive(Clone)]
struct ModelInfo {
model: Arc<dyn LanguageModel>,
- provider_icon: IconName,
+ icon: IconName,
availability: LanguageModelAvailability,
is_selected: bool,
}
@@ -156,7 +156,7 @@ impl PickerDelegate for ModelPickerDelegate {
.selected(selected)
.start_slot(
div().pr_1().child(
- Icon::new(model_info.provider_icon)
+ Icon::new(model_info.icon)
.color(Color::Muted)
.size(IconSize::Medium),
),
@@ -261,16 +261,17 @@ impl<T: PopoverTrigger> RenderOnce for ModelSelector<T> {
.iter()
.flat_map(|provider| {
let provider_id = provider.id();
- let provider_icon = provider.icon();
+ let icon = provider.icon();
let selected_model = selected_model.clone();
let selected_provider = selected_provider.clone();
provider.provided_models(cx).into_iter().map(move |model| {
let model = model.clone();
+ let icon = model.icon().unwrap_or(icon);
ModelInfo {
model: model.clone(),
- provider_icon,
+ icon,
availability: model.availability(),
is_selected: selected_model.as_ref() == Some(&model.id())
&& selected_provider.as_ref() == Some(&provider_id),
@@ -54,6 +54,10 @@ pub struct LanguageModelCacheConfiguration {
pub trait LanguageModel: Send + Sync {
fn id(&self) -> LanguageModelId;
fn name(&self) -> LanguageModelName;
+ /// If None, falls back to [LanguageModelProvider::icon]
+ fn icon(&self) -> Option<IconName> {
+ None
+ }
fn provider_id(&self) -> LanguageModelProviderId;
fn provider_name(&self) -> LanguageModelProviderName;
fn telemetry_id(&self) -> String;
@@ -2,6 +2,7 @@ use proto::Plan;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::EnumIter;
+use ui::IconName;
use crate::LanguageModelAvailability;
@@ -65,6 +66,13 @@ impl CloudModel {
}
}
+ pub fn icon(&self) -> Option<IconName> {
+ match self {
+ Self::Anthropic(_) => Some(IconName::AiAnthropicHosted),
+ _ => None,
+ }
+ }
+
pub fn max_token_count(&self) -> usize {
match self {
Self::Anthropic(model) => model.max_token_count(),
@@ -398,6 +398,10 @@ impl LanguageModel for CloudLanguageModel {
LanguageModelName::from(self.model.display_name().to_string())
}
+ fn icon(&self) -> Option<IconName> {
+ self.model.icon()
+ }
+
fn provider_id(&self) -> LanguageModelProviderId {
LanguageModelProviderId(PROVIDER_ID.into())
}
@@ -107,6 +107,7 @@ impl IconSize {
pub enum IconName {
Ai,
AiAnthropic,
+ AiAnthropicHosted,
AiOpenAi,
AiGoogle,
AiOllama,
@@ -275,6 +276,7 @@ impl IconName {
match self {
IconName::Ai => "icons/ai.svg",
IconName::AiAnthropic => "icons/ai_anthropic.svg",
+ IconName::AiAnthropicHosted => "icons/ai_anthropic_hosted.svg",
IconName::AiOpenAi => "icons/ai_open_ai.svg",
IconName::AiGoogle => "icons/ai_google.svg",
IconName::AiOllama => "icons/ai_ollama.svg",