You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by wy...@apache.org on 2026/10/23 03:23:02 UTC
(maka) 05/07: fix(terminal): fit model trigger and preserve effort caption
This is an automated email from the ASF dual-hosted git repository.
M4n5ter pushed a commit to branch rust-preview
in repository https://gitbox.apache.org/repos/asf/maka.git
commit be9318c083536520af0d5e60da05853f6cd707b6
Author: M4n5ter <m4...@gmail.com>
AuthorDate: Fri Oct 23 10:54:22 2026 +0800
fix(terminal): fit model trigger and preserve effort caption
---
products/maka/terminal-shell/app/ModelSelect.tsx | 41 +++++++++++------
products/maka/terminal-shell/tests/real_host.rs | 58 ++++++++++++++++++++++--
2 files changed, 81 insertions(+), 18 deletions(-)
diff --git a/products/maka/terminal-shell/app/ModelSelect.tsx b/products/maka/terminal-shell/app/ModelSelect.tsx
index bd09b86f6f..4dc68d8506 100644
--- a/products/maka/terminal-shell/app/ModelSelect.tsx
+++ b/products/maka/terminal-shell/app/ModelSelect.tsx
@@ -95,13 +95,9 @@ export function ModelSelect(props: {
}
};
});
- const label = () => {
- const backend = owner.backend();
- if (!backend) return tr('Choose a model');
- const model = modelCaption(backend, owner.modelDetails());
- const effort = effortCaption(backend, owner.modelDetails());
- return effort ? `${model} · ${effort}` : model;
- };
+ const model = () => modelCaption(owner.backend(), owner.modelDetails());
+ const effort = () => effortCaption(owner.backend(), owner.modelDetails());
+ const label = () => (effort() ? `${model()} · ${effort()}` : model());
return (
<Popover
open={props.instance() !== null}
@@ -110,7 +106,7 @@ export function ModelSelect(props: {
align="end"
offset={8}
margin={8}
- style={{ minWidth: 0 }}
+ style={{ minWidth: 0, alignItems: 'flex-end' }}
popupStyle={{
width: 420,
maxWidth: Math.max(0, windowSize().width - 16),
@@ -125,13 +121,14 @@ export function ModelSelect(props: {
trigger={
<Button
accessibilityLabel={tr('Choose model and effort')}
- tooltip={tr('Choose model and effort · Ctrl+G')}
+ tooltip={`${label()} · ${tr('Choose model and effort · Ctrl+G')}`}
onPress={inputAction(props.toggle, {
sessionId: owner.sessionId,
instance: props.instance(),
})}
style={{
...controlStyle,
+ maxWidth: '100%',
minWidth: 0,
flexDirection: 'row',
justifyContent: 'flex-end',
@@ -142,17 +139,31 @@ export function ModelSelect(props: {
focusStyle={{ backgroundColor: C.line }}
activeStyle={{ backgroundColor: C.surface }}
>
- <Text
- numberOfLines={1}
+ <View
style={{
- color: owner.backend() ? C.secondary : C.warning,
- fontSize: 13,
+ flexDirection: 'row',
+ alignItems: 'center',
minWidth: 0,
flexShrink: 1,
}}
>
- {label()}
- </Text>
+ <Text
+ numberOfLines={1}
+ style={{
+ color: owner.backend() ? C.secondary : C.warning,
+ fontSize: 13,
+ minWidth: 0,
+ flexShrink: 1,
+ }}
+ >
+ {model()}
+ </Text>
+ <If when={effort()}>
+ <Text numberOfLines={1} style={{ color: C.secondary, fontSize: 13, flexShrink: 0 }}>
+ {` · ${effort()}`}
+ </Text>
+ </If>
+ </View>
<Icon name="down" color={C.secondary} />
</Button>
}
diff --git a/products/maka/terminal-shell/tests/real_host.rs b/products/maka/terminal-shell/tests/real_host.rs
index 2049b097ed..66ae50f49f 100644
--- a/products/maka/terminal-shell/tests/real_host.rs
+++ b/products/maka/terminal-shell/tests/real_host.rs
@@ -145,6 +145,26 @@ fn model_menu_closed(view: &AppView) -> bool {
&& model_menu_button(view, "Back to model settings").is_none()
}
+fn model_trigger_caption(view: &AppView, model: &str, effort: &str) -> bool {
+ let Some(trigger) = model_menu_button(view, "Choose model and effort") else {
+ return false;
+ };
+ let nodes = view.accessibility_snapshot();
+ [model, &format!(" · {effort}")].iter().all(|label| {
+ nodes.iter().any(|node| {
+ node.label == *label
+ && node.frame.size.width.0 > 0.0
+ && node.frame.size.height.0 > 0.0
+ && node.frame.origin.x.0 >= trigger.frame.origin.x.0
+ && node.frame.origin.y.0 >= trigger.frame.origin.y.0
+ && node.frame.origin.x.0 + node.frame.size.width.0
+ <= trigger.frame.origin.x.0 + trigger.frame.size.width.0
+ && node.frame.origin.y.0 + node.frame.size.height.0
+ <= trigger.frame.origin.y.0 + trigger.frame.size.height.0
+ })
+ })
+}
+
fn assert_effort_choices(view: &AppView, choice: &Value, selected: Option<&str>) {
let nodes = view.accessibility_snapshot();
let mut advertised = choice["thinkingLevels"]
@@ -972,6 +992,36 @@ async fn the_home_palette_creates_switches_models_and_stops_a_real_session_witho
view.handle_event(Event::Paste("Message B uses the selected model".into()));
support::wait_draft(&client, &created_id, "Message B uses the selected model").await;
+ // The remaining footer space belongs to the layout, not the model
+ // trigger. Its actual native frame hugs the caption in both layouts.
+ let viewport = view.surface().viewport();
+ for (columns, rows) in [(160, 40), (80, 24)] {
+ view.resize(columns, rows);
+ wait_view_state(&mut view, |view, _| model_trigger_caption(view, "fixture-model-alt", "high") && model_menu_closed(view)).await;
+ let model = model_menu_button(&view, "Choose model and effort").unwrap().frame;
+ let sandbox = support::wait_enabled_button(&mut view, "Sandbox and approvals").await.frame;
+ let left = sandbox.origin.x.0 + sandbox.size.width.0;
+ let column = ((left + model.origin.x.0) / 16.0).floor() as u16;
+ let row = ((model.origin.y.0 + model.size.height.0 / 2.0) / 16.0).floor() as u16;
+ let center = f32::from(column) * 8.0 + 4.0;
+ assert!(center > left && center < model.origin.x.0, "the model trigger consumed the footer's blank space at {columns} columns");
+ for kind in [MouseEventKind::Down(MouseButton::Left), MouseEventKind::Up(MouseButton::Left)] {
+ view.handle_event(Event::Mouse(MouseEvent { kind, column, row, modifiers: KeyModifiers::NONE }));
+ }
+ let (done, committed) = tokio::sync::oneshot::channel();
+ view.control().unwrap().advance_clock(Duration::ZERO, move || { let _ = done.send(()); });
+ tokio::time::timeout(Duration::from_secs(20), committed).await.unwrap().unwrap();
+ support::tick(&mut view);
+ assert!(model_menu_closed(&view), "blank footer space opened the model chooser at {columns} columns");
+ support::click_button(&mut view, "Choose model and effort").await;
+ wait_view_state(&mut view, |view, _| model_menu_ready(view, "Close model selection")).await;
+ view.handle_event(Event::Key(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)));
+ wait_view_state(&mut view, |view, _| model_menu_closed(view)).await;
+ }
+ view.resize((viewport.width.0 / 8.0) as u16, (viewport.height.0 / 16.0) as u16);
+ tab_to_label(&mut view, "Message composer").await;
+ wait_editable_composer(&mut view).await;
+
let created_editor = view.surface().focused().unwrap();
view.handle_event(Event::Key(KeyEvent::new(KeyCode::Left, KeyModifiers::NONE)));
let caret = view.surface().input_context().unwrap().selection;
@@ -1084,7 +1134,9 @@ async fn the_home_palette_creates_switches_models_and_stops_a_real_session_witho
wait_focused_input(&mut view, "Search models").await;
wait_view(&mut view, |screen| screen.contains("fixture-model-unknown") && !screen.contains("Loading…")).await;
support::click_label(&mut view, "Use fixture-model-unknown · NSH fixture");
- wait_view_state(&mut view, |view, screen| screen.contains("fixture-model-unknown · Provider controlled") && model_menu_closed(view)).await;
+ wait_view_state(&mut view, |view, screen| screen.contains("Provider controlled") && model_trigger_caption(view, "fixture-model-unknown", "Provider controlled") && model_menu_closed(view)).await;
+ let observed = client.query("agent", "observe", json!({"sessionId":created_id})).await.unwrap();
+ assert_eq!(observed["session"]["backend"], json!({"kind":"model","connectionId":fixture.selection["connectionId"],"modelId":"fixture-model-unknown","thinkingLevel":null}), "choosing the route must preserve its inherited provider-controlled policy");
support::click_button(&mut view, "Choose model and effort").await;
support::click_button(&mut view, "Choose reasoning effort").await;
wait_view_state(&mut view, |view, _| model_menu_ready(view, "Use effort high") && model_menu_ready(view, "Back to model settings")).await;
@@ -1099,9 +1151,9 @@ async fn the_home_palette_creates_switches_models_and_stops_a_real_session_witho
wait_view_state(&mut view, |view, _| model_menu_ready(view, "Use provider settings") && model_menu_ready(view, "Back to model settings")).await;
assert_effort_choices(&view, unknown_default, Some("high"));
support::click_button(&mut view, "Use provider settings").await;
- wait_view_state(&mut view, |view, screen| screen.contains("fixture-model-unknown · Provider controlled") && model_menu_closed(view)).await;
+ wait_view_state(&mut view, |view, screen| screen.contains("Provider controlled") && model_trigger_caption(view, "fixture-model-unknown", "Provider controlled") && model_menu_closed(view)).await;
let observed = client.query("agent", "observe", json!({"sessionId":created_id})).await.unwrap();
- assert!(observed["session"]["backend"]["thinkingLevel"].is_null(), "resetting provider control must clear the saved override");
+ assert_eq!(observed["session"]["backend"], json!({"kind":"model","connectionId":fixture.selection["connectionId"],"modelId":"fixture-model-unknown","thinkingLevel":null}), "resetting provider control must clear the saved override while preserving its route");
assert_eq!(fixture.request_count.load(Ordering::SeqCst), 0);
support::click_button(&mut view, "Choose model and effort").await;
support::click_button(&mut view, "Choose model").await;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org