Skip to content
Open
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
12 changes: 11 additions & 1 deletion python/packages/core/agent_framework/_telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ def prepend_agent_framework_to_user_agent(headers: dict[str, Any] | None = None)
user_agent = get_user_agent()
if not headers:
return {USER_AGENT_KEY: user_agent}
headers[USER_AGENT_KEY] = f"{user_agent} {headers[USER_AGENT_KEY]}" if USER_AGENT_KEY in headers else user_agent
# HTTP header names are case-insensitive; detect an existing User-Agent entry
# regardless of casing so the framework value is prepended to it instead of
# creating a second, duplicate User-Agent header.
existing_key = next(
(key for key in headers if isinstance(key, str) and key.lower() == USER_AGENT_KEY.lower()),
None,
)
if existing_key is None:
headers[USER_AGENT_KEY] = user_agent
else:
headers[existing_key] = f"{user_agent} {headers[existing_key]}"

return headers
41 changes: 41 additions & 0 deletions python/packages/core/tests/core/test_telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,47 @@ def test_modifies_original_dict():
assert "User-Agent" in headers


def test_prepend_to_lowercase_user_agent():
"""Test prepending to an existing lowercase user-agent entry.

HTTP header names are case-insensitive, so callers may pass
``user-agent`` instead of ``User-Agent``. The framework value must be
prepended to the existing entry rather than adding a second
User-Agent header alongside it.
"""
headers = {"user-agent": "existing-agent/1.0"}
result = prepend_agent_framework_to_user_agent(headers)

user_agent_values = [value for key, value in result.items() if key.lower() == "user-agent"]
assert len(user_agent_values) == 1
assert user_agent_values[0].startswith("agent-framework-python/")
assert "existing-agent/1.0" in user_agent_values[0]


def test_prepend_to_uppercase_user_agent():
"""Test prepending to an all-caps USER-AGENT entry."""
headers = {"USER-AGENT": "existing-agent/2.0"}
result = prepend_agent_framework_to_user_agent(headers)

user_agent_values = [value for key, value in result.items() if key.lower() == "user-agent"]
assert len(user_agent_values) == 1
assert user_agent_values[0].startswith("agent-framework-python/")
assert "existing-agent/2.0" in user_agent_values[0]


def test_no_duplicate_user_agent_after_prepend(monkeypatch):
"""Test httpx sees a single User-Agent header after the prepend."""
import httpx

headers = {"user-agent": "existing-agent/1.0"}
result = prepend_agent_framework_to_user_agent(headers)
request = httpx.Request("GET", "https://example.com", headers=result)
raw_values = [value for name, value in request.headers.raw if name.lower() == b"user-agent"]

assert len(raw_values) == 1
assert raw_values[0].startswith(b"agent-framework-python/")


# region Test _add_user_agent_prefix


Expand Down
Loading