feat: separate image profiles in tui

This commit is contained in:
2026-07-10 07:04:50 +08:00
parent c52afce684
commit e4b7fc679e
4 changed files with 338 additions and 121 deletions
+49 -11
View File
@@ -28,7 +28,7 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
"config": {"profile_name": "pc", "upstream_base_url": "https://example.com/v1"},
"metrics": {"total_proxy_request_count": 11, "inspected_response_count": 7, "matched_response_count": 2, "reasoning_516_count": 1},
}
self.assertIn("profile pc", mod.summary_line(payload))
self.assertIn("text pc", mod.summary_line(payload))
self.assertIn("req 11", mod.summary_line(payload))
def test_request_rows_sort_desc_and_keep_request_id(self) -> None:
@@ -57,6 +57,18 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
rows = mod.normalize_profile_rows(payload)
self.assertEqual([row["name"] for row in rows], ["alpha", "beta"])
def test_image_profile_rows_show_active_first(self) -> None:
mod = load_module()
payload = {
"image_profiles": [
{"name": "beta", "active": False, "summary": {"base_url": "https://images-b.example/v1", "auth_mode": "fixed_bearer", "auth_source": "env"}},
{"name": "alpha", "active": True, "summary": {"base_url": "https://images-a.example/v1", "auth_mode": "manual_bearer", "auth_source": "manual_file"}},
]
}
rows = mod.normalize_image_profile_rows(payload)
self.assertEqual([row["name"] for row in rows], ["alpha", "beta"])
self.assertEqual(rows[0]["base_url"], "https://images-a.example/v1")
def test_version_update_message_only_for_newer_versions(self) -> None:
mod = load_module()
self.assertIn("0.1.0 -> 0.1.1", mod.version_update_message("0.1.1", "0.1.0"))
@@ -395,7 +407,7 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
self.assertEqual(mod.format_duration_ms_as_seconds(1532), "1.5s")
self.assertEqual(mod.format_duration_ms_as_seconds(120000), "120s")
def test_profile_editor_payload_round_trip(self) -> None:
def test_text_profile_editor_payload_does_not_carry_image_fields(self) -> None:
mod = load_module()
row = {
"name": "pc",
@@ -424,22 +436,48 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
text = mod.profile_editor_document(row)
payload = mod.profile_payload_from_editor_text(text)
self.assertEqual(payload["name"], "pc")
self.assertEqual(payload["image_base_url"], "https://images.example/v1")
self.assertEqual(payload["image_auth_mode"], "manual_bearer")
self.assertEqual(payload["image_manual_secret_file"], "/run/secrets/images-token")
self.assertTrue(payload["image_manual_secret_configured"])
self.assertEqual(payload["image_manual_secret"], "")
self.assertNotIn("image_base_url", payload)
self.assertNotIn("image_base_url", text)
self.assertNotIn("test-image-profile-secret", text)
saved_payload = mod.profile_payload_from_row(row)
self.assertEqual(saved_payload["image_base_url"], "https://images.example/v1")
self.assertEqual(saved_payload["image_auth_mode"], "manual_bearer")
self.assertEqual(saved_payload["image_manual_secret_file"], "/run/secrets/images-token")
self.assertEqual(saved_payload["image_manual_secret"], "")
self.assertNotIn("image_base_url", saved_payload)
self.assertIn(
"stream disconnected before completion: Concurrency limit exceeded for account, please retry later",
payload["retryable_error_messages"],
)
def test_image_profile_editor_payload_round_trip(self) -> None:
mod = load_module()
row = {
"name": "images",
"base_url": "https://images.example/v1",
"auth_mode": "manual_bearer",
"auth_source": "manual_file",
"raw": {
"form": {
"base_url": "https://images.example/v1",
"auth_mode": "manual_bearer",
"manual_secret_file": "/run/secrets/images-token",
"manual_secret_configured": True,
"auth_json_key": "IMAGE_API_KEY",
}
},
}
text = mod.image_profile_editor_document(row)
payload = mod.image_profile_payload_from_editor_text(text)
self.assertEqual(payload["name"], "images")
self.assertEqual(payload["base_url"], "https://images.example/v1")
self.assertEqual(payload["auth_mode"], "manual_bearer")
self.assertEqual(payload["manual_secret_file"], "/run/secrets/images-token")
self.assertTrue(payload["manual_secret_configured"])
self.assertEqual(payload["manual_secret"], "")
self.assertNotIn("test-image-profile-secret", text)
saved_payload = mod.image_profile_payload_from_row(row)
self.assertEqual(saved_payload["base_url"], "https://images.example/v1")
self.assertEqual(saved_payload["auth_mode"], "manual_bearer")
self.assertEqual(saved_payload["manual_secret_file"], "/run/secrets/images-token")
self.assertEqual(saved_payload["manual_secret"], "")
def test_default_api_url_discovers_gateway_state(self) -> None:
mod = load_module()
with tempfile.TemporaryDirectory() as tmpdir: