From ca7a21763daaa96316cebe3b43a8fa6d293820dc Mon Sep 17 00:00:00 2001 From: Johnny Chadda Date: Wed, 30 Apr 2025 14:45:58 +0200 Subject: [PATCH 1/2] Remove processing of metric dimensions --- src/opperai/_opper.py | 62 +++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/src/opperai/_opper.py b/src/opperai/_opper.py index f3ceb82..91a75b2 100644 --- a/src/opperai/_opper.py +++ b/src/opperai/_opper.py @@ -4,7 +4,6 @@ from opperai.embeddings.async_embeddings import AsyncEmbeddings from opperai.embeddings.embeddings import Embeddings from opperai.evaluations._base import Evaluation -from opperai.evaluations.decorator import process_metrics from opperai.functions.async_functions import AsyncFunctions from opperai.functions.functions import Functions from opperai.indexes.async_indexes import AsyncIndexes @@ -98,7 +97,7 @@ async def _evaluate( span = AsyncOpper().spans.get_span(span_id=span_id) # Run each evaluator and process the metrics - for i, evaluator_result in enumerate(evaluators): + for evaluator_result in evaluators: # Check if result is a coroutine and await it if needed if inspect.iscoroutine(evaluator_result): metrics = await evaluator_result @@ -110,46 +109,27 @@ async def _evaluate( else: metrics = evaluator_result - # Get a name for this evaluator result - metric_group = None - if ( - metrics - and len(metrics) > 0 - and hasattr(metrics[0], "dimension") - and metrics[0].dimension - ): - metric_group = ( - metrics[0].dimension.split(".")[0] - if "." in metrics[0].dimension - else metrics[0].dimension + # Ensure we have a list of metrics + if not isinstance(metrics, list): + metrics = [metrics] + + # Validate that each metric has a dimension + for i, metric in enumerate(metrics): + if not metric.dimension: + raise ValueError(f"Metric at index {i} must have a dimension") + + # Save metrics directly to span + for metric in metrics: + await span.save_metric( + dimension=metric.dimension, + value=metric.value or 0.0, + comment=metric.comment or "", ) - else: - # Fallback if no dimension is available - metric_group = f"evaluator_{i}" - - # Process the metrics - eval_result = await process_metrics(metric_group, metrics) - - # Update all metrics - all_metrics.update(eval_result.metrics) - - # Save metrics to span - for group_name, group_metrics in eval_result.metrics.items(): - for metric in group_metrics: - # Create a dimension with the group name prefix if not already present - dimension = metric.dimension - if dimension and not dimension.startswith(f"eval.{group_name}"): - dimension = f"eval.{group_name}.{dimension}" - else: - # If no dimension, create one with the group name - dimension = f"eval.{group_name}" if not dimension else dimension - - # Save the metric to the span - await span.save_metric( - dimension=dimension or "", - value=metric.value or 0.0, - comment=metric.comment or "", - ) + + # Add metrics to flat list + if "metrics" not in all_metrics: + all_metrics["metrics"] = [] + all_metrics["metrics"].extend(metrics) # Create the final evaluation return Evaluation(metrics=all_metrics) From 02888209f1e08a54df4f0f296aa09821de24f9d0 Mon Sep 17 00:00:00 2001 From: Johnny Chadda Date: Wed, 30 Apr 2025 14:47:05 +0200 Subject: [PATCH 2/2] Bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8cfe91e..504400b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "opperai" -version = "0.31.1" +version = "0.31.2" description = "Opper Python client" authors = [{ name = "Opper", email = "support@opper.ai" }] requires-python = "~=3.9"