Case-normalize client names in telemetry labels#73
Conversation
clientInfo.name is used raw from the initialize request while User-Agent-derived names are lowercased product tokens, so the same client splits into two client_id label values (Trae vs trae) across handshake and per-request identity binding. Normalize at both telemetry entry points: strip, lowercase, collapse whitespace runs to hyphens, cap at 64 chars.
Greptile SummaryThis PR fixes a label-split bug where the same MCP client appeared as two distinct
Confidence Score: 5/5Safe to merge — the change is narrowly scoped to a normalization helper and its two call sites, with no behavioral changes to anything outside the telemetry label path. The normalization logic is correct and well-covered: every meaningful edge case (case, internal whitespace, leading/trailing whitespace, empty, None, length cap) has an explicit test assertion. The two call sites in No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "(fix): case-normalize client names in te..." | Re-trigger Greptile |
Summary
The MCP dashboard showed
Traeandtraeas two distinct clients in "Active Sessions by Client". The split happens becauseclient_idis bound from two sources with different casing rules:initializerequest,clientInfo.nameis used raw (http_app.py→record_connection), e.g.Trae._client_from_user_agent), e.g.trae.So a single client contributes two label values across handshake vs per-request metrics, splitting session counts, connection counts, and tool-call attribution.
Change
Add
_normalize_client_name()intelemetry.pyand apply it at both identity entry points (set_request_identity,record_connection): strip surrounding whitespace, lowercase, collapse internal whitespace runs to hyphens (matching the product-token shape of UA-derived names), cap at 64 chars. Empty/whitespace-only names still fall through to the existingunknownhandling.Normalizing at the telemetry layer (rather than the HTTP middleware) covers every caller and keeps the invariant documented in the module docstring:
client_idis a small bounded set of client names.Tests
test_client_names_are_case_normalized— aTraehandshake followed by atraerequest produces a singleclient_id="trae"session and connection label.test_client_name_normalization_shapes— table test for casing, whitespace-to-hyphen, empty/None, and length-cap behavior.Full pre-PR checklist passes: ruff, black, pyright, 168 unit tests.