1818from settings import jump_to_previous_llm # Import the new function
1919
2020# Version
21- __version__ = "1.0.3 "
21+ __version__ = "1.0.4 "
2222
2323class CustomHelpFormatter (argparse .RawTextHelpFormatter ):
2424 """Custom formatter for argparse help messages to adjust spacing."""
@@ -130,6 +130,68 @@ def set_gemini_api_key_interactive(config_dir, config_file):
130130 setup_config (config_dir , config_file , jump_to = "gemini_keys" , is_direct_flag_call = True )
131131 sys .exit (0 )
132132
133+ def start_interactive_session (config_data , config_dir , config_file ):
134+ """Starts an interactive chat session with the configured LLM."""
135+ display_message ("\n --- DeepShell Interactive Mode ---" , "green" )
136+ display_message ("Type 'exit' or 'quit' to end the session." , "yellow" )
137+
138+ # Load service details from config
139+ active_service_name = config_data .get ("active_llm_service" )
140+ service_config = config_data ["llm_services" ][active_service_name ]
141+ model_name = service_config .get ("model" )
142+ active_service_name_display = active_service_name .capitalize ()
143+
144+ # Prepare service-specific details
145+ api_key_value , api_key_nickname = (None , None )
146+ server_address = None
147+ if active_service_name == LLM_SERVICE_GEMINI :
148+ api_key_value , api_key_nickname = _get_active_gemini_key_value (service_config )
149+ if not api_key_value :
150+ display_message ("No active Gemini API key found. Please configure it via --setup." , "red" )
151+ sys .exit (1 )
152+ elif active_service_name == LLM_SERVICE_OLLAMA :
153+ server_address = service_config .get ("server_address" )
154+ if not server_address :
155+ display_message ("Ollama server address not configured. Please configure it via --setup." , "red" )
156+ sys .exit (1 )
157+
158+ conversation_history = []
159+ MAX_HISTORY_TURNS = 10 # 10 pairs of user/model messages
160+ MAX_HISTORY_ITEMS = MAX_HISTORY_TURNS * 2
161+
162+ while True :
163+ try :
164+ user_input = input ("> " )
165+ if user_input .lower () in ['exit' , 'quit' ]:
166+ display_message ("Exiting interactive mode." , "blue" )
167+ break
168+ if not user_input .strip ():
169+ continue
170+
171+ # Trim history if it's too long. Keep the last 9 pairs and make room for the new one.
172+ if len (conversation_history ) >= MAX_HISTORY_ITEMS :
173+ conversation_history = conversation_history [2 :]
174+
175+ response_text = None
176+ if active_service_name == LLM_SERVICE_GEMINI :
177+ response_text = send_gemini_query (
178+ api_key_value , model_name , user_input , conversation_history ,
179+ active_service_name_display , api_key_nickname , service_config
180+ )
181+ elif active_service_name == LLM_SERVICE_OLLAMA :
182+ response_text = send_ollama_query (
183+ server_address , model_name , user_input , conversation_history ,
184+ active_service_name_display , service_config
185+ )
186+
187+ if response_text :
188+ # Add to history using a canonical format
189+ conversation_history .append ({"role" : "user" , "content" : user_input })
190+ conversation_history .append ({"role" : "model" , "content" : response_text })
191+
192+ except EOFError : # Handle Ctrl+D
193+ display_message ("\n Exiting interactive mode." , "blue" )
194+ break
133195
134196def main ():
135197 """
@@ -151,13 +213,21 @@ def main():
151213 dest = "model_change" ,
152214 help = "Change the default model for the active LLM service."
153215 )
154- parser .add_argument (
216+
217+ # Group for mutually exclusive query/interactive modes
218+ mode_group = parser .add_mutually_exclusive_group ()
219+ mode_group .add_argument (
155220 "-q" , "--query" ,
156221 nargs = '+' ,
157222 metavar = "QUERY" ,
158223 help = "The query to send to the LLM. All text following this flag will be treated as the query.\n "
159224 "Example: deepshell -q What is the capital of France?"
160225 )
226+ mode_group .add_argument (
227+ "-i" , "--interactive" ,
228+ action = "store_true" ,
229+ help = "Start an interactive chat session."
230+ )
161231 parser .add_argument (
162232 "-d" , "--delete-config" ,
163233 action = "store_true" ,
@@ -249,6 +319,18 @@ def main():
249319 jump_to_previous_llm (config_dir , config_file )
250320 sys .exit (0 )
251321
322+ if args .interactive :
323+ config_data = load_config (config_file )
324+ if config_data is None or not config_data .get ("active_llm_service" ):
325+ display_message ("Configuration not found or no active LLM service. Running setup..." , "yellow" )
326+ config_data = setup_config (config_dir , config_file , is_direct_flag_call = False )
327+ if not config_data or not config_data .get ("active_llm_service" ):
328+ display_message ("Setup incomplete. Exiting." , "red" )
329+ sys .exit (1 )
330+
331+ start_interactive_session (config_data , config_dir , config_file )
332+ sys .exit (0 )
333+
252334 config_data = load_config (config_file )
253335 user_query_list = args .query
254336 user_query = " " .join (user_query_list ) if user_query_list else None
@@ -290,14 +372,14 @@ def main():
290372 if not server_address :
291373 display_message ("Ollama server address not configured. Please run --setup or --llm to configure Ollama." , "red" )
292374 sys .exit (1 )
293- send_ollama_query (server_address , model_name , user_query , active_service_name_display , service_config )
375+ send_ollama_query (server_address , model_name , user_query , [], active_service_name_display , service_config )
294376 elif active_service_name == LLM_SERVICE_GEMINI :
295377 active_api_key_value , active_nickname = _get_active_gemini_key_value (service_config )
296378 if not active_api_key_value :
297379 display_message ("No active Gemini API key configured or found. Please run --setup or --llm to configure Gemini." , "red" )
298380 sys .exit (1 )
299381 send_gemini_query (
300- active_api_key_value , model_name , user_query ,
382+ active_api_key_value , model_name , user_query , [],
301383 active_service_name_display ,
302384 active_nickname ,
303385 service_config
0 commit comments