fix(ai): align builtin model picker chrome

This commit is contained in:
Fini 2026-05-30 15:49:11 +08:00
parent da198f6432
commit 67ed9ae146
3 changed files with 48 additions and 3 deletions

View file

@ -460,7 +460,7 @@ fn with_alpha(color: Color, a: f32) -> Color {
Color { a, ..color }
}
fn paint_key_glyph(cx: &mut PaintCx<'_>, top_left: Point2D, size: f32, color: Color) {
pub(crate) fn paint_key_glyph(cx: &mut PaintCx<'_>, top_left: Point2D, size: f32, color: Color) {
let cy = top_left.y + size * 0.5;
let ring = Rect {
origin: Point2D::new(top_left.x, cy - size * 0.28),
@ -515,7 +515,7 @@ fn provider_label(provider: AgentProvider) -> &'static str {
match provider {
AgentProvider::ClaudeCode => "ANTHROPIC",
AgentProvider::CodexCli => "OPENAI",
AgentProvider::GeminiCli => "GEMINI",
AgentProvider::GeminiCli => "GOOGLE GEMINI",
AgentProvider::GithubCopilot => "GITHUB COPILOT",
AgentProvider::OpenCode => "OPENCODE",
}
@ -682,6 +682,11 @@ mod tests {
assert_eq!(group_label_for_entry(&entry), "OPENAI API KEY");
}
#[test]
fn gemini_provider_group_label_matches_ts_provider_name() {
assert_eq!(provider_label(AgentProvider::GeminiCli), "GOOGLE GEMINI");
}
#[test]
fn builtin_groups_stay_separate_when_ids_differ_but_provider_matches() {
let models = vec![

View file

@ -632,6 +632,16 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
let selected = self.state.selected_model_entry();
let chip_color = self.theme.muted_foreground;
match selected {
Some(entry)
if entry.builtin_provider_id.is_some() || entry.value.starts_with("builtin:") =>
{
crate::widgets::ai_chat_model_picker::paint_key_glyph(
cx,
Point2D::new(model_x, toolbar_center_y - 7.0),
14.0,
chip_color,
)
}
Some(entry) => crate::widgets::ai_chat_model_picker::paint_provider_logo(
cx,
entry.provider,

View file

@ -204,6 +204,7 @@ fn body_rect_reserves_space_for_fixed_step_checklist() {
#[derive(Default)]
struct PanelPaintBackend {
fills: Vec<(Rect, crate::Color)>,
stroke_lines: usize,
}
impl crate::RenderBackend for PanelPaintBackend {
@ -218,7 +219,9 @@ impl crate::RenderBackend for PanelPaintBackend {
fn save(&mut self) {}
fn restore(&mut self) {}
fn translate(&mut self, _: Point2D) {}
fn stroke_line(&mut self, _: Point2D, _: Point2D, _: crate::Color, _: f32) {}
fn stroke_line(&mut self, _: Point2D, _: Point2D, _: crate::Color, _: f32) {
self.stroke_lines += 1;
}
fn fill_round_rect(&mut self, _: Rect, _: f32, _: crate::Color) {}
fn stroke_round_rect(&mut self, _: Rect, _: f32, _: crate::Color, _: f32) {}
fn stroke_svg_path(&mut self, _: &str, _: Point2D, _: f32, _: crate::Color, _: f32) {}
@ -228,6 +231,33 @@ impl crate::RenderBackend for PanelPaintBackend {
}
}
#[test]
fn paint_model_chip_uses_key_glyph_for_builtin_model() {
let mut s = EditorState::new();
s.chat
.available_models
.push(op_editor_core::chat::ModelEntry::builtin_with_display_name(
op_editor_core::chat::AgentProvider::CodexCli,
"builtin-minimax",
"MiniMax",
"builtin:builtin-minimax:MiniMax-M2.7",
"MiniMax-M2.7",
));
let panel = AIChatPlaceholder::from_editor(&s);
let rect = Rect::xywh(0.0, 0.0, AI_CHAT_WIDTH, AI_CHAT_HEIGHT);
let mut backend = PanelPaintBackend::default();
let mut cx = PaintCx {
backend: &mut backend,
};
panel.paint(&mut cx, rect);
assert!(
backend.stroke_lines >= 2,
"built-in selected model chip should paint the TS-style Key glyph"
);
}
fn has_fill_rect(fills: &[(Rect, crate::Color)], expected: Rect) -> bool {
fills.iter().any(|(rect, _)| {
(rect.origin.x - expected.origin.x).abs() < 1e-4