Skip to content

Commit 8d931c0

Browse files
authored
feat: Supported model degradation info. (#1607)
1 parent 6e57702 commit 8d931c0

16 files changed

Lines changed: 159 additions & 69 deletions

File tree

com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/lsp/protocol/CopilotModel.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class CopilotModel {
2020
private boolean isChatFallback;
2121
private CopilotModelCapabilities capabilities;
2222
private CopilotModelBilling billing;
23+
private String degradationReason;
2324
private String providerName;
2425

2526
/**
@@ -152,6 +153,14 @@ public void setBilling(CopilotModelBilling billing) {
152153
this.billing = billing;
153154
}
154155

156+
public String getDegradationReason() {
157+
return degradationReason;
158+
}
159+
160+
public void setDegradationReason(String degradationReason) {
161+
this.degradationReason = degradationReason;
162+
}
163+
155164
public String getProviderName() {
156165
return providerName;
157166
}
@@ -173,17 +182,17 @@ public boolean equals(Object obj) {
173182
}
174183
CopilotModel other = (CopilotModel) obj;
175184
return Objects.equals(billing, other.billing) && Objects.equals(capabilities, other.capabilities)
176-
&& Objects.equals(id, other.id) && isChatDefault == other.isChatDefault
177-
&& isChatFallback == other.isChatFallback && Objects.equals(modelFamily, other.modelFamily)
178-
&& Objects.equals(modelName, other.modelName) && Objects.equals(modelPolicy, other.modelPolicy)
179-
&& preview == other.preview && Objects.equals(scopes, other.scopes)
180-
&& Objects.equals(providerName, other.providerName);
185+
&& Objects.equals(degradationReason, other.degradationReason) && Objects.equals(id, other.id)
186+
&& isChatDefault == other.isChatDefault && isChatFallback == other.isChatFallback
187+
&& Objects.equals(modelFamily, other.modelFamily) && Objects.equals(modelName, other.modelName)
188+
&& Objects.equals(modelPolicy, other.modelPolicy) && preview == other.preview
189+
&& Objects.equals(providerName, other.providerName) && Objects.equals(scopes, other.scopes);
181190
}
182191

183192
@Override
184193
public int hashCode() {
185-
return Objects.hash(billing, capabilities, id, isChatDefault, isChatFallback, modelFamily, modelName, modelPolicy,
186-
preview, scopes, providerName);
194+
return Objects.hash(billing, capabilities, degradationReason, id, isChatDefault, isChatFallback, modelFamily,
195+
modelName, modelPolicy, preview, providerName, scopes);
187196
}
188197

189198
@Override
@@ -199,7 +208,9 @@ public String toString() {
199208
builder.append("isChatFallback", isChatFallback);
200209
builder.append("capabilities", capabilities);
201210
builder.append("billing", billing);
211+
builder.append("degradationReason", degradationReason);
202212
builder.append("providerName", providerName);
203213
return builder.toString();
204214
}
215+
205216
}

com.microsoft.copilot.eclipse.ui/css/dark.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@
162162
#chat-history-viewer Label.chat-history-item-current-label,
163163
#chat-history-viewer Label.chat-history-item-date-label,
164164
#popup-item-default Label.popup-secondary-text,
165-
#popup-item-selected Label.popup-secondary-text {
165+
#popup-item-selected Label.popup-secondary-text,
166+
#dropdown-popup Label.popup-secondary-text {
166167
color: #A4A4A4;
167168
}
168169

com.microsoft.copilot.eclipse.ui/css/light.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@
162162
#chat-history-viewer Label.chat-history-item-current-label,
163163
#chat-history-viewer Label.chat-history-item-date-label,
164164
#popup-item-default Label.popup-secondary-text,
165-
#popup-item-selected Label.popup-secondary-text {
165+
#popup-item-selected Label.popup-secondary-text,
166+
#dropdown-popup Label.popup-secondary-text {
166167
color: #808080;
167168
}
168169

324 Bytes
Loading
596 Bytes
Loading
388 Bytes
Loading
642 Bytes
Loading

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ActionBar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ private void setUpModelPicker(Composite parent) {
481481
private void setUpChatModePicker(Composite parent) {
482482
this.modePickerButton = new DropdownButton(parent, SWT.NONE);
483483
this.modePickerButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
484+
this.modePickerButton.setToolTipText(Messages.chat_actionBar_modePicker_Tooltip);
484485
this.modePickerButton.setAccessibilityName("chat mode picker");
485486
UserPreferenceService userPreferenceService = chatServiceManager.getUserPreferenceService();
486487
userPreferenceService.bindChatModePicker(this.modePickerButton);

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ModelPickerGroupsBuilder.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import java.util.List;
66
import java.util.Map;
77

8+
import org.apache.commons.lang3.StringUtils;
9+
import org.eclipse.swt.SWT;
10+
import org.eclipse.swt.graphics.Image;
11+
import org.eclipse.swt.widgets.Display;
12+
813
import com.microsoft.copilot.eclipse.core.lsp.protocol.CopilotModel;
914
import com.microsoft.copilot.eclipse.ui.i18n.Messages;
1015
import com.microsoft.copilot.eclipse.ui.preferences.ByokPreferencePage;
@@ -13,13 +18,16 @@
1318
import com.microsoft.copilot.eclipse.ui.swt.ModelHoverContentProvider;
1419
import com.microsoft.copilot.eclipse.ui.utils.ModelUtils;
1520
import com.microsoft.copilot.eclipse.ui.utils.PreferencesUtils;
21+
import com.microsoft.copilot.eclipse.ui.utils.SwtUtils;
1622
import com.microsoft.copilot.eclipse.ui.utils.UiUtils;
1723

1824
/**
1925
* Builds model picker dropdown groups for the chat UI.
2026
*/
2127
public final class ModelPickerGroupsBuilder {
2228

29+
private static Image warningIcon;
30+
2331
private ModelPickerGroupsBuilder() {
2432
}
2533

@@ -31,8 +39,8 @@ private ModelPickerGroupsBuilder() {
3139
* @param showByokManageOption whether to include the BYOK manage action
3240
* @return grouped dropdown items for the model picker
3341
*/
34-
public static List<DropdownItemGroup> build(Map<String, CopilotModel> modelMap,
35-
boolean showAddPremiumModelOption, boolean showByokManageOption) {
42+
public static List<DropdownItemGroup> build(Map<String, CopilotModel> modelMap, boolean showAddPremiumModelOption,
43+
boolean showByokManageOption) {
3644
List<CopilotModel> otherModels = new ArrayList<>();
3745
List<CopilotModel> standardModels = new ArrayList<>();
3846
List<CopilotModel> premiumModels = new ArrayList<>();
@@ -79,8 +87,7 @@ public static List<DropdownItemGroup> build(Map<String, CopilotModel> modelMap,
7987
}
8088
if (showByokManageOption) {
8189
actionItems.add(new DropdownItem.Builder().label(Messages.chat_actionBar_modelPicker_manageModels)
82-
.onAction(ModelPickerGroupsBuilder::openManageModelsPreferences)
83-
.build());
90+
.onAction(ModelPickerGroupsBuilder::openManageModelsPreferences).build());
8491
}
8592
if (!actionItems.isEmpty()) {
8693
groups.add(DropdownItemGroup.of(actionItems));
@@ -93,11 +100,34 @@ private static List<DropdownItem> buildModelDropdownItems(List<CopilotModel> mod
93100
for (CopilotModel model : models) {
94101
String suffix = ModelUtils.getModelSuffix(model);
95102
items.add(new DropdownItem.Builder().id(model.getModelName()).label(model.getModelName()).suffix(suffix)
96-
.hoverProvider(new ModelHoverContentProvider(model)).build());
103+
.icon(resolveModelIcon(model)).hoverProvider(new ModelHoverContentProvider(model)).build());
97104
}
98105
return items;
99106
}
100107

108+
private static Image resolveModelIcon(CopilotModel model) {
109+
if (StringUtils.isBlank(model.getDegradationReason())) {
110+
return null;
111+
}
112+
if (warningIcon == null || warningIcon.isDisposed()) {
113+
warningIcon = UiUtils.isDarkTheme()
114+
? UiUtils.buildImageFromPngPath("/icons/dropdown/dropdown_warning_dark.png")
115+
: UiUtils.buildImageFromPngPath("/icons/dropdown/dropdown_warning.png");
116+
Display display = SwtUtils.getDisplay();
117+
if (display != null) {
118+
display.addListener(SWT.Dispose, event -> disposeWarningIcons());
119+
}
120+
}
121+
return warningIcon;
122+
}
123+
124+
private static void disposeWarningIcons() {
125+
if (warningIcon != null && !warningIcon.isDisposed()) {
126+
warningIcon.dispose();
127+
warningIcon = null;
128+
}
129+
}
130+
101131
private static void openManageModelsPreferences() {
102132
Map<String, Object> parameters = new HashMap<>();
103133
parameters.put("com.microsoft.copilot.eclipse.commands.openPreferences.activePageId", ByokPreferencePage.ID);

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/services/ModelService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.Map;
77
import java.util.concurrent.ExecutionException;
88

9+
import org.apache.commons.lang3.StringUtils;
910
import org.eclipse.core.databinding.observable.sideeffect.ISideEffect;
1011
import org.eclipse.core.databinding.observable.value.IObservableValue;
1112
import org.eclipse.core.databinding.observable.value.WritableValue;
@@ -14,6 +15,7 @@
1415
import org.eclipse.core.runtime.Status;
1516
import org.eclipse.core.runtime.jobs.Job;
1617
import org.eclipse.e4.core.services.events.IEventBroker;
18+
import org.eclipse.osgi.util.NLS;
1719
import org.eclipse.ui.PlatformUI;
1820
import org.osgi.service.event.EventHandler;
1921

@@ -34,6 +36,7 @@
3436
import com.microsoft.copilot.eclipse.core.lsp.protocol.quota.CopilotPlan;
3537
import com.microsoft.copilot.eclipse.ui.chat.ActionBar;
3638
import com.microsoft.copilot.eclipse.ui.chat.ModelPickerGroupsBuilder;
39+
import com.microsoft.copilot.eclipse.ui.i18n.Messages;
3740
import com.microsoft.copilot.eclipse.ui.swt.DropdownButton;
3841
import com.microsoft.copilot.eclipse.ui.utils.ModelUtils;
3942

@@ -433,6 +436,9 @@ public void bindModelPicker(final DropdownButton picker) {
433436
return;
434437
}
435438
picker.setSelectedItemId(activeModel.getModelName());
439+
String suffix = StringUtils.isNotBlank(activeModel.getDegradationReason())
440+
? " - " + activeModel.getDegradationReason() : "";
441+
picker.setToolTipText(NLS.bind(Messages.chat_actionBar_modelPicker_Tooltip, suffix));
436442
});
437443

438444
// Store the side effects for later disposal

0 commit comments

Comments
 (0)