-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Python: Fix FoundryAgent telemetry gaps for name and model (Fixes #5088) #5094
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -214,6 +214,15 @@ def _get_agent_reference(self) -> dict[str, str]: | |||||
| ref["version"] = self.agent_version | ||||||
| return ref | ||||||
|
|
||||||
| @property | ||||||
| def model(self) -> str: | ||||||
| """Get the lazily fetched model name, or 'unknown' if not yet fetched.""" | ||||||
| return getattr(self, "_fetched_model", "unknown") | ||||||
|
|
||||||
| @model.setter | ||||||
| def model(self, value: str) -> None: | ||||||
| pass | ||||||
|
||||||
| pass | |
| self._fetched_model = value |
Copilot
AI
Apr 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lazy model fetch uses if not hasattr(self, "_fetched_model") and then awaits project_client.agents.get_agent(...). If two calls enter _prepare_options concurrently before _fetched_model is set, both will perform the network call. Consider guarding the lazy initialization with an asyncio.Lock or an in-flight Task/Future so only one fetch occurs and others await it.
Copilot
AI
Apr 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating the OpenTelemetry span via trace.get_current_span() won’t work for streaming requests: ChatTelemetryLayer intentionally creates streaming spans without context attachment (core/agent_framework/observability.py:1293-1299), so there may be no “current span” to update. As a result, gen_ai.request.model can still remain unknown for stream=True. Consider a mechanism that ensures the span used for the request is the one being updated (e.g., providing the model before span creation, or passing/propagating the span explicitly).
Copilot
AI
Apr 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The except Exception blocks here swallow all failures (including auth/config/service errors) and then suppress them again when updating OTEL, with no logging. This can make real regressions very hard to diagnose and permanently cache "unknown" after a transient error. Prefer catching expected exception types (e.g., ImportError separately, and the specific Azure SDK error types for get_agent) and logging at least a debug/warning message once when resolution fails.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -465,3 +465,38 @@ async def test_foundry_agent_custom_client_run() -> None: | |||||
| assert isinstance(response, AgentResponse) | ||||||
| assert response.text is not None | ||||||
| assert "response test" in response.text.lower() | ||||||
|
|
||||||
|
|
||||||
| async def test_foundry_agent_telemetry_defaults() -> None: | ||||||
| """Test that agent name acts as a fallback and _prepare_options lazily gets model.""" | ||||||
| mock_project = MagicMock() | ||||||
| mock_openai = MagicMock() | ||||||
| mock_project.get_openai_client.return_value = mock_openai | ||||||
|
|
||||||
| # Mock agents getter | ||||||
| mock_agent_instance = MagicMock() | ||||||
| mock_agent_instance.model = "gpt-telemetry-test" | ||||||
| mock_project.agents.get_agent = AsyncMock(return_value=mock_agent_instance) | ||||||
|
|
||||||
| agent = FoundryAgent( | ||||||
| project_client=mock_project, | ||||||
| agent_name="my-telemetry-agent", | ||||||
| name=None # Explicitly None to test fallback | ||||||
|
||||||
| name=None # Explicitly None to test fallback | |
| name=None, # Explicitly None to test fallback |
Uh oh!
There was an error while loading. Please reload this page.