feat: improve retry first column controls
This commit is contained in:
+121
-56
@@ -81,6 +81,51 @@ REQUEST_TABLE_COLUMN_KEY_SET = set(REQUEST_TABLE_COLUMN_KEYS)
|
|||||||
REQUEST_TABLE_CELL_INDEX = {key: index for index, key in enumerate(REQUEST_TABLE_COLUMN_KEYS)}
|
REQUEST_TABLE_CELL_INDEX = {key: index for index, key in enumerate(REQUEST_TABLE_COLUMN_KEYS)}
|
||||||
DEFAULT_REQUEST_TABLE_VISIBLE_COLUMNS = REQUEST_TABLE_COLUMN_KEYS
|
DEFAULT_REQUEST_TABLE_VISIBLE_COLUMNS = REQUEST_TABLE_COLUMN_KEYS
|
||||||
DEFAULT_REQUEST_TABLE_SORT_COLUMN = "seq"
|
DEFAULT_REQUEST_TABLE_SORT_COLUMN = "seq"
|
||||||
|
REQUEST_TABLE_WIDTH_PROFILES = {
|
||||||
|
"compact": {
|
||||||
|
"seq": 7,
|
||||||
|
"req_id": 18,
|
||||||
|
"resp_id": 18,
|
||||||
|
"thread": 18,
|
||||||
|
"started": 19,
|
||||||
|
"status": 7,
|
||||||
|
"path": 22,
|
||||||
|
"model": 16,
|
||||||
|
"effort": 8,
|
||||||
|
"reasoning": 8,
|
||||||
|
"token_col": 8,
|
||||||
|
"req": 10,
|
||||||
|
"resp": 10,
|
||||||
|
"chunks": 14,
|
||||||
|
"first": 12,
|
||||||
|
"duration": 8,
|
||||||
|
"updated": 8,
|
||||||
|
"note": 22,
|
||||||
|
"round": 10,
|
||||||
|
},
|
||||||
|
"wide": {
|
||||||
|
"seq": 7,
|
||||||
|
"req_id": 24,
|
||||||
|
"resp_id": 24,
|
||||||
|
"thread": 36,
|
||||||
|
"started": 19,
|
||||||
|
"status": 7,
|
||||||
|
"path": 40,
|
||||||
|
"model": 24,
|
||||||
|
"effort": 8,
|
||||||
|
"reasoning": 8,
|
||||||
|
"token_col": 8,
|
||||||
|
"req": 12,
|
||||||
|
"resp": 12,
|
||||||
|
"chunks": 16,
|
||||||
|
"first": 14,
|
||||||
|
"duration": 8,
|
||||||
|
"updated": 8,
|
||||||
|
"note": 48,
|
||||||
|
"round": 10,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
REQUEST_TABLE_MIN_COLUMN_WIDTH = 4
|
||||||
REQUEST_TABLE_COLUMN_ALIASES = {
|
REQUEST_TABLE_COLUMN_ALIASES = {
|
||||||
"seq": ("seq",),
|
"seq": ("seq",),
|
||||||
"req_id": ("req id", "request id", "request_id"),
|
"req_id": ("req id", "request id", "request_id"),
|
||||||
@@ -295,6 +340,29 @@ def request_table_hidden_columns(value: Any, columns: list[str]) -> list[str]:
|
|||||||
return hidden
|
return hidden
|
||||||
|
|
||||||
|
|
||||||
|
def request_table_column_width_value(value: Any) -> int | None:
|
||||||
|
try:
|
||||||
|
width = int(str(value or "").strip())
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
if width <= 0:
|
||||||
|
return None
|
||||||
|
return max(REQUEST_TABLE_MIN_COLUMN_WIDTH, width)
|
||||||
|
|
||||||
|
|
||||||
|
def request_table_width_overrides(value: Any) -> dict[str, int]:
|
||||||
|
requested = value if isinstance(value, dict) else {}
|
||||||
|
overrides: dict[str, int] = {}
|
||||||
|
for raw_key, raw_width in requested.items():
|
||||||
|
width = request_table_column_width_value(raw_width)
|
||||||
|
if width is None:
|
||||||
|
continue
|
||||||
|
for column_key in request_table_column_keys(raw_key):
|
||||||
|
if column_key:
|
||||||
|
overrides[column_key] = width
|
||||||
|
return overrides
|
||||||
|
|
||||||
|
|
||||||
def normalize_request_table_sort_column(value: Any) -> str:
|
def normalize_request_table_sort_column(value: Any) -> str:
|
||||||
column_key = str(value or "").strip()
|
column_key = str(value or "").strip()
|
||||||
if column_key in REQUEST_TABLE_COLUMN_KEY_SET:
|
if column_key in REQUEST_TABLE_COLUMN_KEY_SET:
|
||||||
@@ -320,9 +388,11 @@ def normalize_request_table_preferences(data: Any) -> dict[str, Any]:
|
|||||||
hidden_columns = request_table_hidden_columns(source.get("hidden_columns"), columns)
|
hidden_columns = request_table_hidden_columns(source.get("hidden_columns"), columns)
|
||||||
if len(hidden_columns) >= len(columns) and columns:
|
if len(hidden_columns) >= len(columns) and columns:
|
||||||
hidden_columns = [column_key for column_key in hidden_columns if column_key != columns[0]]
|
hidden_columns = [column_key for column_key in hidden_columns if column_key != columns[0]]
|
||||||
|
width_overrides = request_table_width_overrides(source.get("widths"))
|
||||||
return {
|
return {
|
||||||
"columns": columns,
|
"columns": columns,
|
||||||
"hidden_columns": hidden_columns,
|
"hidden_columns": hidden_columns,
|
||||||
|
"widths": {column_key: width for column_key, width in width_overrides.items() if column_key in columns},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -338,6 +408,7 @@ def request_table_visible_columns(preferences: dict[str, Any]) -> list[str]:
|
|||||||
def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
||||||
columns = []
|
columns = []
|
||||||
hidden_columns = []
|
hidden_columns = []
|
||||||
|
width_overrides: dict[str, int] = {}
|
||||||
seen: set[str] = set()
|
seen: set[str] = set()
|
||||||
for line_number, raw_line in enumerate(text.splitlines(), start=1):
|
for line_number, raw_line in enumerate(text.splitlines(), start=1):
|
||||||
stripped = raw_line.strip()
|
stripped = raw_line.strip()
|
||||||
@@ -350,6 +421,11 @@ def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
|||||||
token = token[1:].strip()
|
token = token[1:].strip()
|
||||||
if not token:
|
if not token:
|
||||||
continue
|
continue
|
||||||
|
width = None
|
||||||
|
width_match = re.match(r"^(.*?)(?:\s+(\d+))?$", token)
|
||||||
|
if width_match:
|
||||||
|
token = (width_match.group(1) or "").strip()
|
||||||
|
width = request_table_column_width_value(width_match.group(2))
|
||||||
column_keys = request_table_column_keys(token)
|
column_keys = request_table_column_keys(token)
|
||||||
if not column_keys:
|
if not column_keys:
|
||||||
if hidden:
|
if hidden:
|
||||||
@@ -362,6 +438,8 @@ def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
|||||||
columns.append(column_key)
|
columns.append(column_key)
|
||||||
if hidden:
|
if hidden:
|
||||||
hidden_columns.append(column_key)
|
hidden_columns.append(column_key)
|
||||||
|
if width is not None:
|
||||||
|
width_overrides[column_key] = width
|
||||||
if not columns:
|
if not columns:
|
||||||
raise ValueError("no request columns found in editor document")
|
raise ValueError("no request columns found in editor document")
|
||||||
missing = [column_key for column_key in REQUEST_TABLE_COLUMN_KEYS if column_key not in seen]
|
missing = [column_key for column_key in REQUEST_TABLE_COLUMN_KEYS if column_key not in seen]
|
||||||
@@ -369,6 +447,7 @@ def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
|||||||
{
|
{
|
||||||
"columns": columns + missing,
|
"columns": columns + missing,
|
||||||
"hidden_columns": hidden_columns + missing,
|
"hidden_columns": hidden_columns + missing,
|
||||||
|
"widths": width_overrides,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -376,17 +455,20 @@ def request_table_preferences_from_text(text: str) -> dict[str, Any]:
|
|||||||
def request_table_preferences_document(preferences: dict[str, Any]) -> str:
|
def request_table_preferences_document(preferences: dict[str, Any]) -> str:
|
||||||
normalized = normalize_request_table_preferences(preferences)
|
normalized = normalize_request_table_preferences(preferences)
|
||||||
hidden = set(normalized["hidden_columns"])
|
hidden = set(normalized["hidden_columns"])
|
||||||
|
widths = normalized["widths"]
|
||||||
lines = [
|
lines = [
|
||||||
"# Request table columns.",
|
"# Request table columns.",
|
||||||
"# One column key per line.",
|
"# One column key per line.",
|
||||||
"# Prefix with # to hide a column.",
|
"# Prefix with # to hide a column.",
|
||||||
|
"# Optional: append an integer width, e.g. `first 14` or `in 10`.",
|
||||||
"# Move lines up or down to change display order.",
|
"# Move lines up or down to change display order.",
|
||||||
"# Common keys: in, out, cache, req_id, resp_id, req_bytes, resp_bytes, round.",
|
"# Common keys: in, out, cache, req_id, resp_id, req_bytes, resp_bytes, round.",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
for column_key in normalized["columns"]:
|
for column_key in normalized["columns"]:
|
||||||
prefix = "# " if column_key in hidden else ""
|
prefix = "# " if column_key in hidden else ""
|
||||||
lines.append(f"{prefix}{column_key}")
|
width_suffix = f" {widths[column_key]}" if column_key in widths else ""
|
||||||
|
lines.append(f"{prefix}{column_key}{width_suffix}")
|
||||||
return "\n".join(lines).rstrip() + "\n"
|
return "\n".join(lines).rstrip() + "\n"
|
||||||
|
|
||||||
|
|
||||||
@@ -769,6 +851,7 @@ def normalize_request_retry_firsts(value: Any) -> list[dict[str, Any]]:
|
|||||||
continue
|
continue
|
||||||
firsts.append(
|
firsts.append(
|
||||||
{
|
{
|
||||||
|
"round": parse_int_value(item.get("round")),
|
||||||
"slot": parse_int_value(item.get("slot")),
|
"slot": parse_int_value(item.get("slot")),
|
||||||
"first_delay_ms": item.get("first_response_delay_ms", item.get("first_delay_ms", item.get("first_ms"))),
|
"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(),
|
"outcome": str(item.get("outcome") or "").strip(),
|
||||||
@@ -781,6 +864,20 @@ def normalize_request_retry_firsts(value: Any) -> list[dict[str, Any]]:
|
|||||||
return firsts
|
return firsts
|
||||||
|
|
||||||
|
|
||||||
|
def request_retry_first_label(first: dict[str, Any], fallback_round: Any = None) -> str:
|
||||||
|
round_number = parse_int_value(first.get("round"))
|
||||||
|
if round_number is None:
|
||||||
|
round_number = parse_int_value(fallback_round)
|
||||||
|
slot = parse_int_value(first.get("slot"))
|
||||||
|
if round_number is not None:
|
||||||
|
if slot is not None and slot > 1:
|
||||||
|
return f"{round_number}-{slot}"
|
||||||
|
return str(round_number)
|
||||||
|
if slot is not None:
|
||||||
|
return str(slot)
|
||||||
|
return "?"
|
||||||
|
|
||||||
|
|
||||||
def request_retry_round_text(row: dict[str, Any]) -> str:
|
def request_retry_round_text(row: dict[str, Any]) -> str:
|
||||||
round_number = parse_int_value(row.get("reasoning_retry_current_round"))
|
round_number = parse_int_value(row.get("reasoning_retry_current_round"))
|
||||||
width = parse_int_value(row.get("reasoning_retry_current_width"))
|
width = parse_int_value(row.get("reasoning_retry_current_width"))
|
||||||
@@ -793,8 +890,11 @@ def request_retry_round_text(row: dict[str, Any]) -> str:
|
|||||||
return f"{round_number}({max(0, width)})"
|
return f"{round_number}({max(0, width)})"
|
||||||
|
|
||||||
|
|
||||||
def request_retry_first_summary(first: dict[str, Any]) -> str:
|
def request_retry_first_summary(first: dict[str, Any], fallback_round: Any = None) -> str:
|
||||||
bits = []
|
bits = []
|
||||||
|
round_label = request_retry_first_label(first, fallback_round)
|
||||||
|
if round_label != "?":
|
||||||
|
bits.append(f"round {round_label}")
|
||||||
slot = parse_int_value(first.get("slot"))
|
slot = parse_int_value(first.get("slot"))
|
||||||
if slot is not None:
|
if slot is not None:
|
||||||
bits.append(f"slot {slot}")
|
bits.append(f"slot {slot}")
|
||||||
@@ -823,10 +923,11 @@ def request_retry_first_summary(first: dict[str, Any]) -> str:
|
|||||||
|
|
||||||
def request_retry_wave_summary(row: dict[str, Any]) -> str:
|
def request_retry_wave_summary(row: dict[str, Any]) -> str:
|
||||||
summaries = []
|
summaries = []
|
||||||
|
fallback_round = row.get("reasoning_retry_current_round")
|
||||||
for first in row.get("reasoning_retry_current_firsts") or []:
|
for first in row.get("reasoning_retry_current_firsts") or []:
|
||||||
if not isinstance(first, dict):
|
if not isinstance(first, dict):
|
||||||
continue
|
continue
|
||||||
summary = request_retry_first_summary(first)
|
summary = request_retry_first_summary(first, fallback_round)
|
||||||
if summary:
|
if summary:
|
||||||
summaries.append(summary)
|
summaries.append(summary)
|
||||||
return "; ".join(summaries)
|
return "; ".join(summaries)
|
||||||
@@ -838,10 +939,7 @@ def request_retry_firsts_compact_text(row: dict[str, Any]) -> str:
|
|||||||
if not isinstance(first, dict):
|
if not isinstance(first, dict):
|
||||||
continue
|
continue
|
||||||
delay = format_duration_ms_as_seconds(first.get("first_delay_ms"))
|
delay = format_duration_ms_as_seconds(first.get("first_delay_ms"))
|
||||||
if delay == "-":
|
parts.append(delay if delay != "-" else "?")
|
||||||
delay = str(first.get("outcome") or "-").strip() or "-"
|
|
||||||
slot = parse_int_value(first.get("slot"))
|
|
||||||
parts.append(f"{slot if slot is not None else '?'}:{delay}")
|
|
||||||
return " ".join(parts)
|
return " ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
@@ -1744,48 +1842,7 @@ def run_textual(
|
|||||||
self.request_table_preferences = load_request_table_preferences()
|
self.request_table_preferences = load_request_table_preferences()
|
||||||
self.request_table_density = "compact"
|
self.request_table_density = "compact"
|
||||||
self.request_table_width_profiles = {
|
self.request_table_width_profiles = {
|
||||||
"compact": {
|
density: dict(widths) for density, widths in REQUEST_TABLE_WIDTH_PROFILES.items()
|
||||||
"seq": 7,
|
|
||||||
"req_id": 18,
|
|
||||||
"resp_id": 18,
|
|
||||||
"thread": 18,
|
|
||||||
"started": 19,
|
|
||||||
"status": 7,
|
|
||||||
"path": 22,
|
|
||||||
"model": 16,
|
|
||||||
"effort": 8,
|
|
||||||
"reasoning": 8,
|
|
||||||
"token_col": 8,
|
|
||||||
"req": 10,
|
|
||||||
"resp": 10,
|
|
||||||
"chunks": 14,
|
|
||||||
"first": 8,
|
|
||||||
"duration": 8,
|
|
||||||
"updated": 8,
|
|
||||||
"note": 22,
|
|
||||||
"round": 10,
|
|
||||||
},
|
|
||||||
"wide": {
|
|
||||||
"seq": 7,
|
|
||||||
"req_id": 24,
|
|
||||||
"resp_id": 24,
|
|
||||||
"thread": 36,
|
|
||||||
"started": 19,
|
|
||||||
"status": 7,
|
|
||||||
"path": 40,
|
|
||||||
"model": 24,
|
|
||||||
"effort": 8,
|
|
||||||
"reasoning": 8,
|
|
||||||
"token_col": 8,
|
|
||||||
"req": 12,
|
|
||||||
"resp": 12,
|
|
||||||
"chunks": 16,
|
|
||||||
"first": 8,
|
|
||||||
"duration": 8,
|
|
||||||
"updated": 8,
|
|
||||||
"note": 48,
|
|
||||||
"round": 10,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
@@ -1875,6 +1932,16 @@ def run_textual(
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _request_table_column_width(self, column_key: str, density: str | None = None) -> int:
|
||||||
|
normalized = normalize_request_table_preferences(self.request_table_preferences)
|
||||||
|
override = request_table_column_width_value(normalized.get("widths", {}).get(column_key))
|
||||||
|
if override is not None:
|
||||||
|
return override
|
||||||
|
active_density = density or self.request_table_density
|
||||||
|
width_profile = self.request_table_width_profiles[active_density]
|
||||||
|
column = REQUEST_TABLE_COLUMN_BY_KEY[column_key]
|
||||||
|
return width_profile[column["width_key"]]
|
||||||
|
|
||||||
def _request_row_key(self, row: dict[str, Any]) -> str:
|
def _request_row_key(self, row: dict[str, Any]) -> str:
|
||||||
return f"{row['seq']}:{row['request_id']}"
|
return f"{row['seq']}:{row['request_id']}"
|
||||||
|
|
||||||
@@ -1897,12 +1964,11 @@ def run_textual(
|
|||||||
table = self.query_one("#requests_table", DataTable)
|
table = self.query_one("#requests_table", DataTable)
|
||||||
selected_row_index = table.cursor_row if table.cursor_row is not None and table.cursor_row >= 0 else 0
|
selected_row_index = table.cursor_row if table.cursor_row is not None and table.cursor_row >= 0 else 0
|
||||||
selected_row_key = self._selected_request_key()
|
selected_row_key = self._selected_request_key()
|
||||||
width_profile = self.request_table_width_profiles[self.request_table_density]
|
|
||||||
table.clear(columns=True)
|
table.clear(columns=True)
|
||||||
self.request_table_column_keys = {}
|
self.request_table_column_keys = {}
|
||||||
for column_key in self._visible_request_column_keys():
|
for column_key in self._visible_request_column_keys():
|
||||||
column = REQUEST_TABLE_COLUMN_BY_KEY[column_key]
|
column = REQUEST_TABLE_COLUMN_BY_KEY[column_key]
|
||||||
width = width_profile[column["width_key"]]
|
width = self._request_table_column_width(column_key)
|
||||||
self.request_table_column_keys[column_key] = table.add_column(
|
self.request_table_column_keys[column_key] = table.add_column(
|
||||||
column["label"],
|
column["label"],
|
||||||
width=width,
|
width=width,
|
||||||
@@ -2140,10 +2206,11 @@ def run_textual(
|
|||||||
"path": width_profile["path"],
|
"path": width_profile["path"],
|
||||||
"model": width_profile["model"],
|
"model": width_profile["model"],
|
||||||
"effort": width_profile["effort"],
|
"effort": width_profile["effort"],
|
||||||
|
"first": width_profile["first"],
|
||||||
"note": width_profile["note"],
|
"note": width_profile["note"],
|
||||||
"round": width_profile["round"],
|
"round": width_profile["round"],
|
||||||
}
|
}
|
||||||
for name in ("req_id", "resp_id", "thread", "path", "model", "effort", "note", "round"):
|
for name in ("req_id", "resp_id", "thread", "path", "model", "effort", "first", "note", "round"):
|
||||||
key = self.request_table_column_keys.get(name)
|
key = self.request_table_column_keys.get(name)
|
||||||
column = table.columns.get(key) if key is not None else None
|
column = table.columns.get(key) if key is not None else None
|
||||||
if column is None or not getattr(column, "width", 0):
|
if column is None or not getattr(column, "width", 0):
|
||||||
@@ -2164,13 +2231,11 @@ def run_textual(
|
|||||||
|
|
||||||
def _apply_request_table_width_profile(self, density: str) -> None:
|
def _apply_request_table_width_profile(self, density: str) -> None:
|
||||||
table = self.query_one("#requests_table", DataTable)
|
table = self.query_one("#requests_table", DataTable)
|
||||||
width_profile = self.request_table_width_profiles[density]
|
|
||||||
for name, key in self.request_table_column_keys.items():
|
for name, key in self.request_table_column_keys.items():
|
||||||
column = table.columns.get(key)
|
column = table.columns.get(key)
|
||||||
width_key = REQUEST_TABLE_COLUMN_BY_KEY.get(name, {}).get("width_key", name)
|
if column is None:
|
||||||
if column is None or width_key not in width_profile:
|
|
||||||
continue
|
continue
|
||||||
column.width = width_profile[width_key]
|
column.width = self._request_table_column_width(name, density)
|
||||||
self.request_table_density = density
|
self.request_table_density = density
|
||||||
self._rerender_requests_after_layout_change()
|
self._rerender_requests_after_layout_change()
|
||||||
self._set_status(f"request table mode {density}")
|
self._set_status(f"request table mode {density}")
|
||||||
|
|||||||
+11
-5
@@ -230,6 +230,7 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
"reasoning_retry_current_width": 2,
|
"reasoning_retry_current_width": 2,
|
||||||
"reasoning_retry_current_firsts": [
|
"reasoning_retry_current_firsts": [
|
||||||
{
|
{
|
||||||
|
"round": 3,
|
||||||
"slot": 1,
|
"slot": 1,
|
||||||
"first_response_delay_ms": 1200,
|
"first_response_delay_ms": 1200,
|
||||||
"outcome": "ok",
|
"outcome": "ok",
|
||||||
@@ -238,6 +239,7 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
"reasoning_tokens": 516,
|
"reasoning_tokens": 516,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"round": 3,
|
||||||
"slot": 2,
|
"slot": 2,
|
||||||
"first_delay_ms": 1800,
|
"first_delay_ms": 1800,
|
||||||
"outcome": "retry",
|
"outcome": "retry",
|
||||||
@@ -254,10 +256,11 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
self.assertEqual(row["reasoning_retry_current_width"], 2)
|
self.assertEqual(row["reasoning_retry_current_width"], 2)
|
||||||
self.assertEqual(len(row["reasoning_retry_current_firsts"]), 2)
|
self.assertEqual(len(row["reasoning_retry_current_firsts"]), 2)
|
||||||
self.assertEqual(mod.request_retry_round_text(row), "3(2)")
|
self.assertEqual(mod.request_retry_round_text(row), "3(2)")
|
||||||
self.assertIn("1:1.2s", mod.request_first_text(row))
|
self.assertEqual(mod.request_first_text(row), "1.2s 1.8s")
|
||||||
self.assertIn("slot 1", mod.request_retry_wave_summary(row))
|
self.assertIn("round 3 slot 1", mod.request_retry_wave_summary(row))
|
||||||
self.assertIn("retry round 3(2)", mod.render_request_detail(row))
|
self.assertIn("retry round 3(2)", mod.render_request_detail(row))
|
||||||
self.assertIn("current wave slot 1 first 1.2s", mod.render_request_detail(row))
|
self.assertIn("first 1.2s 1.8s", mod.render_request_detail(row))
|
||||||
|
self.assertIn("current wave round 3 slot 1 first 1.2s", mod.render_request_detail(row))
|
||||||
self.assertEqual(mod.request_row_cells(row)[20], "3(2)")
|
self.assertEqual(mod.request_row_cells(row)[20], "3(2)")
|
||||||
|
|
||||||
def test_request_table_preferences_round_trip(self) -> None:
|
def test_request_table_preferences_round_trip(self) -> None:
|
||||||
@@ -273,12 +276,14 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
{
|
{
|
||||||
"columns": ["round", "seq", "status", "unknown"],
|
"columns": ["round", "seq", "status", "unknown"],
|
||||||
"hidden_columns": ["status", "unknown"],
|
"hidden_columns": ["status", "unknown"],
|
||||||
|
"widths": {"round": 14, "status": 9, "unknown": 99},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.assertEqual(saved_path, prefs_path)
|
self.assertEqual(saved_path, prefs_path)
|
||||||
loaded = mod.load_request_table_preferences()
|
loaded = mod.load_request_table_preferences()
|
||||||
self.assertEqual(loaded["columns"][:3], ["round", "seq", "status"])
|
self.assertEqual(loaded["columns"][:3], ["round", "seq", "status"])
|
||||||
self.assertEqual(loaded["hidden_columns"], ["status"])
|
self.assertEqual(loaded["hidden_columns"], ["status"])
|
||||||
|
self.assertEqual(loaded["widths"], {"round": 14, "status": 9})
|
||||||
|
|
||||||
def test_request_table_preferences_from_text_hides_and_reorders_columns(self) -> None:
|
def test_request_table_preferences_from_text_hides_and_reorders_columns(self) -> None:
|
||||||
mod = load_module()
|
mod = load_module()
|
||||||
@@ -286,9 +291,9 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
"\n".join(
|
"\n".join(
|
||||||
[
|
[
|
||||||
"# comment",
|
"# comment",
|
||||||
"thread",
|
"thread 24",
|
||||||
"seq",
|
"seq",
|
||||||
"# cache",
|
"# cache 9",
|
||||||
"in",
|
"in",
|
||||||
"out",
|
"out",
|
||||||
"",
|
"",
|
||||||
@@ -297,6 +302,7 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(prefs["columns"][:6], ["thread", "seq", "cache", "in", "out", "req_id"])
|
self.assertEqual(prefs["columns"][:6], ["thread", "seq", "cache", "in", "out", "req_id"])
|
||||||
self.assertIn("cache", prefs["hidden_columns"])
|
self.assertIn("cache", prefs["hidden_columns"])
|
||||||
|
self.assertEqual(prefs["widths"], {"thread": 24, "cache": 9})
|
||||||
|
|
||||||
def test_request_table_preferences_expand_legacy_usage_column(self) -> None:
|
def test_request_table_preferences_expand_legacy_usage_column(self) -> None:
|
||||||
mod = load_module()
|
mod = load_module()
|
||||||
|
|||||||
Reference in New Issue
Block a user