-
Notifications
You must be signed in to change notification settings - Fork 5
Add Foundry-hosted agent ID override for A365 exporter #102
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
base: main
Are you sure you want to change the base?
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 |
|---|---|---|
|
|
@@ -74,6 +74,7 @@ def my_enricher(span): | |
|
|
||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = False | ||
| processor._foundry_agent_id = None | ||
|
|
||
| original_span = MagicMock(spec=ReadableSpan) | ||
| original_span.name = "original" | ||
|
|
@@ -92,6 +93,7 @@ def bad_enricher(span): | |
|
|
||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = False | ||
| processor._foundry_agent_id = None | ||
|
|
||
| original_span = MagicMock(spec=ReadableSpan) | ||
| original_span.name = "original" | ||
|
|
@@ -105,6 +107,7 @@ def bad_enricher(span): | |
| def test_suppress_invoke_agent_input(self): | ||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = True | ||
| processor._foundry_agent_id = None | ||
|
|
||
| span = MagicMock(spec=ReadableSpan) | ||
| span.name = "invoke_agent Travel_Assistant" | ||
|
|
@@ -122,6 +125,7 @@ def test_suppress_invoke_agent_input(self): | |
| def test_no_suppress_for_non_invoke_agent(self): | ||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = True | ||
| processor._foundry_agent_id = None | ||
|
|
||
| span = MagicMock(spec=ReadableSpan) | ||
| span.name = "chat gpt-4" | ||
|
|
@@ -135,5 +139,91 @@ def test_no_suppress_for_non_invoke_agent(self): | |
| mock_super_on_end.assert_called_once_with(span) | ||
|
|
||
|
|
||
| class TestFoundryAgentIdOverride(unittest.TestCase): | ||
| """Tests for Foundry-hosted agent ID override in _EnrichingBatchSpanProcessor.""" | ||
|
|
||
| def setUp(self): | ||
| unregister_span_enricher() | ||
|
|
||
| def tearDown(self): | ||
| unregister_span_enricher() | ||
|
|
||
| @patch.object(_EnrichingBatchSpanProcessor, "__init__", lambda self, *a, **kw: None) | ||
| def test_override_applied_when_foundry_agent_id_set(self): | ||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = False | ||
| processor._foundry_agent_id = "foundry-agent-123" | ||
|
|
||
| span = MagicMock(spec=ReadableSpan) | ||
| span.name = "chat gpt-4" | ||
| span.attributes = {"gen_ai.agent.id": "original-id"} | ||
|
|
||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "on_end") as mock_super_on_end: | ||
| processor.on_end(span) | ||
| passed_span = mock_super_on_end.call_args[0][0] | ||
| self.assertEqual(passed_span.attributes["gen_ai.agent.id"], "foundry-agent-123") | ||
|
|
||
| @patch.object(_EnrichingBatchSpanProcessor, "__init__", lambda self, *a, **kw: None) | ||
| def test_override_not_applied_when_foundry_agent_id_none(self): | ||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = False | ||
| processor._foundry_agent_id = None | ||
|
|
||
| span = MagicMock(spec=ReadableSpan) | ||
| span.name = "chat gpt-4" | ||
| span.attributes = {"gen_ai.agent.id": "original-id"} | ||
|
|
||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "on_end") as mock_super_on_end: | ||
| processor.on_end(span) | ||
| mock_super_on_end.assert_called_once_with(span) | ||
|
|
||
| @patch.dict("os.environ", {"FOUNDRY_HOSTING_ENVIRONMENT": "1", "FOUNDRY_AGENT_IDENTITY": "env-agent-456"}) | ||
| def test_init_reads_env_vars_when_foundry_hosted(self): | ||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "__init__", return_value=None): | ||
| processor = _EnrichingBatchSpanProcessor(MagicMock()) | ||
| self.assertEqual(processor._foundry_agent_id, "env-agent-456") | ||
|
|
||
|
Comment on lines
+180
to
+185
|
||
| @patch.dict("os.environ", {"FOUNDRY_HOSTING_ENVIRONMENT": "0", "FOUNDRY_AGENT_IDENTITY": "env-agent-456"}) | ||
| def test_init_no_override_when_not_foundry_hosted(self): | ||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "__init__", return_value=None): | ||
| processor = _EnrichingBatchSpanProcessor(MagicMock()) | ||
| self.assertIsNone(processor._foundry_agent_id) | ||
|
|
||
| @patch.dict("os.environ", {"FOUNDRY_HOSTING_ENVIRONMENT": "1"}, clear=False) | ||
| def test_init_no_override_when_agent_identity_missing(self): | ||
| # Ensure FOUNDRY_AGENT_IDENTITY is not set | ||
| import os | ||
|
|
||
| os.environ.pop("FOUNDRY_AGENT_IDENTITY", None) | ||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "__init__", return_value=None): | ||
| processor = _EnrichingBatchSpanProcessor(MagicMock()) | ||
| self.assertIsNone(processor._foundry_agent_id) | ||
|
|
||
| @patch.dict("os.environ", {}, clear=False) | ||
| def test_init_no_override_when_both_env_vars_missing(self): | ||
| import os | ||
|
|
||
| os.environ.pop("FOUNDRY_HOSTING_ENVIRONMENT", None) | ||
| os.environ.pop("FOUNDRY_AGENT_IDENTITY", None) | ||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "__init__", return_value=None): | ||
| processor = _EnrichingBatchSpanProcessor(MagicMock()) | ||
| self.assertIsNone(processor._foundry_agent_id) | ||
|
|
||
| @patch.object(_EnrichingBatchSpanProcessor, "__init__", lambda self, *a, **kw: None) | ||
| def test_override_sets_agent_id_when_span_has_no_existing_id(self): | ||
| processor = _EnrichingBatchSpanProcessor.__new__(_EnrichingBatchSpanProcessor) | ||
| processor._suppress_invoke_agent_input = False | ||
| processor._foundry_agent_id = "foundry-agent-789" | ||
|
|
||
| span = MagicMock(spec=ReadableSpan) | ||
| span.name = "chat gpt-4" | ||
| span.attributes = {"gen_ai.operation.name": "chat"} | ||
|
|
||
| with patch.object(_EnrichingBatchSpanProcessor.__bases__[0], "on_end") as mock_super_on_end: | ||
| processor.on_end(span) | ||
| passed_span = mock_super_on_end.call_args[0][0] | ||
| self.assertEqual(passed_span.attributes["gen_ai.agent.id"], "foundry-agent-789") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
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.
FOUNDRY_HOSTING_ENVIRONMENT_ENV is being treated as truthy only when the env var equals the literal string "1". Elsewhere in this repo, env-bool parsing normalizes with strip().lower() and accepts ("true", "1", "yes", "on"). To avoid surprising behavior (e.g., "True"/"on" not enabling the override) and to stay consistent with existing env parsing, normalize + use the same truthy set (or reuse an existing env-bool helper) before deciding whether to apply the override.