fix: derive streaming status from retry firsts

This commit is contained in:
2026-07-10 07:26:15 +08:00
parent ccecee2a44
commit f67cbbda65
4 changed files with 50 additions and 9 deletions
+33 -6
View File
@@ -23,7 +23,7 @@ from typing import Any
APP_NAME = "codex-retry-gateway-tui"
FALLBACK_VERSION = "0.1.7"
FALLBACK_VERSION = "0.1.8"
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
@@ -870,6 +870,7 @@ def normalize_request_retry_firsts(value: Any) -> list[dict[str, Any]]:
{
"round": parse_int_value(item.get("round")),
"slot": parse_int_value(item.get("slot")),
"first_response_at": item.get("first_response_at"),
"first_delay_ms": item.get("first_response_delay_ms", item.get("first_delay_ms", item.get("first_ms"))),
"outcome": str(item.get("outcome") or "").strip(),
"status_code": item.get("status_code", item.get("upstream_status_code", item.get("status"))),
@@ -1339,13 +1340,38 @@ def request_match_score(row: dict[str, Any], needle: str) -> bool:
return needle in haystack
def request_retry_first_received_at(row: dict[str, Any]) -> Any:
latest_value = None
latest_at = None
for first in row.get("reasoning_retry_current_firsts") or []:
if not isinstance(first, dict):
continue
value = first.get("first_response_at")
parsed = parse_datetime(value)
if parsed and (latest_at is None or parsed > latest_at):
latest_value = value
latest_at = parsed
return latest_value
def request_has_received_first(row: dict[str, Any]) -> bool:
if parse_datetime(row.get("first_response_at")):
return True
for first in row.get("reasoning_retry_current_firsts") or []:
if not isinstance(first, dict):
continue
if parse_datetime(first.get("first_response_at")) or parse_int_value(first.get("first_delay_ms")) is not None:
return True
return False
def request_lifecycle_label(row: dict[str, Any]) -> str:
state = str(row.get("lifecycle_state") or "").strip().lower()
if request_is_discarded(row):
return "discarded"
if state in {"finish", "finished", "complete", "completed"} or parse_datetime(row.get("finished_at")):
return "finished"
if state in {"receive_first", "streaming"} or parse_datetime(row.get("first_response_at")):
if state in {"receive_first", "streaming"} or request_has_received_first(row):
return "streaming"
return "waiting"
@@ -1368,11 +1394,12 @@ def request_is_discarded(row: dict[str, Any]) -> bool:
def request_activity_at(row: dict[str, Any]) -> Any:
for key in ("last_activity_at", "first_response_at", "started_at"):
value = row.get(key)
if parse_datetime(value):
return value
candidates = [row.get("last_activity_at"), row.get("first_response_at"), request_retry_first_received_at(row), row.get("started_at")]
parsed_candidates = [(parse_datetime(value), value) for value in candidates]
valid_candidates = [(parsed, value) for parsed, value in parsed_candidates if parsed]
if not valid_candidates:
return None
return max(valid_candidates, key=lambda item: item[0])[1]
def request_activity_age_seconds(row: dict[str, Any], now: dt.datetime | None = None) -> float | None:
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "codex-retry-gateway-tui"
version = "0.1.7"
version = "0.1.8"
description = "Terminal UI for codex-retry-gateway monitoring and control"
readme = "README.md"
requires-python = ">=3.11"
+14
View File
@@ -143,6 +143,18 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
"first_response_at": "2026-07-10T11:59:55Z",
"last_activity_at": "2026-07-10T11:59:55Z",
}
retry_streaming = {
"lifecycle_state": "sent",
"started_at": "2026-07-10T11:59:00Z",
"reasoning_retry_current_firsts": [
{
"round": 1,
"slot": 1,
"first_response_at": "2026-07-10T11:59:58Z",
"first_delay_ms": 2200,
}
],
}
complete = {"lifecycle_state": "finish", "status_code": 200}
discarded = {
"lifecycle_state": "finish",
@@ -161,6 +173,8 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
self.assertEqual(mod.request_status_label(waiting, now), "waiting")
self.assertEqual(mod.request_status_label(streaming, now), "streaming")
self.assertEqual(mod.request_status_label(retry_streaming, now), "streaming")
self.assertEqual(mod.request_activity_at(retry_streaming), "2026-07-10T11:59:58Z")
self.assertEqual(mod.request_status_label(complete, now), "HTTP 200")
self.assertEqual(mod.request_status_label(discarded, now), "discarded")
self.assertEqual(mod.request_status_label(slow_waiting, now), "waiting 30.0s")
Generated
+1 -1
View File
@@ -4,7 +4,7 @@ requires-python = ">=3.11"
[[package]]
name = "codex-retry-gateway-tui"
version = "0.1.7"
version = "0.1.8"
source = { editable = "." }
dependencies = [
{ name = "textual" },