Update OpenClaw to 2026.2.24 and enhance gateway configuration options
- Added `gateway_remote_url` and `gateway_additional_allowed_origins` options for improved remote gateway support. - Updated startup guidance for `gateway_auth_mode=trusted-proxy`. - Adjusted token retrieval instructions in the landing page. - Updated translations for new configuration options. - Fixed various issues related to gateway settings and TLS certificate generation.
This commit is contained in:
@@ -57,12 +57,13 @@ def set_gateway_setting(key, value):
|
||||
return write_config(cfg)
|
||||
|
||||
|
||||
def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_api: bool, auth_mode: str, trusted_proxies_csv: str):
|
||||
def apply_gateway_settings(mode: str, remote_url: str, bind_mode: str, port: int, enable_openai_api: bool, auth_mode: str, trusted_proxies_csv: str):
|
||||
"""
|
||||
Apply gateway settings to OpenClaw config.
|
||||
|
||||
Args:
|
||||
mode: "local" or "remote"
|
||||
remote_url: remote Gateway websocket URL (used when mode=remote)
|
||||
bind_mode: "loopback", "lan", or "tailnet"
|
||||
port: Port number to listen on (must be 1-65535)
|
||||
enable_openai_api: Enable OpenAI-compatible Chat Completions endpoint
|
||||
@@ -97,7 +98,12 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a
|
||||
cfg["gateway"] = {}
|
||||
|
||||
gateway = cfg["gateway"]
|
||||
|
||||
|
||||
# gateway.remote settings
|
||||
if "remote" not in gateway or not isinstance(gateway.get("remote"), dict):
|
||||
gateway["remote"] = {}
|
||||
remote_cfg = gateway["remote"]
|
||||
|
||||
# auth should be nested inside gateway
|
||||
if "auth" not in gateway:
|
||||
gateway["auth"] = {}
|
||||
@@ -120,6 +126,7 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a
|
||||
trusted_proxy_cfg_default = {"userHeader": "x-forwarded-user"}
|
||||
|
||||
current_mode = gateway.get("mode", "")
|
||||
current_remote_url = remote_cfg.get("url", "")
|
||||
current_bind = gateway.get("bind", "")
|
||||
current_port = gateway.get("port", 18789)
|
||||
current_openai_api = chat_completions.get("enabled", False)
|
||||
@@ -132,6 +139,10 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a
|
||||
if current_mode != mode:
|
||||
gateway["mode"] = mode
|
||||
changes.append(f"mode: {current_mode} -> {mode}")
|
||||
|
||||
if current_remote_url != remote_url:
|
||||
remote_cfg["url"] = remote_url
|
||||
changes.append(f"remote.url: {current_remote_url} -> {remote_url}")
|
||||
|
||||
if current_bind != bind_mode:
|
||||
gateway["bind"] = bind_mode
|
||||
@@ -166,11 +177,11 @@ def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_a
|
||||
print("ERROR: Failed to write config")
|
||||
return False
|
||||
else:
|
||||
print(f"INFO: Gateway settings already correct (mode={mode}, bind={bind_mode}, port={port}, chatCompletions={enable_openai_api}, authMode={auth_mode}, trustedProxies={trusted_proxies})")
|
||||
print(f"INFO: Gateway settings already correct (mode={mode}, remoteUrl={remote_url}, bind={bind_mode}, port={port}, chatCompletions={enable_openai_api}, authMode={auth_mode}, trustedProxies={trusted_proxies})")
|
||||
return True
|
||||
|
||||
|
||||
def set_control_ui_origins(origins_csv: str):
|
||||
def set_control_ui_origins(origins_csv: str, additional_origins_csv: str = ""):
|
||||
"""
|
||||
Configure gateway.controlUi for the built-in HTTPS proxy.
|
||||
|
||||
@@ -186,8 +197,8 @@ def set_control_ui_origins(origins_csv: str):
|
||||
been written by earlier add-on versions.
|
||||
|
||||
Args:
|
||||
origins_csv: Comma-separated list of allowed origins.
|
||||
Pass an empty string to clear / leave unset.
|
||||
origins_csv: Comma-separated list of default origins provided by the add-on.
|
||||
additional_origins_csv: Comma-separated list of user-provided extra origins.
|
||||
"""
|
||||
cfg = read_config()
|
||||
if cfg is None:
|
||||
@@ -201,14 +212,23 @@ def set_control_ui_origins(origins_csv: str):
|
||||
gateway["controlUi"] = {}
|
||||
|
||||
control_ui = gateway["controlUi"]
|
||||
origins = [o.strip() for o in origins_csv.split(",") if o.strip()]
|
||||
default_origins = [o.strip() for o in origins_csv.split(",") if o.strip()]
|
||||
additional_origins = [o.strip() for o in (additional_origins_csv or "").split(",") if o.strip()]
|
||||
changes = []
|
||||
|
||||
# --- allowedOrigins ---
|
||||
current_origins = control_ui.get("allowedOrigins", [])
|
||||
if current_origins != origins:
|
||||
control_ui["allowedOrigins"] = origins
|
||||
changes.append(f"allowedOrigins: {current_origins} -> {origins}")
|
||||
if not isinstance(current_origins, list):
|
||||
current_origins = []
|
||||
|
||||
merged_origins = []
|
||||
for origin in [*default_origins, *current_origins, *additional_origins]:
|
||||
if isinstance(origin, str) and origin and origin not in merged_origins:
|
||||
merged_origins.append(origin)
|
||||
|
||||
if current_origins != merged_origins:
|
||||
control_ui["allowedOrigins"] = merged_origins
|
||||
changes.append(f"allowedOrigins: {current_origins} -> {merged_origins}")
|
||||
|
||||
# --- dangerouslyDisableDeviceAuth ---
|
||||
# Skips the interactive pairing handshake (error 1008: pairing required).
|
||||
@@ -224,7 +244,7 @@ def set_control_ui_origins(origins_csv: str):
|
||||
changes.append(f"removed invalid key: {stale_key}")
|
||||
|
||||
if not changes:
|
||||
print(f"INFO: controlUi already correct: origins={origins}, deviceAuth=disabled")
|
||||
print(f"INFO: controlUi already correct: origins={merged_origins}, deviceAuth=disabled")
|
||||
return True
|
||||
|
||||
if write_config(cfg):
|
||||
@@ -243,16 +263,17 @@ def main():
|
||||
cmd = sys.argv[1]
|
||||
|
||||
if cmd == "apply-gateway-settings":
|
||||
if len(sys.argv) != 8:
|
||||
print("Usage: oc_config_helper.py apply-gateway-settings <local|remote> <loopback|lan|tailnet> <port> <enable_openai_api:true|false> <auth_mode:token|trusted-proxy> <trusted_proxies_csv>")
|
||||
if len(sys.argv) != 9:
|
||||
print("Usage: oc_config_helper.py apply-gateway-settings <local|remote> <remote_url> <loopback|lan|tailnet> <port> <enable_openai_api:true|false> <auth_mode:token|trusted-proxy> <trusted_proxies_csv>")
|
||||
sys.exit(1)
|
||||
mode = sys.argv[2]
|
||||
bind_mode = sys.argv[3]
|
||||
port = int(sys.argv[4])
|
||||
enable_openai_api = sys.argv[5].lower() == "true"
|
||||
auth_mode = sys.argv[6]
|
||||
trusted_proxies_csv = sys.argv[7]
|
||||
success = apply_gateway_settings(mode, bind_mode, port, enable_openai_api, auth_mode, trusted_proxies_csv)
|
||||
remote_url = sys.argv[3]
|
||||
bind_mode = sys.argv[4]
|
||||
port = int(sys.argv[5])
|
||||
enable_openai_api = sys.argv[6].lower() == "true"
|
||||
auth_mode = sys.argv[7]
|
||||
trusted_proxies_csv = sys.argv[8]
|
||||
success = apply_gateway_settings(mode, remote_url, bind_mode, port, enable_openai_api, auth_mode, trusted_proxies_csv)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif cmd == "get":
|
||||
@@ -266,11 +287,12 @@ def main():
|
||||
sys.exit(0)
|
||||
|
||||
elif cmd == "set-control-ui-origins":
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: oc_config_helper.py set-control-ui-origins <origins_csv>")
|
||||
if len(sys.argv) not in (3, 4):
|
||||
print("Usage: oc_config_helper.py set-control-ui-origins <origins_csv> [additional_origins_csv]")
|
||||
sys.exit(1)
|
||||
origins_csv = sys.argv[2]
|
||||
success = set_control_ui_origins(origins_csv)
|
||||
additional_origins_csv = sys.argv[3] if len(sys.argv) == 4 else ""
|
||||
success = set_control_ui_origins(origins_csv, additional_origins_csv)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif cmd == "set":
|
||||
|
||||
Reference in New Issue
Block a user