From 7bd95eb50597dc0c1b0b8f4b95b2cb974f20f502 Mon Sep 17 00:00:00 2001 From: Concedo <39025047+LostRuins@users.noreply.github.com> Date: Wed, 29 Apr 2026 21:55:07 +0800 Subject: [PATCH] routermodetimeout -> reqtimeout, add to gui --- koboldcpp.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/koboldcpp.py b/koboldcpp.py index 53e31acce..4d91db0ab 100644 --- a/koboldcpp.py +++ b/koboldcpp.py @@ -64,6 +64,7 @@ default_autofit_padding = 1024 lora_filenames_max = 4 multiuser_concurrent_limit = 10 swa_padding_default = 0 +default_reqtimeout = 600 # 10 min default # abuse prevention stop_token_max = 256 @@ -645,9 +646,9 @@ class MCPStdioClient: if not await_response: return None try: - response = response_q.get(timeout=120) + response = response_q.get(timeout=180) except queue.Empty: - raise RuntimeError("MCP server timed out (no response in 120s)") + raise RuntimeError("MCP server timed out (no response in 180s)") finally: with self._pending_lock: self._pending.pop(msg_id, None) @@ -667,7 +668,7 @@ class MCPStdioClient: self.process.terminate() class MCPHTTPClient: - def __init__(self, url, headers=None, timeout=60.0): + def __init__(self, url, headers=None, timeout=180.0): global nocertify self.url = url self.headers = {"Content-Type": "application/json","Accept": "application/json, text/event-stream"} @@ -3013,13 +3014,13 @@ def websearch(query): os.environ['SSL_CERT_DIR'] = '/etc/ssl/certs' req = urllib.request.Request(encoded_url, headers={'User-Agent': uagent}) - with urllib.request.urlopen(req, timeout=15) as response: + with urllib.request.urlopen(req, timeout=30) as response: html_content = response.read().decode('utf-8', errors='ignore') return html_content except urllib.error.HTTPError: #we got blocked? try 1 more time with a different user agent try: req = urllib.request.Request(encoded_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}) - with urllib.request.urlopen(req, timeout=15) as response: + with urllib.request.urlopen(req, timeout=30) as response: html_content = response.read().decode('utf-8', errors='ignore') return html_content except Exception as e: @@ -4418,7 +4419,7 @@ class KcppProxyHandler(http.server.BaseHTTPRequestHandler): } if args.adminpassword: reqheaders["Authorization"] = f"Bearer {args.adminpassword}" - conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.routermodetimeout) + conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.reqtimeout) conn.request("POST", "/api/admin/reload_config", body=reqbody, headers=reqheaders) resp = conn.getresponse() time.sleep(3) @@ -4464,7 +4465,7 @@ class KcppProxyHandler(http.server.BaseHTTPRequestHandler): } if args.adminpassword: reqheaders["Authorization"] = f"Bearer {args.adminpassword}" - conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.routermodetimeout) + conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.reqtimeout) conn.request("POST", "/api/admin/reload_config", body=reqbody, headers=reqheaders) resp = conn.getresponse() time.sleep(3) @@ -4475,7 +4476,7 @@ class KcppProxyHandler(http.server.BaseHTTPRequestHandler): time.sleep(0.1) try: # connect upstream - conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.routermodetimeout) + conn = http.client.HTTPConnection('localhost', upstream_port, timeout=args.reqtimeout) conn.request( self.command, self.path, body=body, headers=headers) resp = conn.getresponse() except OSError as e: @@ -7453,6 +7454,7 @@ def show_gui(): password_var = ctk.StringVar() maxrequestsize_var = ctk.StringVar(value=str(32)) ratelimit_var = ctk.StringVar(value=str(0)) + reqtimeout_var = ctk.StringVar(value=str(default_reqtimeout)) sd_model_var = ctk.StringVar() sd_lora_var = ctk.StringVar() @@ -8238,6 +8240,7 @@ def show_gui(): makelabelentry(network_tab, "Max Req. Size (MB):", maxrequestsize_var, row=20, width=50, tooltip="Specify a max request payload size. Any requests to the server larger than this size will be dropped. Do not change if unsure.") makelabelentry(network_tab, "IP Rate Limiter (s):", ratelimit_var, row=22, width=50, tooltip="Rate limits each IP to allow a new request once per X seconds. Do not change if unsure.") + makelabelentry(network_tab, "Request Timeout (s):", reqtimeout_var, row=24, width=50, tooltip="Timeout in seconds for HTTP requests") # Horde Tab @@ -8607,6 +8610,7 @@ def show_gui(): args.websearch = (websearch_var.get()==1) args.maxrequestsize = int(maxrequestsize_var.get()) if maxrequestsize_var.get()!="" else 32 args.ratelimit = int(ratelimit_var.get()) if ratelimit_var.get()!="" else 0 + args.reqtimeout = int(reqtimeout_var.get()) if reqtimeout_var.get()!="" else 0 if usehorde_var.get() != 0: args.hordemodelname = horde_name_var.get() @@ -8896,10 +8900,9 @@ def show_gui(): horde_apikey_var.set(mydict["hordekey"] if ("hordekey" in mydict and mydict["hordekey"]) else "") horde_workername_var.set(mydict["hordeworkername"] if ("hordeworkername" in mydict and mydict["hordeworkername"]) else "") usehorde_var.set(1 if ("hordekey" in mydict and mydict["hordekey"]) else 0) - if "maxrequestsize" in mydict and mydict["maxrequestsize"]: - maxrequestsize_var.set(mydict["maxrequestsize"]) - if "ratelimit" in mydict and mydict["ratelimit"]: - ratelimit_var.set(mydict["ratelimit"]) + maxrequestsize_var.set(mydict["maxrequestsize"] if ("maxrequestsize" in mydict and mydict["maxrequestsize"]) else 32) + ratelimit_var.set(mydict["ratelimit"] if ("ratelimit" in mydict and mydict["ratelimit"]) else 0) + reqtimeout_var.set(mydict["reqtimeout"] if ("reqtimeout" in mydict and mydict["reqtimeout"]) else 0) sd_model_var.set(mydict["sdmodel"] if ("sdmodel" in mydict and mydict["sdmodel"]) else "") sd_clamped_var.set(int(mydict["sdclamped"]) if ("sdclamped" in mydict and mydict["sdclamped"]) else 0) @@ -11454,7 +11457,7 @@ if __name__ == '__main__': admingroup.add_argument("--admindir", metavar=('[directory]'), help="Specify a directory to look for .kcpps configs in, which can be used to swap models.", default="") admingroup.add_argument("--adminunloadtimeout", help="Set an idle timeout in seconds after which KoboldCpp will automatically unload the current model.", type=int, default=0) admingroup.add_argument("--routermode", help="Router mode uses a reverse proxy router, allowing you to easily hotswap models and configs within a single request. Requires admin mode.", action='store_true') - admingroup.add_argument("--routermodetimeout", metavar=('[seconds]'), help="Timeout in seconds for the router-mode reverse proxy when forwarding requests to the loaded backend (also applies to admin reload calls). Increase this if long generations are being cut off at the proxy. Defaults to 600.", type=int, default=600) + admingroup.add_argument("--reqtimeout", metavar=('[seconds]'), help="Timeout in seconds for HTTP requests.", type=int, default=default_reqtimeout) admingroup.add_argument("--autoswapmode", help="Autoswap mode builds on router mode to allow switching of model types within the same config automatically. Requires admin mode and router mode. All models desired must be defined within the same config.", action='store_true') admingroup.add_argument("--baseconfig", help="Specify a base .kcpps config to apply, if no custom base config is selected during a model swap", default="")