From e942f6ea0aa38d0c5100ee6f6f9feefcd5d43029 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:03:39 +0000 Subject: [PATCH 1/5] Fix decorator initialization failures by adding auto-initialization logic - Add auto-initialization to decorator factory when tracer is not initialized - Follow same pattern as start_trace() function for consistency - Add proper logging for debugging initialization attempts - Maintain backward compatibility by falling back to unwrapped function on failure - Fixes silent failures of @agent, @tool, @task decorators when SDK not initialized Co-Authored-By: Alex --- agentops/sdk/decorators/factory.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/agentops/sdk/decorators/factory.py b/agentops/sdk/decorators/factory.py index 2ddca1437..a81a4287e 100644 --- a/agentops/sdk/decorators/factory.py +++ b/agentops/sdk/decorators/factory.py @@ -82,7 +82,16 @@ def wrapper( wrapped_func: Callable[..., Any], instance: Optional[Any], args: tuple, kwargs: Dict[str, Any] ) -> Any: if not tracer.initialized: - return wrapped_func(*args, **kwargs) + logger.warning("AgentOps SDK not initialized. Attempting to initialize with defaults before applying decorator.") + try: + from agentops import init + init() + if not tracer.initialized: + logger.error("SDK initialization failed. Decorator will not instrument function.") + return wrapped_func(*args, **kwargs) + except Exception as e: + logger.error(f"SDK auto-initialization failed during decorator application: {e}. Decorator will not instrument function.") + return wrapped_func(*args, **kwargs) operation_name = name or wrapped_func.__name__ is_async = asyncio.iscoroutinefunction(wrapped_func) From f94881cef1d5e34b949240c641823b46477f227d Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:05:39 +0000 Subject: [PATCH 2/5] Apply ruff formatting to decorator auto-initialization logic - Fix line length and spacing issues identified by pre-commit checks - Maintain functionality while conforming to code style requirements Co-Authored-By: Alex --- agentops/sdk/decorators/factory.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/agentops/sdk/decorators/factory.py b/agentops/sdk/decorators/factory.py index a81a4287e..50d25d322 100644 --- a/agentops/sdk/decorators/factory.py +++ b/agentops/sdk/decorators/factory.py @@ -82,15 +82,20 @@ def wrapper( wrapped_func: Callable[..., Any], instance: Optional[Any], args: tuple, kwargs: Dict[str, Any] ) -> Any: if not tracer.initialized: - logger.warning("AgentOps SDK not initialized. Attempting to initialize with defaults before applying decorator.") + logger.warning( + "AgentOps SDK not initialized. Attempting to initialize with defaults before applying decorator." + ) try: from agentops import init + init() if not tracer.initialized: logger.error("SDK initialization failed. Decorator will not instrument function.") return wrapped_func(*args, **kwargs) except Exception as e: - logger.error(f"SDK auto-initialization failed during decorator application: {e}. Decorator will not instrument function.") + logger.error( + f"SDK auto-initialization failed during decorator application: {e}. Decorator will not instrument function." + ) return wrapped_func(*args, **kwargs) operation_name = name or wrapped_func.__name__ From ed767a7fe762f189fbbdde917a6ba7e2e4535e55 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:10:12 +0000 Subject: [PATCH 3/5] Add comprehensive tests for decorator auto-initialization functionality - Test successful auto-initialization when tracer is not initialized - Test graceful handling of initialization failures - Test partial initialization failure scenarios - Provides coverage for the auto-initialization logic in decorator factory Co-Authored-By: Alex --- tests/unit/sdk/test_decorators.py | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/unit/sdk/test_decorators.py b/tests/unit/sdk/test_decorators.py index 96824d0fe..404e79d88 100644 --- a/tests/unit/sdk/test_decorators.py +++ b/tests/unit/sdk/test_decorators.py @@ -761,3 +761,66 @@ def no_cost_tool(self): span for span in spans if span.attributes.get(SpanAttributes.AGENTOPS_SPAN_KIND) == SpanKind.TOOL ) assert SpanAttributes.LLM_USAGE_TOOL_COST not in tool_span.attributes + + +class TestDecoratorAutoInitialization: + """Tests for decorator auto-initialization functionality.""" + + def test_decorator_auto_initialization_success(self, instrumentation: InstrumentationTester): + """Test that decorators auto-initialize when tracer is not initialized.""" + from unittest.mock import patch, MagicMock + from agentops.sdk.decorators.factory import create_entity_decorator + from agentops.sdk.core import tracer + + with patch.object(tracer, 'initialized', False): + with patch('agentops.init') as mock_init: + def mock_init_side_effect(): + tracer.initialized = True + mock_init.side_effect = mock_init_side_effect + + @create_entity_decorator("TASK") + def test_function(): + return "test_result" + + result = test_function() + + mock_init.assert_called_once() + assert result == "test_result" + + def test_decorator_auto_initialization_failure(self, instrumentation: InstrumentationTester): + """Test that decorators handle auto-initialization failure gracefully.""" + from unittest.mock import patch, MagicMock + from agentops.sdk.decorators.factory import create_entity_decorator + from agentops.sdk.core import tracer + + with patch.object(tracer, 'initialized', False): + with patch('agentops.init') as mock_init: + mock_init.side_effect = Exception("Init failed") + + @create_entity_decorator("TASK") + def test_function(): + return "test_result" + + result = test_function() + + mock_init.assert_called_once() + assert result == "test_result" + + def test_decorator_auto_initialization_partial_failure(self, instrumentation: InstrumentationTester): + """Test that decorators handle partial initialization failure gracefully.""" + from unittest.mock import patch, MagicMock + from agentops.sdk.decorators.factory import create_entity_decorator + from agentops.sdk.core import tracer + + with patch.object(tracer, 'initialized', False): + with patch('agentops.init') as mock_init: + mock_init.return_value = None + + @create_entity_decorator("TASK") + def test_function(): + return "test_result" + + result = test_function() + + mock_init.assert_called_once() + assert result == "test_result" From be53ab6022f348bac83ad09ef4fa32d6e0d77cb5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:12:03 +0000 Subject: [PATCH 4/5] Apply ruff formatting to decorator auto-initialization tests - Fix import statement formatting - Apply consistent quote style and spacing - Resolve pre-commit check failures Co-Authored-By: Alex --- tests/unit/sdk/test_decorators.py | 44 ++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/tests/unit/sdk/test_decorators.py b/tests/unit/sdk/test_decorators.py index 404e79d88..46012f959 100644 --- a/tests/unit/sdk/test_decorators.py +++ b/tests/unit/sdk/test_decorators.py @@ -768,59 +768,61 @@ class TestDecoratorAutoInitialization: def test_decorator_auto_initialization_success(self, instrumentation: InstrumentationTester): """Test that decorators auto-initialize when tracer is not initialized.""" - from unittest.mock import patch, MagicMock + from unittest.mock import patch from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - - with patch.object(tracer, 'initialized', False): - with patch('agentops.init') as mock_init: + + with patch.object(tracer, "initialized", False): + with patch("agentops.init") as mock_init: + def mock_init_side_effect(): tracer.initialized = True + mock_init.side_effect = mock_init_side_effect - + @create_entity_decorator("TASK") def test_function(): return "test_result" - + result = test_function() - + mock_init.assert_called_once() assert result == "test_result" def test_decorator_auto_initialization_failure(self, instrumentation: InstrumentationTester): """Test that decorators handle auto-initialization failure gracefully.""" - from unittest.mock import patch, MagicMock + from unittest.mock import patch from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - - with patch.object(tracer, 'initialized', False): - with patch('agentops.init') as mock_init: + + with patch.object(tracer, "initialized", False): + with patch("agentops.init") as mock_init: mock_init.side_effect = Exception("Init failed") - + @create_entity_decorator("TASK") def test_function(): return "test_result" - + result = test_function() - + mock_init.assert_called_once() assert result == "test_result" def test_decorator_auto_initialization_partial_failure(self, instrumentation: InstrumentationTester): """Test that decorators handle partial initialization failure gracefully.""" - from unittest.mock import patch, MagicMock + from unittest.mock import patch from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - - with patch.object(tracer, 'initialized', False): - with patch('agentops.init') as mock_init: + + with patch.object(tracer, "initialized", False): + with patch("agentops.init") as mock_init: mock_init.return_value = None - + @create_entity_decorator("TASK") def test_function(): return "test_result" - + result = test_function() - + mock_init.assert_called_once() assert result == "test_result" From a95fec80987653a3f540feaba17888117b032e91 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:16:34 +0000 Subject: [PATCH 5/5] Fix test implementation to mock _initialized attribute instead of initialized property - Replace patch.object(tracer, 'initialized', False) with patch.object(tracer, '_initialized', False) - Fix side effect function to set tracer._initialized = True - Resolves AttributeError: property 'initialized' has no setter/deleter Co-Authored-By: Alex --- tests/unit/sdk/test_decorators.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/sdk/test_decorators.py b/tests/unit/sdk/test_decorators.py index 46012f959..f8b19dfc4 100644 --- a/tests/unit/sdk/test_decorators.py +++ b/tests/unit/sdk/test_decorators.py @@ -772,11 +772,11 @@ def test_decorator_auto_initialization_success(self, instrumentation: Instrument from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - with patch.object(tracer, "initialized", False): + with patch.object(tracer, "_initialized", False): with patch("agentops.init") as mock_init: def mock_init_side_effect(): - tracer.initialized = True + tracer._initialized = True mock_init.side_effect = mock_init_side_effect @@ -795,7 +795,7 @@ def test_decorator_auto_initialization_failure(self, instrumentation: Instrument from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - with patch.object(tracer, "initialized", False): + with patch.object(tracer, "_initialized", False): with patch("agentops.init") as mock_init: mock_init.side_effect = Exception("Init failed") @@ -814,7 +814,7 @@ def test_decorator_auto_initialization_partial_failure(self, instrumentation: In from agentops.sdk.decorators.factory import create_entity_decorator from agentops.sdk.core import tracer - with patch.object(tracer, "initialized", False): + with patch.object(tracer, "_initialized", False): with patch("agentops.init") as mock_init: mock_init.return_value = None