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