fix: rerender wide mode request text
This commit is contained in:
+73
-32
@@ -436,6 +436,29 @@ def request_chunk_progress(row: dict[str, Any]) -> str:
|
||||
return f"{row.get('stream_chunk_count') or 0} / {format_bytes(row.get('response_bytes_received'))}"
|
||||
|
||||
|
||||
def request_row_cells(row: dict[str, Any], text_limits: dict[str, int] | None = None) -> tuple[Any, ...]:
|
||||
limits = text_limits or {}
|
||||
note_prefix = f"{row['upstream_attempt_count'] or 0}x "
|
||||
note_width = max(4, limits.get("note", 22) - len(note_prefix))
|
||||
return (
|
||||
str(row["seq"]),
|
||||
short_text(primary_request_id(row), limits.get("id", 18)) or "-",
|
||||
short_text(row["thread_id"], limits.get("thread", 18)) or "-",
|
||||
short_time(row["started_at"]),
|
||||
f"{status_symbol(row)} {row.get('status_code') or '-'}",
|
||||
short_text(row["path"], limits.get("path", 22)),
|
||||
short_text(row["model"] or row["requested_model"] or row["forwarded_model"], limits.get("model", 16)),
|
||||
row["reasoning_tokens"] if row["reasoning_tokens"] is not None else "-",
|
||||
short_text(request_usage_summary(row), limits.get("usage", 24)),
|
||||
format_bytes(row["response_bytes_received"]),
|
||||
request_chunk_progress(row),
|
||||
format_duration_ms_as_seconds(row["first_response_delay_ms"]),
|
||||
format_duration_ms_as_seconds(row["duration_ms"]),
|
||||
request_updated_elapsed(row),
|
||||
f"{note_prefix}{short_text(row['error'], note_width)}",
|
||||
)
|
||||
|
||||
|
||||
def status_kind(value: Any) -> str:
|
||||
text = str(value or "").strip().lower()
|
||||
if text in {"ok", "operational", "success"}:
|
||||
@@ -1160,20 +1183,20 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
||||
},
|
||||
"wide": {
|
||||
"seq": 7,
|
||||
"id": 20,
|
||||
"thread": 30,
|
||||
"id": 36,
|
||||
"thread": 36,
|
||||
"started": 19,
|
||||
"status": 7,
|
||||
"path": 34,
|
||||
"model": 18,
|
||||
"path": 40,
|
||||
"model": 24,
|
||||
"reasoning": 10,
|
||||
"usage": 52,
|
||||
"usage": 72,
|
||||
"resp": 12,
|
||||
"chunks": 16,
|
||||
"first": 8,
|
||||
"duration": 8,
|
||||
"updated": 8,
|
||||
"note": 34,
|
||||
"note": 48,
|
||||
},
|
||||
}
|
||||
self.request_usage_width = self.request_table_width_profiles[self.request_table_density]["usage"]
|
||||
@@ -1366,46 +1389,36 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
||||
self.render_logs()
|
||||
self.render_profiles()
|
||||
if self.current_view == "requests":
|
||||
if self.requests:
|
||||
self.render_detail(self.requests[0], kind="request")
|
||||
row = self._selected_request_row()
|
||||
if row:
|
||||
self.render_detail(row, kind="request")
|
||||
else:
|
||||
self.query_one("#detail", Static).update("no requests")
|
||||
elif self.current_view == "logs":
|
||||
if self.logs:
|
||||
self.render_detail(self.logs[0], kind="log")
|
||||
row = self._selected_log_row()
|
||||
if row:
|
||||
self.render_detail(row, kind="log")
|
||||
else:
|
||||
self.query_one("#detail", Static).update("no logs")
|
||||
elif self.current_view == "profiles":
|
||||
if self.profiles:
|
||||
self.render_detail(self.profiles[0], kind="profile")
|
||||
row = self._selected_profile_row()
|
||||
if row:
|
||||
self.render_detail(row, kind="profile")
|
||||
else:
|
||||
self.query_one("#detail", Static).update("no profiles")
|
||||
|
||||
def render_requests(self) -> None:
|
||||
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
|
||||
text_limits = self._request_text_limits(table)
|
||||
table.clear()
|
||||
self.request_by_key = {}
|
||||
for row in self.requests:
|
||||
key = f"{row['seq']}:{row['request_id']}"
|
||||
self.request_by_key[key] = row
|
||||
table.add_row(
|
||||
str(row["seq"]),
|
||||
short_text(primary_request_id(row), 18) or "-",
|
||||
short_text(row["thread_id"], 18) or "-",
|
||||
short_time(row["started_at"]),
|
||||
f"{status_symbol(row)} {row.get('status_code') or '-'}",
|
||||
short_text(row["path"], 22),
|
||||
short_text(row["model"] or row["requested_model"] or row["forwarded_model"], 16),
|
||||
row["reasoning_tokens"] if row["reasoning_tokens"] is not None else "-",
|
||||
short_text(request_usage_summary(row), 24),
|
||||
format_bytes(row["response_bytes_received"]),
|
||||
request_chunk_progress(row),
|
||||
format_duration_ms_as_seconds(row["first_response_delay_ms"]),
|
||||
format_duration_ms_as_seconds(row["duration_ms"]),
|
||||
request_updated_elapsed(row),
|
||||
f"{row['upstream_attempt_count'] or 0}x {short_text(row['error'], 18)}",
|
||||
key=key,
|
||||
)
|
||||
table.add_row(*request_row_cells(row, text_limits), key=key)
|
||||
if self.requests:
|
||||
self._select_table_row(table, min(selected_row_index, len(self.requests) - 1))
|
||||
|
||||
def render_logs(self) -> None:
|
||||
table = self.query_one("#logs_table", DataTable)
|
||||
@@ -1488,9 +1501,37 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
||||
return
|
||||
self.request_usage_width = max(18, min(80, width))
|
||||
column.width = self.request_usage_width
|
||||
table.refresh(layout=True)
|
||||
self._rerender_requests_after_layout_change()
|
||||
self._set_status(f"usage column width {self.request_usage_width}")
|
||||
|
||||
def _request_text_limits(self, table: DataTable) -> dict[str, int]:
|
||||
width_profile = self.request_table_width_profiles[self.request_table_density]
|
||||
limits = {
|
||||
"id": width_profile["id"],
|
||||
"thread": width_profile["thread"],
|
||||
"path": width_profile["path"],
|
||||
"model": width_profile["model"],
|
||||
"usage": self.request_usage_width,
|
||||
"note": width_profile["note"],
|
||||
}
|
||||
for name in ("id", "thread", "path", "model", "usage", "note"):
|
||||
key = self.request_table_column_keys.get(name)
|
||||
column = table.columns.get(key) if key is not None else None
|
||||
if column is None or not getattr(column, "width", 0):
|
||||
continue
|
||||
limits[name] = int(column.width)
|
||||
return limits
|
||||
|
||||
def _rerender_requests_after_layout_change(self) -> None:
|
||||
self.render_requests()
|
||||
if self.current_view not in {"overview", "requests"}:
|
||||
return
|
||||
row = self._selected_request_row()
|
||||
if row:
|
||||
self.render_detail(row, kind="request")
|
||||
else:
|
||||
self.query_one("#detail", Static).update("no requests")
|
||||
|
||||
def _apply_request_table_width_profile(self, density: str) -> None:
|
||||
table = self.query_one("#requests_table", DataTable)
|
||||
width_profile = self.request_table_width_profiles[density]
|
||||
@@ -1501,7 +1542,7 @@ def run_textual(api_url: str, status_url: str, refresh_seconds: int, timeout: in
|
||||
column.width = width_profile[name]
|
||||
self.request_table_density = density
|
||||
self.request_usage_width = width_profile["usage"]
|
||||
table.refresh(layout=True)
|
||||
self._rerender_requests_after_layout_change()
|
||||
self._set_status(f"request table mode {density}")
|
||||
|
||||
def action_toggle_request_table_density(self) -> None:
|
||||
|
||||
@@ -109,6 +109,40 @@ class CodexRetryGatewayTUITests(unittest.TestCase):
|
||||
}
|
||||
self.assertEqual(mod.request_usage_summary(row), "in 75 | out 40 | cached 25 (25%)")
|
||||
|
||||
def test_request_row_cells_expand_with_wider_limits(self) -> None:
|
||||
mod = load_module()
|
||||
row = {
|
||||
"seq": 1,
|
||||
"request_id": "req_abcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"response_id": "resp_abcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"thread_id": "thread_abcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"started_at": "2026-06-30T12:00:00Z",
|
||||
"status_code": 200,
|
||||
"path": "/v1/responses/this/is/a/very/long/path/for/testing/truncation",
|
||||
"model": "gpt-very-long-model-name-for-testing",
|
||||
"requested_model": "",
|
||||
"forwarded_model": "",
|
||||
"reasoning_tokens": 516,
|
||||
"input_tokens": 1200,
|
||||
"output_tokens": 340,
|
||||
"cached_tokens": 128,
|
||||
"response_bytes_received": 363800,
|
||||
"response_stream": True,
|
||||
"stream_chunk_count": 587,
|
||||
"first_response_delay_ms": 1500,
|
||||
"duration_ms": 1542200,
|
||||
"upstream_attempt_count": 2,
|
||||
"error": "Selected model is at capacity. Please try a different model.",
|
||||
"finished_at": "2026-06-30T12:25:00Z",
|
||||
}
|
||||
compact = mod.request_row_cells(row, {"id": 18, "thread": 18, "path": 22, "model": 16, "usage": 24, "note": 22})
|
||||
wide = mod.request_row_cells(row, {"id": 36, "thread": 36, "path": 40, "model": 24, "usage": 72, "note": 48})
|
||||
self.assertLess(len(compact[1]), len(wide[1]))
|
||||
self.assertLess(len(compact[2]), len(wide[2]))
|
||||
self.assertLess(len(compact[5]), len(wide[5]))
|
||||
self.assertLess(len(compact[8]), len(wide[8]))
|
||||
self.assertLess(len(compact[14]), len(wide[14]))
|
||||
|
||||
def test_request_rows_read_usage_from_nested_usage_object(self) -> None:
|
||||
mod = load_module()
|
||||
payload = {
|
||||
|
||||
Reference in New Issue
Block a user