mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2025-09-10 09:04:36 +00:00
Zentk integration (Zenity/yad support) (#1475)
* Zentk integration (Zenity/yad support) * Escape incompatible dependencies in zentk * Properly clean env
This commit is contained in:
parent
e2fefc373f
commit
8fd70f37bd
1 changed files with 118 additions and 15 deletions
133
koboldcpp.py
133
koboldcpp.py
|
@ -29,6 +29,7 @@ import html
|
|||
import urllib.parse as urlparse
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import datetime, timezone
|
||||
from typing import Tuple
|
||||
|
||||
# constants
|
||||
sampler_order_max = 7
|
||||
|
@ -615,9 +616,8 @@ def unpack_to_dir(destpath = ""):
|
|||
print("Attempt to unpack KoboldCpp into directory...")
|
||||
|
||||
if not cliunpack:
|
||||
from tkinter.filedialog import askdirectory
|
||||
from tkinter import messagebox
|
||||
destpath = askdirectory(title='Select an empty folder to unpack KoboldCpp')
|
||||
destpath = zentk_askdirectory(title='Select an empty folder to unpack KoboldCpp')
|
||||
if not destpath:
|
||||
return
|
||||
|
||||
|
@ -3455,19 +3455,123 @@ def RunServerMultiThreaded(addr, port, server_handler):
|
|||
threadArr[i].stop()
|
||||
sys.exit(0)
|
||||
|
||||
# Based on https://github.com/mathgeniuszach/xdialog/blob/main/xdialog/zenity_dialogs.py - MIT license | - Expanded version by Henk717
|
||||
|
||||
def zenity_clean(txt: str):
|
||||
return txt\
|
||||
.replace("\\", "\\\\")\
|
||||
.replace("$", "\\$")\
|
||||
.replace("!", "\\!")\
|
||||
.replace("*", "\\*")\
|
||||
.replace("?", "\\?")\
|
||||
.replace("&", "&")\
|
||||
.replace("|", "|")\
|
||||
.replace("<", "<")\
|
||||
.replace(">", ">")\
|
||||
.replace("(", "\\(")\
|
||||
.replace(")", "\\)")\
|
||||
.replace("[", "\\[")\
|
||||
.replace("]", "\\]")\
|
||||
.replace("{", "\\{")\
|
||||
.replace("}", "\\}")\
|
||||
|
||||
def zenity(typ, filetypes=None, initialdir="", initialfile="", **kwargs) -> Tuple[int, str]:
|
||||
import shutil, subprocess, os, platform
|
||||
if not platform.system() == "Linux":
|
||||
raise Exception("This feature should only be used on Linux, if you see this error there is no TK fallback implemented in the code.")
|
||||
zenity_bin = shutil.which("zenity")
|
||||
if not zenity_bin:
|
||||
zenity_bin = shutil.which("yad")
|
||||
if not zenity_bin:
|
||||
raise Exception("Zenity not present")
|
||||
|
||||
# Build args based on keywords
|
||||
args = ['/usr/bin/env', zenity_bin, '--'+typ]
|
||||
for k, v in kwargs.items():
|
||||
if v is True:
|
||||
args.append(f'--{k.replace("_", "-").strip("-")}')
|
||||
elif isinstance(v, str):
|
||||
cv = zenity_clean(v) if k != "title" else v
|
||||
args.append(f'--{k.replace("_", "-").strip("-")}={cv}')
|
||||
|
||||
# Build filetypes specially if specified
|
||||
if filetypes:
|
||||
for name, globs in filetypes:
|
||||
if name:
|
||||
globlist = globs.split()
|
||||
args.append(f'--file-filter={name.replace("|", "")} ({", ".join(t for t in globlist)})|{globs}')
|
||||
|
||||
# Default filename and folder
|
||||
if initialdir is None:
|
||||
initialdir=os.getcwd()
|
||||
if initialfile is None:
|
||||
initialfile=""
|
||||
initialpath = os.path.join(initialdir, initialfile)
|
||||
args.append(f'--filename={initialpath}')
|
||||
|
||||
clean_env = os.environ.copy()
|
||||
clean_env.pop("LD_LIBRARY_PATH", None)
|
||||
clean_env["PATH"] = "/usr/bin:/bin"
|
||||
|
||||
proc = subprocess.Popen(
|
||||
args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
shell=False,
|
||||
env=clean_env
|
||||
)
|
||||
stdout, _ = proc.communicate()
|
||||
|
||||
return (proc.returncode, stdout.decode('utf-8').strip())
|
||||
|
||||
# note: In this section we wrap around file dialogues to allow for zenity
|
||||
|
||||
def zentk_askopenfilename(**options):
|
||||
try:
|
||||
result = zenity('file-selection', filetypes=options.get("filetypes"), initialdir=options.get("initialdir"), title=options.get("title"))[1]
|
||||
except:
|
||||
from tkinter.filedialog import askopenfilename
|
||||
result = askopenfilename(**options)
|
||||
return result
|
||||
|
||||
def zentk_askopenmultiplefilenames(**options):
|
||||
try:
|
||||
from os.path import isfile
|
||||
files = zenity('file-selection', filetypes=options.get("filetypes"), initialdir=options.get("initialdir"), title=options.get("title"), multiple=True, separator="\n")[1].splitlines()
|
||||
result = tuple(filter(isfile, files))
|
||||
except:
|
||||
from tkinter.filedialog import askopenfilenames
|
||||
result = askopenfilenames(**options)
|
||||
return result
|
||||
|
||||
def zentk_askdirectory(**options):
|
||||
try:
|
||||
result = zenity('file-selection', initialdir=options.get("initialdir"), title=options.get("title"), directory=True)[1]
|
||||
except:
|
||||
from tkinter.filedialog import askdirectory
|
||||
result = askdirectory(**options)
|
||||
return result
|
||||
|
||||
def zentk_asksaveasfilename(**options):
|
||||
try:
|
||||
result = zenity('file-selection', filetypes=options.get("filetypes"), initialdir=options.get("initialdir"), initialfile=options.get("initialfile"), title=options.get("title"), save=True)[1]
|
||||
except:
|
||||
from tkinter.filedialog import asksaveasfilename
|
||||
result = asksaveasfilename(**options)
|
||||
return result
|
||||
### End of MIT license
|
||||
|
||||
# note: customtkinter-5.2.0
|
||||
def show_gui():
|
||||
global using_gui_launcher
|
||||
using_gui_launcher = True
|
||||
from tkinter.filedialog import askopenfilename, askdirectory
|
||||
from tkinter.filedialog import asksaveasfilename
|
||||
|
||||
# if args received, launch
|
||||
if len(sys.argv) != 1 and not args.showgui:
|
||||
import tkinter as tk
|
||||
root = tk.Tk() #we dont want the useless window to be visible, but we want it in taskbar
|
||||
root.attributes("-alpha", 0)
|
||||
args.model_param = askopenfilename(title="Select ggml model .bin or .gguf file or .kcpps config")
|
||||
args.model_param = zentk_askopenfilename(title="Select ggml model .bin or .gguf file or .kcpps config")
|
||||
root.withdraw()
|
||||
root.quit()
|
||||
if args.model_param and args.model_param!="" and (args.model_param.lower().endswith('.kcpps') or args.model_param.lower().endswith('.kcppt') or args.model_param.lower().endswith('.kcpps?download=true') or args.model_param.lower().endswith('.kcppt?download=true')):
|
||||
|
@ -3770,16 +3874,16 @@ def show_gui():
|
|||
initialDir = initialDir if os.path.isdir(initialDir) else None
|
||||
fnam = None
|
||||
if dialog_type==2:
|
||||
fnam = askdirectory(title=text, mustexist=True, initialdir=initialDir)
|
||||
fnam = zentk_askdirectory(title=text, mustexist=True, initialdir=initialDir)
|
||||
elif dialog_type==1:
|
||||
fnam = asksaveasfilename(title=text, filetypes=filetypes, defaultextension=filetypes, initialdir=initialDir)
|
||||
fnam = zentk_asksaveasfilename(title=text, filetypes=filetypes, defaultextension=filetypes, initialdir=initialDir)
|
||||
if not fnam:
|
||||
fnam = ""
|
||||
else:
|
||||
fnam = str(fnam).strip()
|
||||
fnam = f"{fnam}.jsondb" if ".jsondb" not in fnam.lower() else fnam
|
||||
else:
|
||||
fnam = askopenfilename(title=text,filetypes=filetypes, initialdir=initialDir)
|
||||
fnam = zentk_askopenfilename(title=text,filetypes=filetypes, initialdir=initialDir)
|
||||
if fnam:
|
||||
var.set(fnam)
|
||||
if onchoosefile:
|
||||
|
@ -4181,7 +4285,7 @@ def show_gui():
|
|||
def pickpremadetemplate():
|
||||
initialDir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'kcpp_adapters')
|
||||
initialDir = initialDir if os.path.isdir(initialDir) else None
|
||||
fnam = askopenfilename(title="Pick Premade ChatCompletions Adapter",filetypes=[("JSON Adapter", "*.json")], initialdir=initialDir)
|
||||
fnam = zentk_askopenfilename(title="Pick Premade ChatCompletions Adapter",filetypes=[("JSON Adapter", "*.json")], initialdir=initialDir)
|
||||
if fnam:
|
||||
chatcompletionsadapter_var.set(fnam)
|
||||
ctk.CTkButton(model_tab, 64, text="Pick Premade", command=pickpremadetemplate).grid(row=25, column=0, padx=322, stick="nw")
|
||||
|
@ -4311,7 +4415,7 @@ def show_gui():
|
|||
file_type = [("KoboldCpp LaunchTemplate", "*.kcppt")]
|
||||
#remove blacklisted fields
|
||||
savdict = convert_args_to_template(savdict)
|
||||
filename = asksaveasfilename(filetypes=file_type, defaultextension=".kcppt")
|
||||
filename = zentk_asksaveasfilename(filetypes=file_type, defaultextension=".kcppt")
|
||||
if not filename:
|
||||
return
|
||||
filenamestr = str(filename).strip()
|
||||
|
@ -4335,7 +4439,7 @@ def show_gui():
|
|||
# launch
|
||||
def guilaunch():
|
||||
if model_var.get() == "" and sd_model_var.get() == "" and whisper_model_var.get() == "" and tts_model_var.get() == "" and embeddings_model_var.get() == "" and nomodel.get()!=1:
|
||||
tmp = askopenfilename(title="Select ggml model .bin or .gguf file")
|
||||
tmp = zentk_askopenfilename(title="Select ggml model .bin or .gguf file")
|
||||
model_var.set(tmp)
|
||||
nonlocal nextstate
|
||||
nextstate = 1
|
||||
|
@ -4713,7 +4817,7 @@ def show_gui():
|
|||
export_vars()
|
||||
savdict = json.loads(json.dumps(args.__dict__))
|
||||
file_type = [("KoboldCpp Settings", "*.kcpps")]
|
||||
filename = asksaveasfilename(filetypes=file_type, defaultextension=".kcpps")
|
||||
filename = zentk_asksaveasfilename(filetypes=file_type, defaultextension=".kcpps")
|
||||
if not filename:
|
||||
return
|
||||
filenamestr = str(filename).strip()
|
||||
|
@ -4727,7 +4831,7 @@ def show_gui():
|
|||
def load_config_gui(): #this is used to populate the GUI with a config file, whereas load_config_cli simply overwrites cli args
|
||||
file_type = [("KoboldCpp Settings", "*.kcpps *.kcppt")]
|
||||
global runmode_untouched
|
||||
filename = askopenfilename(filetypes=file_type, defaultextension=".kcppt", initialdir=None)
|
||||
filename = zentk_askopenfilename(filetypes=file_type, defaultextension=".kcppt", initialdir=None)
|
||||
if not filename or filename=="":
|
||||
return
|
||||
runmode_untouched = False
|
||||
|
@ -5371,8 +5475,7 @@ def analyze_gguf_model(args,filename):
|
|||
def analyze_gguf_model_wrapper(filename=""):
|
||||
if not filename or filename=="":
|
||||
try:
|
||||
from tkinter.filedialog import askopenfilename
|
||||
filename = askopenfilename(title="Select GGUF to analyze")
|
||||
filename = zentk_askopenfilename(title="Select GGUF to analyze")
|
||||
except Exception as e:
|
||||
print(f"Cannot select file to analyze: {e}")
|
||||
if not filename or filename=="" or not os.path.exists(filename):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue