feat: preserve image profile configuration
This commit is contained in:
@@ -23,7 +23,7 @@ from typing import Any
|
||||
|
||||
|
||||
APP_NAME = "codex-retry-gateway-tui"
|
||||
FALLBACK_VERSION = "0.1.4"
|
||||
FALLBACK_VERSION = "0.1.5"
|
||||
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
|
||||
@@ -1403,6 +1403,7 @@ def normalize_request_rows(payload: dict[str, Any], filter_text: str = "") -> li
|
||||
"error": str(entry.get("error") or ""),
|
||||
"upstream_origin": str(entry.get("upstream")["origin"] if isinstance(entry.get("upstream"), dict) else entry.get("upstream_origin") or ""),
|
||||
"upstream_path": str(entry.get("upstream")["path"] if isinstance(entry.get("upstream"), dict) else entry.get("upstream_path") or ""),
|
||||
"upstream_route": str(entry.get("upstream")["route"] if isinstance(entry.get("upstream"), dict) else entry.get("upstream_route") or ""),
|
||||
"upstream_auth_mode": str(entry.get("upstream")["auth_mode"] if isinstance(entry.get("upstream"), dict) else entry.get("upstream_auth_mode") or ""),
|
||||
"upstream_auth_source": str(entry.get("upstream")["auth_source"] if isinstance(entry.get("upstream"), dict) else entry.get("upstream_auth_source") or ""),
|
||||
"raw": entry,
|
||||
@@ -1456,6 +1457,8 @@ def render_request_detail(row: dict[str, Any]) -> str:
|
||||
bits.append(f"origin {row['upstream_origin']}")
|
||||
if row.get("upstream_path"):
|
||||
bits.append(f"upstream path {row['upstream_path']}")
|
||||
if row.get("upstream_route"):
|
||||
bits.append(f"route {row['upstream_route']}")
|
||||
if row.get("upstream_auth_mode"):
|
||||
bits.append(f"auth {row['upstream_auth_mode']}/{row.get('upstream_auth_source') or '-'}")
|
||||
retry_wave = request_retry_wave_summary(row)
|
||||
@@ -1490,6 +1493,14 @@ def normalize_profile_rows(payload: dict[str, Any], filter_text: str = "") -> li
|
||||
"auth_file": str(summary.get("auth_file") or ""),
|
||||
"auth_json_path": str(summary.get("auth_json_path") or ""),
|
||||
"auth_json_key": str(summary.get("auth_json_key") or "-"),
|
||||
"image_base_url": str(summary.get("image_base_url") or "-"),
|
||||
"image_auth_mode": str(summary.get("image_auth_mode") or "-"),
|
||||
"image_auth_env": str(summary.get("image_auth_env") or "-"),
|
||||
"image_auth_file": str(summary.get("image_auth_file") or ""),
|
||||
"image_manual_secret_file": str(summary.get("image_manual_secret_file") or ""),
|
||||
"image_auth_json_path": str(summary.get("image_auth_json_path") or ""),
|
||||
"image_auth_json_key": str(summary.get("image_auth_json_key") or "-"),
|
||||
"image_auth_source": str(summary.get("image_auth_source") or "disabled"),
|
||||
"request_history_limit": summary.get("request_history_limit"),
|
||||
"model_remap": str(summary.get("model_remap") or ""),
|
||||
"auth_source": str(summary.get("auth_source") or "-"),
|
||||
@@ -1506,9 +1517,14 @@ def render_profile_detail(row: dict[str, Any]) -> str:
|
||||
f"{row['name']}",
|
||||
"active" if row["active"] else "inactive",
|
||||
f"listen {row['listen_host']}:{row['listen_port']}",
|
||||
f"upstream {short_text(row['upstream_base_url'], 64)}",
|
||||
f"auth {row['auth_mode']}/{row['auth_source']}",
|
||||
f"text upstream {short_text(row['upstream_base_url'], 64)}",
|
||||
f"text auth {row['auth_mode']}/{row['auth_source']}",
|
||||
]
|
||||
if row.get("image_base_url") and row["image_base_url"] != "-":
|
||||
bits.append(f"image upstream {short_text(row['image_base_url'], 64)}")
|
||||
bits.append(f"image auth {row['image_auth_mode']}/{row['image_auth_source']}")
|
||||
else:
|
||||
bits.append("image upstream disabled")
|
||||
if row.get("request_history_limit") is not None:
|
||||
bits.append(f"history {row['request_history_limit']}")
|
||||
if row.get("reasoning_equals"):
|
||||
@@ -1538,6 +1554,15 @@ def profile_form_state(row: dict[str, Any]) -> dict[str, Any]:
|
||||
"manual_secret_configured": parse_bool_value(form.get("manual_secret_configured"), False),
|
||||
"auth_json_path": form.get("auth_json_path") or "",
|
||||
"auth_json_key": form.get("auth_json_key") or row.get("auth_json_key") or "",
|
||||
"image_base_url": form.get("image_base_url") or "",
|
||||
"image_auth_mode": form.get("image_auth_mode") or "fixed_bearer",
|
||||
"image_auth_env": form.get("image_auth_env") or "CODEX_RETRY_GATEWAY_IMAGE_API_KEY",
|
||||
"image_auth_file": form.get("image_auth_file") or "",
|
||||
"image_manual_secret": "",
|
||||
"image_manual_secret_file": form.get("image_manual_secret_file") or "",
|
||||
"image_manual_secret_configured": parse_bool_value(form.get("image_manual_secret_configured"), False),
|
||||
"image_auth_json_path": form.get("image_auth_json_path") or "",
|
||||
"image_auth_json_key": form.get("image_auth_json_key") or "OPENAI_API_KEY",
|
||||
"request_history_limit": parse_int_value(form.get("request_history_limit") or row.get("request_history_limit"))
|
||||
if parse_int_value(form.get("request_history_limit") or row.get("request_history_limit")) is not None
|
||||
else DEFAULT_PROFILE_REQUEST_HISTORY_LIMIT,
|
||||
@@ -1573,6 +1598,15 @@ def profile_payload_from_row(row: dict[str, Any]) -> dict[str, Any]:
|
||||
"manual_secret_configured": bool(state.get("manual_secret_configured")),
|
||||
"auth_json_path": str(state.get("auth_json_path") or "").strip(),
|
||||
"auth_json_key": str(state.get("auth_json_key") or "").strip(),
|
||||
"image_base_url": str(state.get("image_base_url") or "").strip(),
|
||||
"image_auth_mode": str(state.get("image_auth_mode") or "fixed_bearer").strip(),
|
||||
"image_auth_env": str(state.get("image_auth_env") or "").strip(),
|
||||
"image_auth_file": str(state.get("image_auth_file") or "").strip(),
|
||||
"image_manual_secret": "",
|
||||
"image_manual_secret_file": str(state.get("image_manual_secret_file") or "").strip(),
|
||||
"image_manual_secret_configured": bool(state.get("image_manual_secret_configured")),
|
||||
"image_auth_json_path": str(state.get("image_auth_json_path") or "").strip(),
|
||||
"image_auth_json_key": str(state.get("image_auth_json_key") or "").strip(),
|
||||
"request_history_limit": state.get("request_history_limit"),
|
||||
"model_remap": str(state.get("model_remap") or "").strip(),
|
||||
"reasoning_equals": state.get("reasoning_equals") or [],
|
||||
@@ -1595,6 +1629,8 @@ def profile_editor_document(row: dict[str, Any]) -> str:
|
||||
[
|
||||
"# Edit the selected codex-retry-gateway profile and save.",
|
||||
"# Leave manual_secret empty to keep the current secret file.",
|
||||
"# image_base_url applies to both /images/* and /v1/images/*.",
|
||||
"# Leave image_manual_secret empty to keep the current image secret file.",
|
||||
"# Changing name creates a new profile file; it does not delete the old one.",
|
||||
"",
|
||||
f"name = {toml_string(state.get('name'))}",
|
||||
@@ -1609,6 +1645,18 @@ def profile_editor_document(row: dict[str, Any]) -> str:
|
||||
f"manual_secret_configured = {toml_bool(state.get('manual_secret_configured'))}",
|
||||
f"auth_json_path = {toml_string(state.get('auth_json_path'))}",
|
||||
f"auth_json_key = {toml_string(state.get('auth_json_key'))}",
|
||||
"",
|
||||
"# Optional image-specific upstream and authentication.",
|
||||
f"image_base_url = {toml_string(state.get('image_base_url'))}",
|
||||
f"image_auth_mode = {toml_string(state.get('image_auth_mode'))}",
|
||||
f"image_auth_env = {toml_string(state.get('image_auth_env'))}",
|
||||
f"image_auth_file = {toml_string(state.get('image_auth_file'))}",
|
||||
'image_manual_secret = ""',
|
||||
f"image_manual_secret_file = {toml_string(state.get('image_manual_secret_file'))}",
|
||||
f"image_manual_secret_configured = {toml_bool(state.get('image_manual_secret_configured'))}",
|
||||
f"image_auth_json_path = {toml_string(state.get('image_auth_json_path'))}",
|
||||
f"image_auth_json_key = {toml_string(state.get('image_auth_json_key'))}",
|
||||
"",
|
||||
f"request_history_limit = {state.get('request_history_limit') if state.get('request_history_limit') is not None else 0}",
|
||||
f"model_remap = {model_remap_value}",
|
||||
f"reasoning_equals = {toml_int_list(state.get('reasoning_equals'))}",
|
||||
@@ -1639,6 +1687,15 @@ def profile_payload_from_editor_text(text: str) -> dict[str, Any]:
|
||||
"manual_secret_configured": parse_bool_value(data.get("manual_secret_configured"), False),
|
||||
"auth_json_path": str(data.get("auth_json_path") or "").strip(),
|
||||
"auth_json_key": str(data.get("auth_json_key") or "").strip(),
|
||||
"image_base_url": str(data.get("image_base_url") or "").strip(),
|
||||
"image_auth_mode": str(data.get("image_auth_mode") or "fixed_bearer").strip(),
|
||||
"image_auth_env": str(data.get("image_auth_env") or "").strip(),
|
||||
"image_auth_file": str(data.get("image_auth_file") or "").strip(),
|
||||
"image_manual_secret": str(data.get("image_manual_secret") or "").strip(),
|
||||
"image_manual_secret_file": str(data.get("image_manual_secret_file") or "").strip(),
|
||||
"image_manual_secret_configured": parse_bool_value(data.get("image_manual_secret_configured"), False),
|
||||
"image_auth_json_path": str(data.get("image_auth_json_path") or "").strip(),
|
||||
"image_auth_json_key": str(data.get("image_auth_json_key") or "").strip(),
|
||||
"request_history_limit": parse_int_value(data.get("request_history_limit")),
|
||||
"model_remap": str(data.get("model_remap") or "").strip(),
|
||||
"reasoning_equals": normalize_editor_integer_list(data.get("reasoning_equals")),
|
||||
@@ -1918,7 +1975,18 @@ def run_textual(
|
||||
profiles = self.query_one("#profiles_table", DataTable)
|
||||
profiles.cursor_type = "row"
|
||||
profiles.zebra_stripes = True
|
||||
profiles.add_columns("Name", "Active", "Listen", "Upstream", "Auth", "History", "Reasoning", "Source")
|
||||
profiles.add_columns(
|
||||
"Name",
|
||||
"Active",
|
||||
"Listen",
|
||||
"Text Upstream",
|
||||
"Text Auth",
|
||||
"Image Upstream",
|
||||
"Image Auth",
|
||||
"History",
|
||||
"Reasoning",
|
||||
"Source",
|
||||
)
|
||||
|
||||
self._set_view("overview")
|
||||
self.refresh_data(refresh=True)
|
||||
@@ -2193,6 +2261,8 @@ def run_textual(
|
||||
f"{row['listen_host']}:{row['listen_port']}",
|
||||
short_text(row["upstream_base_url"], 24),
|
||||
f"{row['auth_mode']}/{row['auth_source']}",
|
||||
short_text(row["image_base_url"], 24),
|
||||
f"{row['image_auth_mode']}/{row['image_auth_source']}",
|
||||
str(row["request_history_limit"] if row["request_history_limit"] is not None else "-"),
|
||||
short_text(row["reasoning_equals"], 12),
|
||||
short_text(row["file_path"], 28),
|
||||
|
||||
Reference in New Issue
Block a user