-
Notifications
You must be signed in to change notification settings - Fork 1
Labels
awCreated by agentic workflowCreated by agentic workflowaw-dispatchedIssue has been dispatched to implementerIssue has been dispatched to implementer
Description
Problem
src/copilot_usage/report.py has three functions that all format a time duration into a human-readable string:
format_duration(ms: int)(line 64) — Takes milliseconds, returns e.g."6m 29s","1h 1m 1s"_format_elapsed_since(start: datetime)(line 94) — Computesnow - start, returns e.g."2h 15m"or"3m 42s"_format_detail_duration(start, end)(line 271) — Computesend - start, returns e.g."5m 30s"or"—"if either is None
All three contain the same hours/minutes/seconds decomposition and formatting logic. They differ only in input type and null handling.
Solution
- Create a single core helper:
def _format_timedelta(td: timedelta) -> str:
"""Format a timedelta to human-readable duration (e.g. '1h 5m 30s')."""
total_seconds = max(int(td.total_seconds()), 0)
hours, remainder = divmod(total_seconds, 3600)
minutes, seconds = divmod(remainder, 60)
parts: list[str] = []
if hours:
parts.append(f"{hours}h")
if minutes:
parts.append(f"{minutes}m")
if seconds or not parts:
parts.append(f"{seconds}s")
return " ".join(parts)- Rewrite the three functions to use it:
format_duration(ms: int)→_format_timedelta(timedelta(milliseconds=ms))_format_elapsed_since(start)→_format_timedelta(datetime.now(tz=UTC) - ensure_aware(start))_format_detail_duration(start, end)→ return"—"if None, else_format_timedelta(end - start)
format_durationis in__all__(public API) — keep its signature unchanged.
Tests
Existing tests for format_duration must continue to pass. Add a test for _format_timedelta directly to verify the core logic. Verify _format_elapsed_since and _format_detail_duration still produce the same outputs.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
awCreated by agentic workflowCreated by agentic workflowaw-dispatchedIssue has been dispatched to implementerIssue has been dispatched to implementer