Skip to content

Commit 367fb94

Browse files
authored
Merge branch 'staging' into customer-id-tags
2 parents 0ca7539 + 7772a9e commit 367fb94

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/judgeval/common/tracer.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,55 @@ def wrapper(*args, **kwargs):
21502150

21512151
return wrapper
21522152

2153+
def observe_tools(self, cls=None, *, exclude_methods: Optional[List[str]] = None,
2154+
include_private: bool = False, warn_on_double_decoration: bool = True):
2155+
"""
2156+
Automatically adds @observe(span_type="tool") to all methods in a class.
2157+
2158+
Args:
2159+
cls: The class to decorate (automatically provided when used as decorator)
2160+
exclude_methods: List of method names to skip decorating. Defaults to common magic methods
2161+
include_private: Whether to decorate methods starting with underscore. Defaults to False
2162+
warn_on_double_decoration: Whether to print warnings when skipping already-decorated methods. Defaults to True
2163+
"""
2164+
2165+
if exclude_methods is None:
2166+
exclude_methods = ['__init__', '__new__', '__del__', '__str__', '__repr__']
2167+
2168+
def decorate_class(cls):
2169+
if not self.enable_monitoring:
2170+
return cls
2171+
2172+
decorated = []
2173+
skipped = []
2174+
2175+
for name in dir(cls):
2176+
method = getattr(cls, name)
2177+
2178+
if (not callable(method) or
2179+
name in exclude_methods or
2180+
(name.startswith('_') and not include_private) or
2181+
not hasattr(cls, name)):
2182+
continue
2183+
2184+
if hasattr(method, '_judgment_span_name'):
2185+
skipped.append(name)
2186+
if warn_on_double_decoration:
2187+
print(f"Warning: {cls.__name__}.{name} already decorated, skipping")
2188+
continue
2189+
2190+
try:
2191+
decorated_method = self.observe(method, span_type="tool")
2192+
setattr(cls, name, decorated_method)
2193+
decorated.append(name)
2194+
except Exception as e:
2195+
if warn_on_double_decoration:
2196+
print(f"Warning: Failed to decorate {cls.__name__}.{name}: {e}")
2197+
2198+
return cls
2199+
2200+
return decorate_class if cls is None else decorate_class(cls)
2201+
21532202
def async_evaluate(self, *args, **kwargs):
21542203
if not self.enable_evaluations:
21552204
return

0 commit comments

Comments
 (0)