Skip to content

refactor: extract shared merge_model_metrics helper (#47)#49

Merged
microsasa merged 2 commits intomainfrom
fix/extract-merge-model-metrics-47-242b5cfddc1b4f98
Mar 15, 2026
Merged

refactor: extract shared merge_model_metrics helper (#47)#49
microsasa merged 2 commits intomainfrom
fix/extract-merge-model-metrics-47-242b5cfddc1b4f98

Conversation

@microsasa
Copy link
Owner

Closes #47

Problem

ModelMetrics dict merging was implemented twice with divergent approaches:

  • parser.py (build_session_summary): Creates new ModelMetrics/RequestMetrics/TokenUsage objects on every merge — safe but verbose.
  • report.py (_aggregate_model_metrics): Uses model_copy() on first insertion, then mutates the copy in-place — fragile if copy is ever removed.

Any future bug fix or field addition (e.g. a new token type on TokenUsage) had to be applied in both places.

Solution

Extracted a shared merge_model_metrics(base, additional) helper in models.py that:

  • Returns a new dict without mutating either input
  • Deep-copies base entries and accumulates additional entries by model name
  • Is the single source of truth for merging model metrics

Both parser.py and report.py now delegate to this helper.

Changes

File Change
src/copilot_usage/models.py Added merge_model_metrics() function
src/copilot_usage/parser.py Replaced 20-line inline merge loop with merge_model_metrics() call
src/copilot_usage/report.py Replaced _aggregate_model_metrics body with merge_model_metrics() call
tests/copilot_usage/test_models.py Added TestMergeModelMetrics with 7 test cases

Tests

New TestMergeModelMetrics class covers:

  • Both dicts empty
  • Empty base / empty additional
  • Overlapping keys — all 6 fields accumulate correctly
  • Disjoint keys kept separate
  • No mutation of base input
  • No mutation of additional input

Existing test_parser.py and test_report.py tests (including TestAggregateModelMetrics) remain unchanged and validate regression.

Generated by Issue Implementer ·

Warning

⚠️ Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • astral.sh
  • conda.anaconda.org
  • pypi.org
  • repo.anaconda.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "astral.sh"
    - "conda.anaconda.org"
    - "pypi.org"
    - "repo.anaconda.com"

See Network Configuration for more information.

@microsasa microsasa marked this pull request as ready for review March 15, 2026 04:06
@microsasa microsasa requested a review from Copilot March 15, 2026 04:06
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors duplicated ModelMetrics merging logic into a shared merge_model_metrics(base, additional) helper to ensure consistent, non-mutating aggregation across the codebase.

Changes:

  • Added merge_model_metrics() helper to centralize model-metrics merging behavior.
  • Updated parser.py and report.py to delegate merging to the shared helper.
  • Added dedicated unit tests for merge_model_metrics().

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/copilot_usage/models.py Introduces merge_model_metrics() helper for non-mutating metric aggregation.
src/copilot_usage/parser.py Replaces inline shutdown-cycle metric merge loop with merge_model_metrics().
src/copilot_usage/report.py Replaces _aggregate_model_metrics loop body with merge_model_metrics().
tests/copilot_usage/test_models.py Adds TestMergeModelMetrics coverage for empty/overlap/disjoint/non-mutation cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

github-actions bot and others added 2 commits March 14, 2026 21:14
Extract duplicated ModelMetrics merging logic from parser.py and
report.py into a single merge_model_metrics() function in models.py.

- Add merge_model_metrics() that returns a new dict without mutating
  either input
- Replace inline merging in build_session_summary() (parser.py)
- Replace _aggregate_model_metrics body (report.py) with calls to
  the shared helper
- Add unit tests: empty dicts, single entry, overlapping keys,
  disjoint keys, all token fields accumulate, no-mutation guarantees

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replaces manual ModelMetrics reconstruction with model_copy(deep=True)
and in-place field accumulation. Keeps copy aligned with model schema
and reduces allocations for overlapping keys.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsasa microsasa force-pushed the fix/extract-merge-model-metrics-47-242b5cfddc1b4f98 branch from 263eca4 to bc3d7da Compare March 15, 2026 04:14
@microsasa microsasa merged commit f7d4524 into main Mar 15, 2026
4 checks passed
@microsasa microsasa deleted the fix/extract-merge-model-metrics-47-242b5cfddc1b4f98 branch March 15, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[aw][code health] Duplicated ModelMetrics merging logic in parser.py and report.py

2 participants