Repository: AgentOps-AI/agentops

Issue:
Set User-Agent header on requests to api.agentops.ai
Include sdk version as well.


Discussion:

Patch:
diff --git a/agentops/client/api/base.py b/agentops/client/api/base.py
index f9ae318d5..44140956e 100644
--- a/agentops/client/api/base.py
+++ b/agentops/client/api/base.py
@@ -9,6 +9,7 @@
 import requests
 
 from agentops.client.http.http_client import HttpClient
+from agentops.helpers.version import get_agentops_version
 
 
 class TokenFetcher(Protocol):
@@ -51,6 +52,7 @@ def prepare_headers(self, custom_headers: Optional[Dict[str, str]] = None) -> Di
             "Content-Type": "application/json",
             "Connection": "keep-alive",
             "Keep-Alive": "timeout=10, max=1000",
+            "User-Agent": f"agentops-python/{get_agentops_version() or 'unknown'}",
         }
 
         if custom_headers:
diff --git a/agentops/client/api/versions/v4.py b/agentops/client/api/versions/v4.py
index a04733f3e..eee2fbe16 100644
--- a/agentops/client/api/versions/v4.py
+++ b/agentops/client/api/versions/v4.py
@@ -9,6 +9,7 @@
 from agentops.client.api.base import BaseApiClient
 from agentops.exceptions import ApiServerException
 from agentops.client.api.types import UploadedObjectResponse
+from agentops.helpers.version import get_agentops_version
 
 
 class V4Client(BaseApiClient):
@@ -36,6 +37,7 @@ def prepare_headers(self, custom_headers: Optional[Dict[str, str]] = None) -> Di
         """
         headers = {
             "Authorization": f"Bearer {self.auth_token}",
+            "User-Agent": f"agentops-python/{get_agentops_version() or 'unknown'}",
         }
         if custom_headers:
             headers.update(custom_headers)
diff --git a/agentops/client/http/http_client.py b/agentops/client/http/http_client.py
index 1b105bce7..01eb0cefe 100644
--- a/agentops/client/http/http_client.py
+++ b/agentops/client/http/http_client.py
@@ -4,6 +4,7 @@
 
 from agentops.client.http.http_adapter import BaseHTTPAdapter
 from agentops.logging import logger
+from agentops.helpers.version import get_agentops_version
 
 
 class HttpClient:
@@ -36,9 +37,10 @@ def get_session(cls) -> requests.Session:
                     "Connection": "keep-alive",
                     "Keep-Alive": "timeout=10, max=1000",
                     "Content-Type": "application/json",
+                    "User-Agent": f"agentops-python/{get_agentops_version() or 'unknown'}",
                 }
             )
-
+            logger.debug(f"Agentops version: agentops-python/{get_agentops_version() or 'unknown'}")
         return cls._session
 
     # @classmethod


Test patch:
diff --git a/tests/unit/test_user_agent.py b/tests/unit/test_user_agent.py
new file mode 100644
index 000000000..681306798
--- /dev/null
+++ b/tests/unit/test_user_agent.py
@@ -0,0 +1,34 @@
+import pytest
+import requests
+from unittest.mock import patch
+from agentops.client.http.http_client import HttpClient
+from agentops.helpers.version import get_agentops_version
+
+
+@pytest.fixture(autouse=True)
+def reset_http_client_session():
+    # Reset the cached session before each test
+    HttpClient._session = None
+
+
+def test_user_agent_header():
+    with patch("requests.Session", wraps=requests.Session):
+        session = HttpClient.get_session()
+        expected_version = get_agentops_version() or "unknown"
+        expected_user_agent = f"agentops-python/{expected_version}"
+        # Check the session's headers directly
+        assert "User-Agent" in session.headers
+        assert session.headers["User-Agent"] == expected_user_agent
+
+
+def test_user_agent_header_content():
+    with patch("requests.Session", wraps=requests.Session):
+        session = HttpClient.get_session()
+        # Check the session's headers directly
+        assert "User-Agent" in session.headers
+        assert "Connection" in session.headers
+        assert "Keep-Alive" in session.headers
+        assert "Content-Type" in session.headers
+        assert session.headers["Connection"] == "keep-alive"
+        assert session.headers["Keep-Alive"] == "timeout=10, max=1000"
+        assert session.headers["Content-Type"] == "application/json"