Skip to content

fix(headers): merge tracking headers regardless of casing - #7471

Draft
BlueRaddish wants to merge 1 commit into
google:mainfrom
BlueRaddish:fix/oct8b-tracking-header-case
Draft

BlueRaddish wants to merge 1 commit into
google:mainfrom
BlueRaddish:fix/oct8b-tracking-header-case

Conversation

@BlueRaddish

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

Problem: merge_tracking_headers looks up tracking header names using lowercase dictionary keys. A caller supplying User-Agent or X-Goog-Api-Client therefore gets its custom field plus a second lowercase field containing the ADK tokens. A real httpx.Request carries two values for each affected HTTP field.

Reproduction on base 7d8c9502f924ed5e7a1ab00dc1f5a603e858abc3: merge {"User-Agent": "custom-client/1", "X-Goog-Api-Client": "custom-sdk/1"}, then create an httpx.Request with those headers. request.headers.get_list("user-agent") returns the custom value and a separate ADK tracking value. Expected: one merged field preserving both sets of tokens.

Solution: Merge custom tokens from every casing variant of the two tracking fields into one canonical field, avoiding duplicate tokens. Keep unrelated header spelling and leave the input dictionary unchanged. Remove the MCP caller's redundant casing normalization, which otherwise discards an earlier variant before the shared helper can preserve it.

Testing Plan

Unit Tests:

  • Added regression cases to the existing header utility test file.
  • The affected header and client-label test files pass locally: 20 passed on Python 3.12.15. The two new mixed-case cases fail on the base. A further case proves both aliases retain their custom tokens and deduplicate shared tokens; it fails on the initial normalization approach and passes after repair.
  • Supported repository MCP regression: fails on the unchanged base because base-client tracking tokens are lost, then passes on the revised code. The complete affected header, client-label, and MCP test files pass: 148 passed on Python 3.13.14 with real supported mcp 2.3.0. Existing experimental-feature and AsyncMock warnings remain.

sh pytest tests/unittests/utils/test_google_client_headers.py tests/unittests/utils/test_client_labels_utils.py tests/unittests/tools/mcp_tool/test_mcp_session_manager.py -q

Manual End-to-End (E2E) Tests: The regression tests construct real httpx.Request objects with the merged headers and check that each tracking field reaches the transport once, with the custom tokens retained. Real Google GenAI types are used; no model, network request, or service mock is involved.

A separate focused header-flow check executes the exact AST-extracted production MCP _merge_headers method with the real shared helper and HTTPX. The base method loses the earlier custom tokens; the revised method preserves both variants and unrelated-header override behavior. This check uses plain connection-parameter values and does not establish complete MCP integration coverage.

Checklist

  • Read the contribution guide and performed a self-review.
  • Added tests that demonstrate the reported failure.
  • All new and affected existing tests pass locally.
  • Checked the real HTTP request representation.

Additional context

No signatures, dependencies, authentication behavior, or unrelated headers change. Normal repository pre-commit hooks pass in the existing native Linux environment, including Ruff, isort, Pyink, compliance, license, private-module, documentation, and spelling checks. The hook formatter only adds one blank line before an adjacent top-level MCP function. git diff --check passes. Current main still has all affected source/test blobs unchanged; complete matching PR diffs were checked and none supersede this fix.

Full repository, service-backed MCP integration, and multi-version tox suites were not run; the contribution guide calls for full multi-version tox before review. Focused tests use actual production modules and supported MCP dependencies, with existing MCP test mocks. The real HTTPX transport representation is checked without a remote service or model call.

Prepared with assistance from OpenAI Codex.

Merge every case variant of the two tracking fields without losing custom tokens. Let MCP use the shared merge instead of collapsing aliases first.
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.

2 participants