MCPcopy Create free account
hub / github.com/AgentOps-AI/agentops / decorator

Function decorator

agentops/sdk/decorators/factory.py:31–484  ·  view source on GitHub ↗
(
        wrapped: Optional[Callable[..., Any]] = None,
        *,
        name: Optional[str] = None,
        version: Optional[Any] = None,
        tags: Optional[Union[list, dict]] = None,
        cost=None,
        spec=None,
        capture_request: bool = True,
        capture_response: bool = True,
    )

Source from the content-addressed store, hash-verified

29 """
30
31 def decorator(
32 wrapped: Optional[Callable[..., Any]] = None,
33 *,
34 name: Optional[str] = None,
35 version: Optional[Any] = None,
36 tags: Optional[Union[list, dict]] = None,
37 cost=None,
38 spec=None,
39 capture_request: bool = True,
40 capture_response: bool = True,
41 ) -> Callable[..., Any]:
42 if wrapped is None:
43 return functools.partial(
44 decorator,
45 name=name,
46 version=version,
47 tags=tags,
48 cost=cost,
49 spec=spec,
50 capture_request=capture_request,
51 capture_response=capture_response,
52 )
53
54 if inspect.isclass(wrapped):
55 # Class decoration wraps __init__ and aenter/aexit for context management.
56 # For SpanKind.SESSION, this creates a span for __init__ or async context, not instance lifetime.
57 class WrappedClass(wrapped):
58 def __init__(self, *args: Any, **kwargs: Any):
59 op_name = name or wrapped.__name__
60 self._agentops_span_context_manager = _create_as_current_span(op_name, entity_kind, version)
61 self._agentops_active_span = self._agentops_span_context_manager.__enter__()
62 try:
63 _record_entity_input(self._agentops_active_span, args, kwargs)
64 except Exception as e:
65 logger.warning(f"Failed to record entity input for class {op_name}: {e}")
66 super().__init__(*args, **kwargs)
67
68 def __del__(self):
69 """Ensure span is properly ended when object is destroyed."""
70 if hasattr(self, "_agentops_span_context_manager") and self._agentops_span_context_manager:
71 try:
72 self._agentops_span_context_manager.__exit__(None, None, None)
73 except Exception:
74 pass
75
76 async def __aenter__(self) -> "WrappedClass":
77 if hasattr(self, "_agentops_active_span") and self._agentops_active_span is not None:
78 return self
79 op_name = name or wrapped.__name__
80 self._agentops_span_context_manager = _create_as_current_span(op_name, entity_kind, version)
81 self._agentops_active_span = self._agentops_span_context_manager.__enter__()
82 return self
83
84 async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
85 if hasattr(self, "_agentops_active_span") and hasattr(self, "_agentops_span_context_manager"):
86 try:
87 _record_entity_output(self._agentops_active_span, self)
88 except Exception as e:

Callers

nothing calls this directly

Calls 1

wrapperFunction · 0.70

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…