Skip to content

Commit 3d99b87

Browse files
committed
add downloaddir
1 parent ada982b commit 3d99b87

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

koboldcpp.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5545,6 +5545,7 @@ def hide_tooltip(event):
55455545
draftgpulayers_var = ctk.StringVar(value=str(999))
55465546
draftgpusplit_str_vars = ctk.StringVar(value="")
55475547
nomodel = ctk.IntVar(value=0)
5548+
download_dir_var = ctk.StringVar()
55485549

55495550
port_var = ctk.StringVar(value=defaultport)
55505551
host_var = ctk.StringVar(value="")
@@ -6249,18 +6250,19 @@ def togglejinja(a,b,c):
62496250
makefileentry(model_tab, "Preload Story:", "Select Preloaded Story File", preloadstory_var, 17,width=280,singlerow=True,tooltiptxt="Select an optional KoboldAI JSON savefile \nto be served on launch to any client.")
62506251
makefileentry(model_tab, "SaveData File:", "Select or Create New SaveData Database File", savedatafile_var, 19,width=280,filetypes=[("KoboldCpp SaveDB", "*.jsondb")],singlerow=True,dialog_type=1,tooltiptxt="Selecting a file will allow data to be loaded and saved persistently to this KoboldCpp server remotely. File is created if it does not exist.")
62516252
makefileentry(model_tab, "MCP JSON:", "Select a mcp.json configuration file", mcpfile_var, 21,width=280,filetypes=[("MCP JSON", "*.json")],singlerow=True,tooltiptxt="Specify path to mcp.json which contains the Cladue Desktop compatible MCP server config.")
6252-
makefileentry(model_tab, "ChatCompletions Adapter:", "Select ChatCompletions Adapter File", chatcompletionsadapter_var, 24, width=250, filetypes=[("JSON Adapter", "*.json")], tooltiptxt="Select an optional ChatCompletions Adapter JSON file to force custom instruct tags.")
6253+
makefileentry(model_tab, "Chat Adapter:", "Select ChatCompletions Adapter File", chatcompletionsadapter_var, 24, width=184, filetypes=[("JSON Adapter", "*.json")], singlerow=True, tooltiptxt="Select an optional ChatCompletions Adapter JSON file to force custom instruct tags.")
62536254
def pickpremadetemplate():
62546255
initialDir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'kcpp_adapters')
62556256
initialDir = initialDir if os.path.isdir(initialDir) else None
62566257
fnam = zentk_askopenfilename(title="Pick Premade ChatCompletions Adapter",filetypes=[("JSON Adapter", "*.json")], initialdir=initialDir)
62576258
if fnam:
62586259
chatcompletionsadapter_var.set(fnam)
6259-
ctk.CTkButton(model_tab, 64, text="Pick Premade", command=pickpremadetemplate).grid(row=25, column=0, padx=(322), pady=2, stick="nw")
6260+
ctk.CTkButton(model_tab, 64, text="Pick Premade", command=pickpremadetemplate).grid(row=24, column=0, padx=(350), pady=2, stick="nw")
62606261

62616262
mmproj_var.trace_add("write", gui_changed_modelfile)
62626263
draftmodel_var.trace_add("write", gui_changed_modelfile)
6263-
makecheckbox(model_tab, "Allow Launch Without Models", nomodel, 27, tooltiptxt="Allows running the WebUI with no model loaded.")
6264+
makefileentry(model_tab, "Download Dir:", "Select directory to store all model downloads", download_dir_var, 27, width=280, singlerow=True, dialog_type=2, tooltiptxt="Specify a directory to store any downloaded models.")
6265+
makecheckbox(model_tab, "Allow Launch Without Models", nomodel, 40, tooltiptxt="Allows running the WebUI with no model loaded.")
62646266

62656267
# Network Tab
62666268
network_tab = tabcontent["Network"]
@@ -6578,6 +6580,7 @@ def export_vars():
65786580
args.preloadstory = None if preloadstory_var.get() == "" else preloadstory_var.get()
65796581
args.savedatafile = None if savedatafile_var.get() == "" else savedatafile_var.get()
65806582
args.mcpfile = None if mcpfile_var.get() == "" else mcpfile_var.get()
6583+
args.downloaddir = download_dir_var.get()
65816584
try:
65826585
if kcpp_exporting_template and isinstance(args.preloadstory, str) and args.preloadstory!="" and os.path.exists(args.preloadstory):
65836586
print("Embedding preload story...") # parse and save embedded preload story
@@ -6859,6 +6862,7 @@ def import_vars(dict):
68596862
multiuser_var.set(dict["multiuser"] if ("multiuser" in dict) else 1)
68606863
multiplayer_var.set(dict["multiplayer"] if ("multiplayer" in dict) else 0)
68616864
websearch_var.set(dict["websearch"] if ("websearch" in dict) else 0)
6865+
download_dir_var.set(dict["downloaddir"] if ("downloaddir" in dict and dict["downloaddir"]) else "")
68626866

68636867
horde_name_var.set(dict["hordemodelname"] if ("hordemodelname" in dict and dict["hordemodelname"]) else "koboldcpp")
68646868
horde_context_var.set(dict["hordemaxctx"] if ("hordemaxctx" in dict and dict["hordemaxctx"]) else maxhordectx)
@@ -6985,11 +6989,11 @@ def load_noob_template():
69856989
if data is not None:
69866990
import_vars(data)
69876991
popup.destroy()
6988-
ctk.CTkLabel(popup, text="Newbie Resources").pack(pady=(5, 0))
6992+
ctk.CTkLabel(popup, text="Helpful Newbie Resources").pack(pady=(5, 0))
69896993
ctk.CTkButton(popup, text="Read the Wiki", command=display_wiki).pack(pady=5)
69906994
ctk.CTkButton(popup, text="Read Starter Guides", command=display_starter_guides).pack(pady=5)
69916995
ctk.CTkButton(popup, text="Search Model on Hugginface", command=display_hf).pack(pady=5)
6992-
ctk.CTkLabel(popup, text="Easy Templates for Newbies").pack(pady=(12, 0))
6996+
ctk.CTkLabel(popup, text="Or, Pick an Easy Template for Newbies").pack(pady=(12, 0))
69936997
noobbox = ctk.CTkComboBox(popup, values=[], width=280, variable=noobbox_var, state="readonly")
69946998
noobbox.pack(pady=5)
69956999
ctk.CTkButton(popup, text="Load Template", command=load_noob_template).pack(pady=5)
@@ -7012,7 +7016,7 @@ def display_updates():
70127016
ctk.CTkButton(tabs , text = "Update", fg_color="#9900cc", hover_color="#aa11dd", command = display_updates, width=90, height = 35 ).grid(row=1,column=0, stick="sw", padx= 5, pady=5)
70137017
ctk.CTkButton(tabs , text = "Save Config", fg_color="#084a66", hover_color="#085a88", command = save_config_gui, width=60, height = 35 ).grid(row=1,column=1, stick="sw", padx= 5, pady=5)
70147018
ctk.CTkButton(tabs , text = "Load Config", fg_color="#084a66", hover_color="#085a88", command = load_config_gui, width=60, height = 35 ).grid(row=1,column=1, stick="sw", padx= (92), pady=5)
7015-
ctk.CTkButton(tabs , text = "Help", fg_color="#992222", hover_color="#bb3333", command = display_help, width=60, height = 35 ).grid(row=1,column=1, stick="sw", padx= (180), pady=5)
7019+
ctk.CTkButton(tabs , text = "Get Help", fg_color="#992222", hover_color="#bb3333", command = display_help, width=60, height = 35 ).grid(row=1,column=1, stick="sw", padx= (180), pady=5)
70167020

70177021
# start a thread that tries to get actual gpu names and layer counts
70187022
gpuinfo_thread = threading.Thread(target=auto_set_backend_gui)
@@ -7542,21 +7546,28 @@ def sanitize_string(input_string):
75427546
return sanitized_string
75437547

75447548
def downloader_internal(input_url, output_filename, capture_output, min_file_size=64): # 64 bytes required by default
7549+
download_dir_path = args.downloaddir
75457550
if "https://huggingface.co/" in input_url and "/blob/main/" in input_url:
75467551
input_url = input_url.replace("/blob/main/", "/resolve/main/")
7552+
if download_dir_path:
7553+
download_dir_path = os.path.abspath(download_dir_path)
7554+
os.makedirs(download_dir_path, exist_ok=True)
75477555
if output_filename == "auto":
7548-
cwd = os.getcwd()
7549-
non_writable = False
7550-
if os.name == "nt":
7551-
parts = [p.lower() for p in os.path.normpath(cwd).split(os.sep)]
7552-
if "windows" in parts and ("system32" in parts or "syswow64" in parts):
7553-
non_writable = True
7554-
if not non_writable:
7555-
output_filename = os.path.basename(input_url).split('?')[0].split('#')[0]
7556+
filename = os.path.basename(input_url).split('?')[0].split('#')[0]
7557+
if download_dir_path:
7558+
output_filename = os.path.join(download_dir_path, filename)
75567559
else:
7557-
exe_dir = os.path.dirname(sys.executable if getattr(sys, 'frozen', False) else __file__)
7558-
filename = os.path.basename(input_url).split('?')[0].split('#')[0]
7559-
output_filename = os.path.join(exe_dir, filename)
7560+
cwd = os.getcwd()
7561+
non_writable = False
7562+
if os.name == "nt":
7563+
parts = [p.lower() for p in os.path.normpath(cwd).split(os.sep)]
7564+
if "windows" in parts and ("system32" in parts or "syswow64" in parts):
7565+
non_writable = True
7566+
if not non_writable:
7567+
output_filename = filename
7568+
else:
7569+
exe_dir = os.path.dirname(sys.executable if getattr(sys, 'frozen', False) else __file__)
7570+
output_filename = os.path.join(exe_dir, filename)
75607571
incomplete_dl_exist = (os.path.exists(output_filename+".aria2") and os.path.getsize(output_filename+".aria2") > 16)
75617572
if os.path.exists(output_filename) and os.path.getsize(output_filename) > min_file_size and not incomplete_dl_exist:
75627573
print(f"{output_filename} already exists, using existing file.")
@@ -8894,6 +8905,7 @@ def range_checker(arg: str):
88948905
advparser.add_argument("--gendefaultsoverwrite", help="Allow the gendefaults parameters to overwrite the original value in API payloads.", action='store_true')
88958906
advparser.add_argument("--mcpfile", metavar=('[mcp json file]'), help="Specify path to mcp.json which contains the Cladue Desktop compatible MCP server config.", default="")
88968907
advparser.add_argument("--device", "-dev", metavar=('<dev1,dev2,..>'), help="Set llama.cpp compatible device selection override. Comma separated. Overrides normal device choices.", default="")
8908+
advparser.add_argument("--downloaddir", metavar=('[directory]'), help="Specify a directory that models will be downloaded to or searched from, if unset uses the working directory.", default="")
88978909

88988910
hordeparsergroup = parser.add_argument_group('Horde Worker Commands')
88998911
hordeparsergroup.add_argument("--hordemodelname", metavar=('[name]'), help="Sets your AI Horde display model name.", default="")

0 commit comments

Comments
 (0)