Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/copilot_usage/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,11 @@ def _start_observer(
treat a ``None`` return as "auto-refresh unavailable" and continue
without it.
"""
from watchdog.observers import Observer # type: ignore[import-untyped]
from watchdog.observers import Observer

handler: _FileChangeEventHandler = _FileChangeHandler(change_event)
observer = Observer()
observer.schedule(handler, str(session_path), recursive=True) # type: ignore[arg-type]
observer.schedule(handler, str(session_path), recursive=True) # pyright: ignore[reportArgumentType]
observer.daemon = True
try:
observer.start()
Expand Down
2 changes: 1 addition & 1 deletion src/copilot_usage/logging_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ def _emoji_patcher(record: _PatcherRecord) -> None:
def setup_logging() -> None:
"""Configure loguru for CLI use: stderr only, WARNING level."""
logger.remove()
logger.configure(patcher=_emoji_patcher) # type: ignore[arg-type] # TypedDict value invariance: _PatcherRecord is a structural subset of loguru.Record
logger.configure(patcher=_emoji_patcher) # pyright: ignore[reportArgumentType] # TypedDict value invariance: _PatcherRecord is a structural subset of loguru.Record
logger.add(sys.stderr, format=CONSOLE_FORMAT, level="WARNING", colorize=True)
5 changes: 0 additions & 5 deletions src/copilot_usage/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,6 @@ class GenericEventData(BaseModel, extra="allow"):
"""Catch‐all payload for event types not yet modeled explicitly."""


# ---------------------------------------------------------------------------
# Typed event helpers
# ---------------------------------------------------------------------------


# ---------------------------------------------------------------------------
# Event envelope
# ---------------------------------------------------------------------------
Expand Down
31 changes: 31 additions & 0 deletions tests/copilot_usage/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3006,6 +3006,37 @@ def test_shutdown_event_nonempty_shutdown_type_shown_in_detail(self) -> None:
)
assert _build_event_details(ev) == "type=normal"

def test_tool_execution_with_model_field(self) -> None:
"""TOOL_EXECUTION_COMPLETE with model → detail string includes model=<name>."""
ev = _make_event(
EventType.TOOL_EXECUTION_COMPLETE,
data={
"toolCallId": "t1",
"success": True,
"model": "claude-sonnet-4",
"toolTelemetry": {"properties": {"tool_name": "bash"}},
},
)
details = _build_event_details(ev)
assert "model=claude-sonnet-4" in details
assert "bash" in details
assert "✓" in details

def test_tool_execution_with_empty_model_string(self) -> None:
"""TOOL_EXECUTION_COMPLETE with model='' → model not shown in details."""
ev = _make_event(
EventType.TOOL_EXECUTION_COMPLETE,
data={
"toolCallId": "t1",
"success": True,
"model": "",
"toolTelemetry": {"properties": {"tool_name": "bash"}},
},
)
details = _build_event_details(ev)
assert "model=" not in details
assert "✓" in details


class TestRenderShutdownCyclesEdgeCases:
"""Test _render_shutdown_cycles with edge-case summaries."""
Expand Down
12 changes: 8 additions & 4 deletions tests/test_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
def test_all_names_importable(module_name: str) -> None:
"""Every name listed in a module's ``__all__`` must be importable at runtime."""
mod = importlib.import_module(module_name)
dunder_all: list[str] | None = getattr(mod, "__all__", None) # noqa: B009
mod_vars = vars(mod)
dunder_all: list[str] | None = mod_vars.get("__all__")
assert dunder_all is not None, f"{module_name} is missing __all__"
for name in dunder_all:
assert hasattr(mod, name), ( # noqa: B009
assert name in mod_vars, (
f"{module_name}.__all__ lists {name!r}, but it is not defined in the module"
)

Expand Down Expand Up @@ -64,10 +65,13 @@ def test_parse_data_and_event_data_removed_from_public_api() -> None:

dunder_all = models_mod.__all__
assert "EventData" not in dunder_all, "EventData must not be in models.__all__"
assert not hasattr(models_mod, "EventData"), ( # noqa: B009
models_vars = vars(models_mod)
assert "EventData" not in models_vars, (
"EventData type alias must not exist in models module"
)
assert not hasattr(models_mod.SessionEvent, "parse_data"), ( # noqa: B009
assert not hasattr(
models_mod.SessionEvent, "parse_data"
), ( # hasattr intentional: must check full MRO
"SessionEvent.parse_data() must not exist — use as_*() accessors"
)

Expand Down
Loading