ragaai-catalyst 2.1.5b20__py3-none-any.whl → 2.1.5b22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ragaai_catalyst/dataset.py +54 -1
- ragaai_catalyst/synthetic_data_generation.py +39 -6
- ragaai_catalyst/tracers/agentic_tracing/tracers/agent_tracer.py +28 -18
- ragaai_catalyst/tracers/agentic_tracing/tracers/base.py +3 -1
- ragaai_catalyst/tracers/agentic_tracing/tracers/custom_tracer.py +17 -7
- ragaai_catalyst/tracers/agentic_tracing/tracers/llm_tracer.py +106 -16
- ragaai_catalyst/tracers/agentic_tracing/tracers/main_tracer.py +1 -2
- ragaai_catalyst/tracers/agentic_tracing/tracers/tool_tracer.py +17 -6
- ragaai_catalyst/tracers/agentic_tracing/upload/upload_trace_metric.py +6 -5
- ragaai_catalyst/tracers/agentic_tracing/utils/file_name_tracker.py +21 -2
- ragaai_catalyst/tracers/agentic_tracing/utils/llm_utils.py +30 -11
- ragaai_catalyst/tracers/agentic_tracing/utils/model_costs.json +1204 -484
- ragaai_catalyst/tracers/agentic_tracing/utils/span_attributes.py +35 -0
- ragaai_catalyst/tracers/agentic_tracing/utils/trace_utils.py +0 -32
- ragaai_catalyst/tracers/distributed.py +7 -3
- ragaai_catalyst/tracers/tracer.py +25 -8
- ragaai_catalyst/tracers/utils/langchain_tracer_extraction_logic.py +5 -4
- {ragaai_catalyst-2.1.5b20.dist-info → ragaai_catalyst-2.1.5b22.dist-info}/METADATA +2 -2
- {ragaai_catalyst-2.1.5b20.dist-info → ragaai_catalyst-2.1.5b22.dist-info}/RECORD +22 -22
- {ragaai_catalyst-2.1.5b20.dist-info → ragaai_catalyst-2.1.5b22.dist-info}/LICENSE +0 -0
- {ragaai_catalyst-2.1.5b20.dist-info → ragaai_catalyst-2.1.5b22.dist-info}/WHEEL +0 -0
- {ragaai_catalyst-2.1.5b20.dist-info → ragaai_catalyst-2.1.5b22.dist-info}/top_level.txt +0 -0
@@ -258,7 +258,10 @@ class ToolTracerMixin:
|
|
258
258
|
@functools.wraps(func)
|
259
259
|
async def async_wrapper(*args, **kwargs):
|
260
260
|
async_wrapper.metadata = metadata
|
261
|
-
|
261
|
+
gt = kwargs.get("gt") if kwargs else None
|
262
|
+
if gt is not None:
|
263
|
+
span = self.span(name)
|
264
|
+
span.add_gt(gt)
|
262
265
|
return await self._trace_tool_execution(
|
263
266
|
func, name, tool_type, version, *args, **kwargs
|
264
267
|
)
|
@@ -267,7 +270,10 @@ class ToolTracerMixin:
|
|
267
270
|
@functools.wraps(func)
|
268
271
|
def sync_wrapper(*args, **kwargs):
|
269
272
|
sync_wrapper.metadata = metadata
|
270
|
-
|
273
|
+
gt = kwargs.get("gt") if kwargs else None
|
274
|
+
if gt is not None:
|
275
|
+
span = self.span(name)
|
276
|
+
span.add_gt(gt)
|
271
277
|
return self._trace_sync_tool_execution(
|
272
278
|
func, name, tool_type, version, *args, **kwargs
|
273
279
|
)
|
@@ -302,7 +308,7 @@ class ToolTracerMixin:
|
|
302
308
|
|
303
309
|
try:
|
304
310
|
# Execute the tool
|
305
|
-
result = func(*args, **kwargs)
|
311
|
+
result = self.file_tracker.trace_wrapper(func)(*args, **kwargs)
|
306
312
|
|
307
313
|
# Calculate resource usage
|
308
314
|
end_memory = psutil.Process().memory_info().rss
|
@@ -384,7 +390,7 @@ class ToolTracerMixin:
|
|
384
390
|
self.start_component(component_id)
|
385
391
|
try:
|
386
392
|
# Execute the tool
|
387
|
-
result = await func(*args, **kwargs)
|
393
|
+
result = await self.file_tracker.trace_wrapper(func)(*args, **kwargs)
|
388
394
|
|
389
395
|
# Calculate resource usage
|
390
396
|
end_memory = psutil.Process().memory_info().rss
|
@@ -504,8 +510,13 @@ class ToolTracerMixin:
|
|
504
510
|
"interactions": interactions,
|
505
511
|
}
|
506
512
|
|
507
|
-
if self.
|
508
|
-
|
513
|
+
if name in self.span_attributes_dict:
|
514
|
+
span_gt = self.span_attributes_dict[name].gt
|
515
|
+
if span_gt is not None:
|
516
|
+
component["data"]["gt"] = span_gt
|
517
|
+
span_context = self.span_attributes_dict[name].context
|
518
|
+
if span_context:
|
519
|
+
component["data"]["context"] = span_context
|
509
520
|
|
510
521
|
# Reset the SpanAttributes context variable
|
511
522
|
self.span_attributes_dict[kwargs["name"]] = SpanAttributes(kwargs["name"])
|
@@ -8,6 +8,7 @@ def upload_trace_metric(json_file_path, dataset_name, project_name):
|
|
8
8
|
try:
|
9
9
|
with open(json_file_path, "r") as f:
|
10
10
|
traces = json.load(f)
|
11
|
+
|
11
12
|
metrics = get_trace_metrics_from_trace(traces)
|
12
13
|
metrics = _change_metrics_format_for_payload(metrics)
|
13
14
|
|
@@ -21,7 +22,6 @@ def upload_trace_metric(json_file_path, dataset_name, project_name):
|
|
21
22
|
metricConfig = next((user_metric["metricConfig"] for user_metric in user_trace_metrics if user_metric["displayName"] == metric["displayName"]), None)
|
22
23
|
if not metricConfig or metricConfig.get("Metric Source", {}).get("value") != "user":
|
23
24
|
raise ValueError(f"Metrics {metric['displayName']} already exist in dataset {dataset_name} of project {project_name}.")
|
24
|
-
|
25
25
|
headers = {
|
26
26
|
"Content-Type": "application/json",
|
27
27
|
"Authorization": f"Bearer {os.getenv('RAGAAI_CATALYST_TOKEN')}",
|
@@ -68,13 +68,14 @@ def get_trace_metrics_from_trace(traces):
|
|
68
68
|
# get span level metrics
|
69
69
|
for span in traces["data"][0]["spans"]:
|
70
70
|
if span["type"] == "agent":
|
71
|
+
# Add children metrics of agent
|
71
72
|
children_metric = _get_children_metrics_of_agent(span["data"]["children"])
|
72
73
|
if children_metric:
|
73
74
|
metrics.extend(children_metric)
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
|
76
|
+
metric = span.get("metrics", [])
|
77
|
+
if metric:
|
78
|
+
metrics.extend(metric)
|
78
79
|
return metrics
|
79
80
|
|
80
81
|
def _change_metrics_format_for_payload(metrics):
|
@@ -8,13 +8,32 @@ class TrackName:
|
|
8
8
|
def trace_decorator(self, func):
|
9
9
|
@wraps(func)
|
10
10
|
def wrapper(*args, **kwargs):
|
11
|
-
file_name = self.
|
11
|
+
file_name = self._get_decorated_file_name()
|
12
12
|
self.files.add(file_name)
|
13
13
|
|
14
14
|
return func(*args, **kwargs)
|
15
15
|
return wrapper
|
16
|
+
|
17
|
+
def trace_wrapper(self, func):
|
18
|
+
@wraps(func)
|
19
|
+
def wrapper(*args, **kwargs):
|
20
|
+
file_name = self._get_wrapped_file_name()
|
21
|
+
self.files.add(file_name)
|
22
|
+
return func(*args, **kwargs)
|
23
|
+
return wrapper
|
24
|
+
|
25
|
+
def _get_wrapped_file_name(self):
|
26
|
+
try:
|
27
|
+
from IPython import get_ipython
|
28
|
+
if 'IPKernelApp' in get_ipython().config:
|
29
|
+
return self._get_notebook_name()
|
30
|
+
except Exception:
|
31
|
+
pass
|
32
|
+
|
33
|
+
frame = inspect.stack()[4]
|
34
|
+
return frame.filename
|
16
35
|
|
17
|
-
def
|
36
|
+
def _get_decorated_file_name(self):
|
18
37
|
# Check if running in a Jupyter notebook
|
19
38
|
try:
|
20
39
|
from IPython import get_ipython
|
@@ -2,9 +2,9 @@ from ..data.data_structure import LLMCall
|
|
2
2
|
from .trace_utils import (
|
3
3
|
calculate_cost,
|
4
4
|
convert_usage_to_dict,
|
5
|
-
load_model_costs,
|
6
5
|
)
|
7
6
|
from importlib import resources
|
7
|
+
from litellm import model_cost
|
8
8
|
import json
|
9
9
|
import os
|
10
10
|
import asyncio
|
@@ -38,7 +38,13 @@ def extract_model_name(args, kwargs, result):
|
|
38
38
|
metadata = manager.metadata
|
39
39
|
model_name = metadata.get('ls_model_name', None)
|
40
40
|
if model_name:
|
41
|
-
model = model_name
|
41
|
+
model = model_name
|
42
|
+
|
43
|
+
if not model:
|
44
|
+
if 'to_dict' in dir(result):
|
45
|
+
result = result.to_dict()
|
46
|
+
if 'model_version' in result:
|
47
|
+
model = result['model_version']
|
42
48
|
|
43
49
|
|
44
50
|
# Normalize Google model names
|
@@ -50,11 +56,6 @@ def extract_model_name(args, kwargs, result):
|
|
50
56
|
return "gemini-1.5-pro"
|
51
57
|
if "gemini-pro" in model:
|
52
58
|
return "gemini-pro"
|
53
|
-
|
54
|
-
if 'to_dict' in dir(result):
|
55
|
-
result = result.to_dict()
|
56
|
-
if 'model_version' in result:
|
57
|
-
model = result['model_version']
|
58
59
|
|
59
60
|
return model or "default"
|
60
61
|
|
@@ -268,10 +269,21 @@ def num_tokens_from_messages(model="gpt-4o-mini-2024-07-18", prompt_messages=Non
|
|
268
269
|
}
|
269
270
|
|
270
271
|
def extract_input_data(args, kwargs, result):
|
271
|
-
"""
|
272
|
+
"""Sanitize and format input data, including handling of nested lists and dictionaries."""
|
273
|
+
|
274
|
+
def sanitize_value(value):
|
275
|
+
if isinstance(value, (int, float, bool, str)):
|
276
|
+
return value
|
277
|
+
elif isinstance(value, list):
|
278
|
+
return [sanitize_value(item) for item in value]
|
279
|
+
elif isinstance(value, dict):
|
280
|
+
return {key: sanitize_value(val) for key, val in value.items()}
|
281
|
+
else:
|
282
|
+
return str(value) # Convert non-standard types to string
|
283
|
+
|
272
284
|
return {
|
273
|
-
|
274
|
-
|
285
|
+
"args": [sanitize_value(arg) for arg in args],
|
286
|
+
"kwargs": {key: sanitize_value(val) for key, val in kwargs.items()},
|
275
287
|
}
|
276
288
|
|
277
289
|
|
@@ -370,6 +382,13 @@ def extract_llm_output(result):
|
|
370
382
|
})
|
371
383
|
return OutputResponse(output)
|
372
384
|
|
385
|
+
# Handle AIMessage Format
|
386
|
+
if hasattr(result, "content"):
|
387
|
+
return OutputResponse([{
|
388
|
+
"content": result.content,
|
389
|
+
"role": getattr(result, "role", "assistant")
|
390
|
+
}])
|
391
|
+
|
373
392
|
# Handle Vertex AI format
|
374
393
|
# format1
|
375
394
|
if hasattr(result, "text"):
|
@@ -517,7 +536,7 @@ def extract_llm_data(args, kwargs, result):
|
|
517
536
|
token_usage = extract_token_usage(result)
|
518
537
|
|
519
538
|
# Load model costs
|
520
|
-
model_costs =
|
539
|
+
model_costs = model_cost
|
521
540
|
|
522
541
|
# Calculate cost
|
523
542
|
cost = calculate_llm_cost(token_usage, model_name, model_costs)
|