77from agent_chat_cli .components .caret import Caret
88from agent_chat_cli .components .flex import Flex
99from agent_chat_cli .components .slash_command_menu import SlashCommandMenu
10+ from agent_chat_cli .components .model_selection_menu import ModelSelectionMenu
1011from agent_chat_cli .core .actions import Actions
1112from agent_chat_cli .utils .enums import Key
1213
@@ -35,6 +36,7 @@ def compose(self) -> ComposeResult:
3536 yield SlashCommandMenu (
3637 actions = self .actions , on_filter_change = self ._on_filter_change
3738 )
39+ yield ModelSelectionMenu (actions = self .actions )
3840
3941 def _on_filter_change (self , char : str ) -> None :
4042 text_area = self .query_one (TextArea )
@@ -51,13 +53,15 @@ def on_descendant_blur(self, event: DescendantBlur) -> None:
5153 if not self .display :
5254 return
5355
54- menu = self .query_one ( SlashCommandMenu )
56+ menu = self ._get_visible_menu ( )
5557
56- if isinstance (event .widget , TextArea ) and not menu . is_visible :
58+ if isinstance (event .widget , TextArea ) and not menu :
5759 event .widget .focus (scroll_visible = False )
58- elif isinstance (event .widget , OptionList ) and menu .is_visible :
59- menu .hide ()
60- self .query_one (TextArea ).focus (scroll_visible = False )
60+ elif isinstance (event .widget , OptionList ) and menu :
61+ menu_option_list = menu .query_one (OptionList )
62+ if event .widget == menu_option_list :
63+ menu .hide ()
64+ self .query_one (TextArea ).focus (scroll_visible = False )
6165
6266 def on_text_area_changed (self , event : TextArea .Changed ) -> None :
6367 menu = self .query_one (SlashCommandMenu )
@@ -68,10 +72,10 @@ def on_text_area_changed(self, event: TextArea.Changed) -> None:
6872 menu .show ()
6973
7074 async def on_key (self , event ) -> None :
71- menu = self .query_one ( SlashCommandMenu )
75+ menu = self ._get_visible_menu ( )
7276
73- if menu . is_visible :
74- self ._close_menu (event )
77+ if menu :
78+ self ._close_menu (event , menu )
7579 return
7680
7781 if event .key == "up" :
@@ -92,9 +96,7 @@ def _insert_newline(self, event) -> None:
9296 input_widget = self .query_one (TextArea )
9397 input_widget .insert ("\n " )
9498
95- def _close_menu (self , event ) -> None :
96- menu = self .query_one (SlashCommandMenu )
97-
99+ def _close_menu (self , event , menu : SlashCommandMenu | ModelSelectionMenu ) -> None :
98100 if event .key == Key .ESCAPE .value :
99101 event .stop ()
100102 event .prevent_default ()
@@ -104,7 +106,10 @@ def _close_menu(self, event) -> None:
104106 input_widget .focus ()
105107 return
106108
107- if event .key in (Key .BACKSPACE .value , Key .DELETE .value ):
109+ if isinstance (menu , SlashCommandMenu ) and event .key in (
110+ Key .BACKSPACE .value ,
111+ Key .DELETE .value ,
112+ ):
108113 if menu .filter_text :
109114 menu .filter_text = menu .filter_text [:- 1 ]
110115 menu ._refresh_options ()
@@ -147,10 +152,21 @@ async def _navigate_history(self, event, direction: int) -> None:
147152 input_widget .text = self .message_history [self .history_index ]
148153 input_widget .move_cursor_relative (rows = 999 , columns = 999 )
149154
155+ def _get_visible_menu (self ) -> SlashCommandMenu | ModelSelectionMenu | None :
156+ slash_menu = self .query_one (SlashCommandMenu )
157+ if slash_menu .is_visible :
158+ return slash_menu
159+
160+ model_menu = self .query_one (ModelSelectionMenu )
161+ if model_menu .is_visible :
162+ return model_menu
163+
164+ return None
165+
150166 async def action_submit (self ) -> None :
151- menu = self .query_one ( SlashCommandMenu )
167+ menu = self ._get_visible_menu ( )
152168
153- if menu . is_visible :
169+ if menu :
154170 option_list = menu .query_one (OptionList )
155171 option_list .action_select ()
156172 input_widget = self .query_one (TextArea )
0 commit comments