fix: tolerate gateways without image profiles

This commit is contained in:
2026-07-10 07:29:01 +08:00
parent f67cbbda65
commit c79e85e635
4 changed files with 36 additions and 7 deletions
+16 -5
View File
@@ -16,6 +16,7 @@ import subprocess
import sys
import tempfile
import tomllib
import urllib.error
import urllib.parse
import urllib.request
from pathlib import Path
@@ -23,7 +24,7 @@ from typing import Any
APP_NAME = "codex-retry-gateway-tui"
FALLBACK_VERSION = "0.1.8"
FALLBACK_VERSION = "0.1.9"
DEFAULT_GATEWAY_ADMIN_PATH = "/__codex_retry_gateway"
DEFAULT_GATEWAY_URL = "http://127.0.0.1:4610/__codex_retry_gateway"
DEFAULT_API_URL = DEFAULT_GATEWAY_URL
@@ -1150,11 +1151,21 @@ def fetch_payload(api_url: str, timeout: int, access_key: str = "") -> dict[str,
return data
def fetch_optional_payload(url: str, timeout: int, access_key: str = "") -> tuple[dict[str, Any], str]:
def fetch_optional_payload(
url: str,
timeout: int,
access_key: str = "",
*,
allow_not_found: bool = False,
) -> tuple[dict[str, Any], str]:
if not str(url or "").strip():
return {}, ""
try:
return fetch_payload(url, timeout, access_key), ""
except urllib.error.HTTPError as exc:
if allow_not_found and exc.code == 404:
return {}, ""
return {}, str(exc)
except Exception as exc:
return {}, str(exc)
@@ -2030,12 +2041,12 @@ def fetch_dashboard_snapshot(
"image_profiles": build_api_url(gateway_root, "/api/image-profiles"),
}
def fetch_optional(url: str) -> tuple[dict[str, Any], str]:
return fetch_optional_payload(url, timeout, access_key)
def fetch_optional(url: str, *, allow_not_found: bool = False) -> tuple[dict[str, Any], str]:
return fetch_optional_payload(url, timeout, access_key, allow_not_found=allow_not_found)
with ThreadPoolExecutor(max_workers=5) as pool:
futures = {
name: pool.submit(fetch_optional, url)
name: pool.submit(fetch_optional, url, allow_not_found=name == "image_profiles")
for name, url in endpoints.items()
}
status_payload, status_error = futures["status"].result()
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "codex-retry-gateway-tui"
version = "0.1.8"
version = "0.1.9"
description = "Terminal UI for codex-retry-gateway monitoring and control"
readme = "README.md"
requires-python = ">=3.11"
+18
View File
@@ -121,6 +121,24 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
self.assertEqual(mod.request_updated_elapsed(row), "1.0s")
self.assertEqual(mod.request_chunk_progress(row), "7 / 4.1KB")
def test_optional_image_profiles_endpoint_can_be_absent_on_older_gateway(self) -> None:
mod = load_module()
missing_endpoint = mod.urllib.error.HTTPError(
"http://127.0.0.1:4610/__codex_retry_gateway/api/image-profiles",
404,
"Not Found",
{},
None,
)
with mock.patch.object(mod, "fetch_payload", side_effect=missing_endpoint):
payload, error = mod.fetch_optional_payload(
"http://127.0.0.1:4610/__codex_retry_gateway/api/image-profiles",
5,
allow_not_found=True,
)
self.assertEqual(payload, {})
self.assertEqual(error, "")
def test_request_usage_summary_shows_cached_ratio(self) -> None:
mod = load_module()
row = {
Generated
+1 -1
View File
@@ -4,7 +4,7 @@ requires-python = ">=3.11"
[[package]]
name = "codex-retry-gateway-tui"
version = "0.1.8"
version = "0.1.9"
source = { editable = "." }
dependencies = [
{ name = "textual" },