Added inactive timer
This commit is contained in:
		
							parent
							
								
									46e3921585
								
							
						
					
					
						commit
						daf56c2de4
					
				| @ -22,14 +22,17 @@ def log_output(pipe): | |||||||
| 
 | 
 | ||||||
| class instance(): | class instance(): | ||||||
| 
 | 
 | ||||||
|     def __init__(self, local_port:int, remote_url:str, remote:bool, tweaks:dict, overrides:dict, bearer_token:str): |     def __init__(self, local_port:int, remote_url:str, remote:bool, tweaks:dict, overrides:dict, bearer_token:str, idle_timer_delay:int): | ||||||
|         self.local_port=local_port |         self.local_port=local_port | ||||||
|         self.remote_url=remote_url |         self.remote_url=remote_url | ||||||
|         self.remote=remote |         self.remote=remote | ||||||
|         self.tweaks=tweaks |         self.tweaks=tweaks | ||||||
|         self.overrides=overrides |         self.overrides=overrides | ||||||
|         self.bearer_token=bearer_token |         self.bearer_token=bearer_token | ||||||
|         self.instance = None |         self.idle_timer_delay=idle_timer_delay | ||||||
|  |         self.idle_timer_stop_event=threading.Event() | ||||||
|  |         self.idle_timer=None | ||||||
|  |         self.instance=None | ||||||
|         if not self.remote: |         if not self.remote: | ||||||
|             self.start() |             self.start() | ||||||
| 
 | 
 | ||||||
| @ -42,11 +45,17 @@ class instance(): | |||||||
|         return headers if len(headers.keys()) > 0 else None |         return headers if len(headers.keys()) > 0 else None | ||||||
| 
 | 
 | ||||||
|     def request(self, connection_type:str, connection_url:str, data:dict=None, callback:callable=None) -> requests.models.Response: |     def request(self, connection_type:str, connection_url:str, data:dict=None, callback:callable=None) -> requests.models.Response: | ||||||
|  |         if self.idle_timer: | ||||||
|  |             self.idle_timer_stop_event.set() | ||||||
|  |             self.idle_timer=None | ||||||
|  |         if not self.instance: | ||||||
|  |             self.start() | ||||||
|         connection_url = '{}/{}'.format(self.remote_url if self.remote else 'http://127.0.0.1:{}'.format(self.local_port), connection_url) |         connection_url = '{}/{}'.format(self.remote_url if self.remote else 'http://127.0.0.1:{}'.format(self.local_port), connection_url) | ||||||
|         logger.info('Connection: {} : {}'.format(connection_type, connection_url)) |         logger.info('Connection: {} : {}'.format(connection_type, connection_url)) | ||||||
|  |         response = None | ||||||
|         match connection_type: |         match connection_type: | ||||||
|             case "GET": |             case "GET": | ||||||
|                 return requests.get(connection_url, headers=self.get_headers(False)) |                 response = requests.get(connection_url, headers=self.get_headers(False)) | ||||||
|             case "POST": |             case "POST": | ||||||
|                 if callback: |                 if callback: | ||||||
|                     response = requests.post(connection_url, headers=self.get_headers(True), data=data, stream=True) |                     response = requests.post(connection_url, headers=self.get_headers(True), data=data, stream=True) | ||||||
| @ -54,29 +63,48 @@ class instance(): | |||||||
|                         for line in response.iter_lines(): |                         for line in response.iter_lines(): | ||||||
|                             if line: |                             if line: | ||||||
|                                 callback(json.loads(line.decode("utf-8"))) |                                 callback(json.loads(line.decode("utf-8"))) | ||||||
|                     return response |                     response = response | ||||||
|                 else: |                 else: | ||||||
|                     return requests.post(connection_url, headers=self.get_headers(True), data=data, stream=False) |                     response = requests.post(connection_url, headers=self.get_headers(True), data=data, stream=False) | ||||||
|             case "DELETE": |             case "DELETE": | ||||||
|                 return requests.delete(connection_url, headers=self.get_headers(False), json=data) |                 response = requests.delete(connection_url, headers=self.get_headers(False), json=data) | ||||||
|  |         if not self.idle_timer: | ||||||
|  |             self.start_timer() | ||||||
|  |         return response | ||||||
|  | 
 | ||||||
|  |     def run_timer(self): | ||||||
|  |         if not self.idle_timer_stop_event.wait(self.idle_timer_delay*60): | ||||||
|  |             self.stop() | ||||||
|  | 
 | ||||||
|  |     def start_timer(self): | ||||||
|  |         if self.idle_timer: | ||||||
|  |             self.idle_timer_stop_event.set() | ||||||
|  |             self.idle_timer=None | ||||||
|  |         if self.idle_timer_delay > 0: | ||||||
|  |             self.idle_timer_stop_event.clear() | ||||||
|  |             self.idle_timer = threading.Thread(target=self.run_timer) | ||||||
|  |             self.idle_timer.start() | ||||||
| 
 | 
 | ||||||
|     def start(self): |     def start(self): | ||||||
|         if not os.path.isdir(os.path.join(cache_dir, 'tmp/ollama')): |         if not os.path.isdir(os.path.join(cache_dir, 'tmp/ollama')): | ||||||
|             os.mkdir(os.path.join(cache_dir, 'tmp/ollama')) |             os.mkdir(os.path.join(cache_dir, 'tmp/ollama')) | ||||||
| 
 |         self.instance = None | ||||||
|         params = self.overrides.copy() |         params = self.overrides.copy() | ||||||
|         params["OLLAMA_DEBUG"] = "1" |         params["OLLAMA_DEBUG"] = "1" | ||||||
|         params["OLLAMA_HOST"] = f"127.0.0.1:{self.local_port}" # You can't change this directly sorry :3 |         params["OLLAMA_HOST"] = f"127.0.0.1:{self.local_port}" # You can't change this directly sorry :3 | ||||||
|         params["HOME"] = data_dir |         params["HOME"] = data_dir | ||||||
|         params["TMPDIR"] = os.path.join(cache_dir, 'tmp/ollama') |         params["TMPDIR"] = os.path.join(cache_dir, 'tmp/ollama') | ||||||
|         self.instance = subprocess.Popen(["ollama", "serve"], env={**os.environ, **params}, stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True) |         instance = subprocess.Popen(["ollama", "serve"], env={**os.environ, **params}, stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True) | ||||||
|         threading.Thread(target=log_output, args=(self.instance.stdout,)).start() |         threading.Thread(target=log_output, args=(instance.stdout,)).start() | ||||||
|         threading.Thread(target=log_output, args=(self.instance.stderr,)).start() |         threading.Thread(target=log_output, args=(instance.stderr,)).start() | ||||||
|         logger.info("Starting Alpaca's Ollama instance...") |         logger.info("Starting Alpaca's Ollama instance...") | ||||||
|         logger.debug(params) |         logger.debug(params) | ||||||
|         logger.info("Started Alpaca's Ollama instance") |         logger.info("Started Alpaca's Ollama instance") | ||||||
|         v_str = subprocess.check_output("ollama -v", shell=True).decode('utf-8') |         v_str = subprocess.check_output("ollama -v", shell=True).decode('utf-8') | ||||||
|         logger.info('Ollama version: {}'.format(v_str.split('client version is ')[1].strip())) |         logger.info('Ollama version: {}'.format(v_str.split('client version is ')[1].strip())) | ||||||
|  |         self.instance = instance | ||||||
|  |         if not self.idle_timer: | ||||||
|  |             self.start_timer() | ||||||
| 
 | 
 | ||||||
|     def stop(self): |     def stop(self): | ||||||
|         if self.instance: |         if self.instance: | ||||||
|  | |||||||
| @ -109,6 +109,7 @@ class AlpacaWindow(Adw.ApplicationWindow): | |||||||
|     ollama_instance = None |     ollama_instance = None | ||||||
|     model_manager = None |     model_manager = None | ||||||
|     add_chat_button = Gtk.Template.Child() |     add_chat_button = Gtk.Template.Child() | ||||||
|  |     instance_idle_timer = Gtk.Template.Child() | ||||||
| 
 | 
 | ||||||
|     background_switch = Gtk.Template.Child() |     background_switch = Gtk.Template.Child() | ||||||
|     remote_connection_switch = Gtk.Template.Child() |     remote_connection_switch = Gtk.Template.Child() | ||||||
| @ -275,6 +276,11 @@ class AlpacaWindow(Adw.ApplicationWindow): | |||||||
|             self.ollama_instance.tweaks[spin.get_name()] = value |             self.ollama_instance.tweaks[spin.get_name()] = value | ||||||
|             self.save_server_config() |             self.save_server_config() | ||||||
| 
 | 
 | ||||||
|  |     @Gtk.Template.Callback() | ||||||
|  |     def instance_idle_timer_changed(self, spin): | ||||||
|  |         self.ollama_instance.idle_timer_delay = round(spin.get_value()) | ||||||
|  |         self.save_server_config() | ||||||
|  | 
 | ||||||
|     @Gtk.Template.Callback() |     @Gtk.Template.Callback() | ||||||
|     def create_model_start(self, button): |     def create_model_start(self, button): | ||||||
|         name = self.create_model_name.get_text().lower().replace(":", "") |         name = self.create_model_name.get_text().lower().replace(":", "") | ||||||
| @ -488,7 +494,8 @@ Generate a title following these rules: | |||||||
|                 'local_port': self.ollama_instance.local_port, |                 'local_port': self.ollama_instance.local_port, | ||||||
|                 'run_on_background': self.background_switch.get_active(), |                 'run_on_background': self.background_switch.get_active(), | ||||||
|                 'model_tweaks': self.ollama_instance.tweaks, |                 'model_tweaks': self.ollama_instance.tweaks, | ||||||
|                 'ollama_overrides': self.ollama_instance.overrides |                 'ollama_overrides': self.ollama_instance.overrides, | ||||||
|  |                 'idle_timer': self.ollama_instance.idle_timer_delay | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             json.dump(data, f, indent=6) |             json.dump(data, f, indent=6) | ||||||
| @ -769,7 +776,7 @@ Generate a title following these rules: | |||||||
|             elif extension == 'pdf': |             elif extension == 'pdf': | ||||||
|                 self.attach_file(file.get_path(), 'pdf') |                 self.attach_file(file.get_path(), 'pdf') | ||||||
| 
 | 
 | ||||||
|     def prepare_alpaca(self, local_port:int, remote_url:str, remote:bool, tweaks:dict, overrides:dict, bearer_token:str, save:bool, show_launch_dialog:bool): |     def prepare_alpaca(self, local_port:int, remote_url:str, remote:bool, tweaks:dict, overrides:dict, bearer_token:str, idle_timer_delay:int, save:bool, show_launch_dialog:bool): | ||||||
|         #Show launch dialog |         #Show launch dialog | ||||||
|         if show_launch_dialog: |         if show_launch_dialog: | ||||||
|             self.launch_dialog.present(self) |             self.launch_dialog.present(self) | ||||||
| @ -777,7 +784,7 @@ Generate a title following these rules: | |||||||
|         #Instance |         #Instance | ||||||
|         self.launch_level_bar.set_value(0) |         self.launch_level_bar.set_value(0) | ||||||
|         self.launch_status.set_description(_('Loading instance')) |         self.launch_status.set_description(_('Loading instance')) | ||||||
|         self.ollama_instance = connection_handler.instance(local_port, remote_url, remote, tweaks, overrides, bearer_token) |         self.ollama_instance = connection_handler.instance(local_port, remote_url, remote, tweaks, overrides, bearer_token, idle_timer_delay) | ||||||
| 
 | 
 | ||||||
|         #User Preferences |         #User Preferences | ||||||
|         self.launch_level_bar.set_value(1) |         self.launch_level_bar.set_value(1) | ||||||
| @ -795,6 +802,7 @@ Generate a title following these rules: | |||||||
|         self.remote_connection_switch.set_sensitive(self.remote_connection_entry.get_text()) |         self.remote_connection_switch.set_sensitive(self.remote_connection_entry.get_text()) | ||||||
|         self.remote_bearer_token_entry.set_text(self.ollama_instance.bearer_token) |         self.remote_bearer_token_entry.set_text(self.ollama_instance.bearer_token) | ||||||
|         self.remote_connection_switch.set_active(self.ollama_instance.remote) |         self.remote_connection_switch.set_active(self.ollama_instance.remote) | ||||||
|  |         self.instance_idle_timer.set_value(self.ollama_instance.idle_timer_delay) | ||||||
| 
 | 
 | ||||||
|         #Model Manager |         #Model Manager | ||||||
|         self.model_manager = model_widget.model_manager_container() |         self.model_manager = model_widget.model_manager_container() | ||||||
| @ -877,10 +885,12 @@ Generate a title following these rules: | |||||||
|                 with open(os.path.join(config_dir, "server.json"), "r", encoding="utf-8") as f: |                 with open(os.path.join(config_dir, "server.json"), "r", encoding="utf-8") as f: | ||||||
|                     data = json.load(f) |                     data = json.load(f) | ||||||
|                     self.background_switch.set_active(data['run_on_background']) |                     self.background_switch.set_active(data['run_on_background']) | ||||||
|                     threading.Thread(target=self.prepare_alpaca, args=(data['local_port'], data['remote_url'], data['run_remote'], data['model_tweaks'], data['ollama_overrides'], data['remote_bearer_token'], False, not data['run_remote'])).start() |                     if 'idle_timer' not in data: | ||||||
|  |                         data['idle_timer'] = 0 | ||||||
|  |                     threading.Thread(target=self.prepare_alpaca, args=(data['local_port'], data['remote_url'], data['run_remote'], data['model_tweaks'], data['ollama_overrides'], data['remote_bearer_token'], round(data['idle_timer']), False, not data['run_remote'])).start() | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 logger.error(e) |                 logger.error(e) | ||||||
|                 threading.Thread(target=self.prepare_alpaca, args=(11435, '', False, {'temperature': 0.7, 'seed': 0, 'keep_alive': 5}, {}, '', True, True)).start() |                 threading.Thread(target=self.prepare_alpaca, args=(11435, '', False, {'temperature': 0.7, 'seed': 0, 'keep_alive': 5}, {}, '', 0, True, True)).start() | ||||||
|         else: |         else: | ||||||
|             threading.Thread(target=self.prepare_alpaca, args=(11435, '', False, {'temperature': 0.7, 'seed': 0, 'keep_alive': 5}, {}, '', True, False)).start() |             threading.Thread(target=self.prepare_alpaca, args=(11435, '', False, {'temperature': 0.7, 'seed': 0, 'keep_alive': 5}, {}, '', 0, True, False)).start() | ||||||
|             self.welcome_dialog.present(self) |             self.welcome_dialog.present(self) | ||||||
|  | |||||||
| @ -390,6 +390,26 @@ | |||||||
|               </child> |               </child> | ||||||
|             </object> |             </object> | ||||||
|           </child> |           </child> | ||||||
|  |           <child> | ||||||
|  |             <object class="AdwPreferencesGroup"> | ||||||
|  |               <child> | ||||||
|  |                 <object class="AdwSpinRow" id="instance_idle_timer"> | ||||||
|  |                   <signal name="changed" handler="instance_idle_timer_changed"/> | ||||||
|  |                   <property name="name">timer</property> | ||||||
|  |                   <property name="title" translatable="yes">Idle Timer</property> | ||||||
|  |                   <property name="subtitle" translatable="yes">Number of minutes the instance should remain idle before it is shut down (0 means it won't be shut down)</property> | ||||||
|  |                   <property name="digits">0</property> | ||||||
|  |                   <property name="adjustment"> | ||||||
|  |                     <object class="GtkAdjustment"> | ||||||
|  |                       <property name="lower">0</property> | ||||||
|  |                       <property name="upper">60</property> | ||||||
|  |                       <property name="step-increment">5</property> | ||||||
|  |                     </object> | ||||||
|  |                   </property> | ||||||
|  |                 </object> | ||||||
|  |               </child> | ||||||
|  |             </object> | ||||||
|  |           </child> | ||||||
|         </object> |         </object> | ||||||
|       </child> |       </child> | ||||||
|     </object> |     </object> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user