datarobot-moderations 11.2.1__py3-none-any.whl → 11.2.2__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.
@@ -667,7 +667,7 @@ def __get_otel_values(guards_list, stage, result_df):
667
667
  for guard in guards_list:
668
668
  if not guard.has_average_score_custom_metric():
669
669
  continue
670
- guard_metric_column_name = guard.get_metric_column_name(stage)
670
+ guard_metric_column_name = guard.metric_column_name
671
671
  if guard_metric_column_name not in result_df.columns:
672
672
  _logger.warning(f"Missing column: {guard_metric_column_name} in result_df")
673
673
  continue
datarobot_dome/guard.py CHANGED
@@ -230,6 +230,52 @@ moderation_config_trafaret = t.Dict(
230
230
  )
231
231
 
232
232
 
233
+ def get_metric_column_name(
234
+ guard_type: GuardType,
235
+ ootb_type: OOTBType | None,
236
+ stage: GuardStage,
237
+ model_guard_target_name: str | None = None,
238
+ metric_name: str | None = None,
239
+ ) -> str:
240
+ """Gets the metric column name. Note that this function gets used in buzok code. If you update
241
+ it, please also update the moderation library in the buzok worker image.
242
+ """
243
+ if guard_type == GuardType.MODEL:
244
+ if model_guard_target_name is None:
245
+ raise ValueError(
246
+ "For the model guard type, a valid model_guard_target_name has to be provided."
247
+ )
248
+ metric_result_key = Guard.get_stage_str(stage) + "_" + model_guard_target_name
249
+ elif guard_type == GuardType.OOTB:
250
+ if ootb_type is None:
251
+ raise ValueError("For the OOTB type, a valid OOTB guard type has to be provided.")
252
+ elif ootb_type == OOTBType.TOKEN_COUNT:
253
+ metric_result_key = Guard.get_stage_str(stage) + "_" + TOKEN_COUNT_COLUMN_NAME
254
+ elif ootb_type == OOTBType.ROUGE_1:
255
+ metric_result_key = Guard.get_stage_str(stage) + "_" + ROUGE_1_COLUMN_NAME
256
+ elif ootb_type == OOTBType.FAITHFULNESS:
257
+ metric_result_key = Guard.get_stage_str(stage) + "_" + FAITHFULLNESS_COLUMN_NAME
258
+ elif ootb_type == OOTBType.AGENT_GOAL_ACCURACY:
259
+ metric_result_key = AGENT_GOAL_ACCURACY_COLUMN_NAME
260
+ elif ootb_type == OOTBType.CUSTOM_METRIC:
261
+ if metric_name is None:
262
+ raise ValueError(
263
+ "For the custom metric type, a valid metric_name has to be provided."
264
+ )
265
+ metric_result_key = Guard.get_stage_str(stage) + "_" + metric_name
266
+ elif ootb_type == OOTBType.COST:
267
+ metric_result_key = COST_COLUMN_NAME
268
+ elif ootb_type == OOTBType.TASK_ADHERENCE:
269
+ metric_result_key = TASK_ADHERENCE_SCORE_COLUMN_NAME
270
+ else:
271
+ raise ValueError("The provided OOTB type is not implemented.")
272
+ elif guard_type == GuardType.NEMO_GUARDRAILS:
273
+ metric_result_key = Guard.get_stage_str(stage) + "_" + NEMO_GUARD_COLUMN_NAME
274
+ else:
275
+ raise ValueError("The provided guard type is not implemented.")
276
+ return metric_result_key
277
+
278
+
233
279
  class Guard(ABC):
234
280
  def __init__(self, config: dict, stage=None):
235
281
  self._name = config["name"]
@@ -244,6 +290,13 @@ class Guard(ABC):
244
290
  self._faas_url = config.get("faas_url")
245
291
  self._copy_citations = config["copy_citations"]
246
292
  self.is_agentic = config.get("is_agentic", False)
293
+ self.metric_column_name = get_metric_column_name(
294
+ config["type"],
295
+ config.get("ootb_type"),
296
+ self._stage,
297
+ config.get("model_info", {}).get("target_name"),
298
+ config["name"],
299
+ )
247
300
 
248
301
  if config.get("intervention"):
249
302
  self.intervention = GuardIntervention(config["intervention"])
@@ -448,11 +501,6 @@ class ModelGuard(Guard):
448
501
  def model_info(self):
449
502
  return self._model_info
450
503
 
451
- def get_metric_column_name(self, stage):
452
- if self.model_info is None:
453
- raise NotImplementedError("Missing model_info for model guard")
454
- return self.get_stage_str(stage) + "_" + self._model_info.target_name
455
-
456
504
  def get_span_column_name(self, _):
457
505
  if self.model_info is None:
458
506
  raise NotImplementedError("Missing model_info for model guard")
@@ -580,9 +628,6 @@ class NeMoGuard(Guard, GuardLLMMixin):
580
628
  """No average score metrics for NemoGuard's"""
581
629
  return False
582
630
 
583
- def get_metric_column_name(self, stage):
584
- return self.get_stage_str(stage) + "_" + NEMO_GUARD_COLUMN_NAME
585
-
586
631
  @property
587
632
  def nemo_llm_rails(self):
588
633
  return self._nemo_llm_rails
@@ -601,16 +646,6 @@ class OOTBGuard(Guard):
601
646
  """Latency is not tracked for token counts guards"""
602
647
  return self._ootb_type != OOTBType.TOKEN_COUNT
603
648
 
604
- def get_metric_column_name(self, stage):
605
- if self._ootb_type == OOTBType.TOKEN_COUNT:
606
- return self.get_stage_str(stage) + "_" + TOKEN_COUNT_COLUMN_NAME
607
- elif self._ootb_type == OOTBType.ROUGE_1:
608
- return self.get_stage_str(stage) + "_" + ROUGE_1_COLUMN_NAME
609
- elif self._ootb_type == OOTBType.CUSTOM_METRIC:
610
- return self.get_stage_str(stage) + "_" + self.name
611
- else:
612
- raise NotImplementedError(f"No metric column name defined for {self._ootb_type} guard")
613
-
614
649
  def get_span_column_name(self, _):
615
650
  if self._ootb_type == OOTBType.TOKEN_COUNT:
616
651
  return TOKEN_COUNT_COLUMN_NAME
@@ -640,9 +675,6 @@ class OOTBCostMetric(OOTBGuard):
640
675
  self.output_unit = cost_config["output_unit"]
641
676
  self.output_multiplier = self.output_price / self.output_unit
642
677
 
643
- def get_metric_column_name(self, _):
644
- return COST_COLUMN_NAME
645
-
646
678
  def get_average_score_custom_metric_name(self, _):
647
679
  return f"Total cost in {self.currency}"
648
680
 
@@ -681,9 +713,6 @@ class FaithfulnessGuard(OOTBGuard, GuardLLMMixin):
681
713
  Settings.embed_model = None
682
714
  self._evaluator = FaithfulnessEvaluator()
683
715
 
684
- def get_metric_column_name(self, stage):
685
- return self.get_stage_str(stage) + "_" + FAITHFULLNESS_COLUMN_NAME
686
-
687
716
  @property
688
717
  def faithfulness_evaluator(self):
689
718
  return self._evaluator
@@ -708,9 +737,6 @@ class AgentGoalAccuracyGuard(OOTBGuard, GuardLLMMixin):
708
737
  evaluator_llm = LangchainLLMWrapper(llm)
709
738
  self.scorer = AgentGoalAccuracyWithoutReference(llm=evaluator_llm)
710
739
 
711
- def get_metric_column_name(self, _):
712
- return AGENT_GOAL_ACCURACY_COLUMN_NAME
713
-
714
740
  @property
715
741
  def accuracy_scorer(self):
716
742
  return self.scorer
@@ -735,9 +761,6 @@ class TaskAdherenceGuard(OOTBGuard, GuardLLMMixin):
735
761
  deepeval_llm = ModerationDeepEvalLLM(llm)
736
762
  self.scorer = TaskCompletionMetric(model=deepeval_llm, include_reason=True)
737
763
 
738
- def get_metric_column_name(self, _):
739
- return TASK_ADHERENCE_SCORE_COLUMN_NAME
740
-
741
764
  @property
742
765
  def task_adherence_scorer(self):
743
766
  return self.scorer
@@ -113,7 +113,7 @@ class AsyncGuardExecutor:
113
113
  if guard.has_latency_custom_metric():
114
114
  self.pipeline.report_guard_latency(guard, latency)
115
115
  if guard.has_average_score_custom_metric():
116
- metric_column_name = guard.get_metric_column_name(stage)
116
+ metric_column_name = guard.metric_column_name
117
117
  if metric_column_name in df.columns:
118
118
  span.set_attribute(
119
119
  guard.get_span_attribute_name(stage),
@@ -222,7 +222,7 @@ class AsyncGuardExecutor:
222
222
  # and "Response_toxicity_toxic_PREDICTION", if toxicity is configured for both
223
223
  # prompts and responses
224
224
  copy_df.rename(
225
- columns={metric_column: guard.get_metric_column_name(stage)},
225
+ columns={metric_column: guard.metric_column_name},
226
226
  inplace=True,
227
227
  )
228
228
  except Exception as ex:
@@ -359,7 +359,7 @@ class AsyncGuardExecutor:
359
359
  else:
360
360
  prompt_column_name = self.pipeline.get_input_column(GuardStage.PROMPT)
361
361
  response_column_name = self.pipeline.get_input_column(GuardStage.RESPONSE)
362
- metric_column_name = guard.get_metric_column_name(stage)
362
+ metric_column_name = guard.metric_column_name
363
363
 
364
364
  try:
365
365
  copy_df[metric_column_name] = copy_df.apply(
@@ -407,7 +407,7 @@ class AsyncGuardExecutor:
407
407
  else:
408
408
  prompt_column_name = self.pipeline.get_input_column(GuardStage.PROMPT)
409
409
  response_column_name = self.pipeline.get_input_column(GuardStage.RESPONSE)
410
- metric_column_name = guard.get_metric_column_name(stage)
410
+ metric_column_name = guard.metric_column_name
411
411
 
412
412
  try:
413
413
  copy_df[metric_column_name] = copy_df.apply(
@@ -454,7 +454,7 @@ class AsyncGuardExecutor:
454
454
  else:
455
455
  prompt_column_name = self.pipeline.get_input_column(GuardStage.PROMPT)
456
456
  response_column_name = self.pipeline.get_input_column(GuardStage.RESPONSE)
457
- metric_column_name = guard.get_metric_column_name(stage)
457
+ metric_column_name = guard.metric_column_name
458
458
 
459
459
  try:
460
460
  copy_df[metric_column_name] = copy_df.apply(
@@ -500,7 +500,7 @@ class AsyncGuardExecutor:
500
500
  intervene = False
501
501
  else:
502
502
  input_column = self.pipeline.get_input_column(stage)
503
- metric_column_name = guard.get_metric_column_name(stage)
503
+ metric_column_name = guard.metric_column_name
504
504
  copy_df[metric_column_name] = copy_df.apply(
505
505
  lambda x: get_rouge_1_score(
506
506
  scorer=self.pipeline.rouge_scorer,
@@ -517,7 +517,7 @@ class AsyncGuardExecutor:
517
517
 
518
518
  prompt_column_name = self.pipeline.get_input_column(GuardStage.PROMPT)
519
519
  response_column_name = self.pipeline.get_input_column(GuardStage.RESPONSE)
520
- metric_column_name = guard.get_metric_column_name(stage)
520
+ metric_column_name = guard.metric_column_name
521
521
  if (
522
522
  PROMPT_TOKEN_COUNT_COLUMN_NAME_FROM_USAGE not in copy_df.columns
523
523
  or RESPONSE_TOKEN_COUNT_COLUMN_NAME_FROM_USAGE not in copy_df.columns
@@ -539,7 +539,7 @@ class AsyncGuardExecutor:
539
539
  if not isinstance(guard, OOTBGuard):
540
540
  raise ValueError(f"Guard object should be of type OOTBGuard, got: {type(guard)}")
541
541
  input_column = self.pipeline.get_input_column(stage)
542
- metric_column_name = guard.get_metric_column_name(stage)
542
+ metric_column_name = guard.metric_column_name
543
543
  intervene = self._should_intervene(guard)
544
544
 
545
545
  if guard.ootb_type == OOTBType.TOKEN_COUNT:
@@ -594,7 +594,7 @@ class AsyncGuardExecutor:
594
594
  raise ValueError(f"Guard object should be of type NeMoGuard, got: {type(guard)}")
595
595
 
596
596
  input_column = self.pipeline.get_input_column(stage)
597
- metric_column_name = guard.get_metric_column_name(stage)
597
+ metric_column_name = guard.metric_column_name
598
598
  intervene = self._should_intervene(guard)
599
599
 
600
600
  try:
@@ -304,7 +304,7 @@ class LLMPipeline(Pipeline):
304
304
  metric_list = [
305
305
  (
306
306
  guard.get_average_score_custom_metric_name(guard.stage),
307
- guard.get_metric_column_name(guard.stage),
307
+ guard.metric_column_name,
308
308
  )
309
309
  ]
310
310
  if intervention_action:
@@ -323,7 +323,7 @@ class ModerationIterator:
323
323
  self.aggregated_metrics_df[column_name] = metrics_df[column_name]
324
324
  elif guard.type == GuardType.OOTB:
325
325
  if guard.ootb_type == OOTBType.TOKEN_COUNT:
326
- column_name = guard.get_metric_column_name(GuardStage.RESPONSE)
326
+ column_name = guard.metric_column_name
327
327
  self.aggregated_metrics_df[column_name] += metrics_df[column_name]
328
328
  else:
329
329
  # Faithfulness, ROUGE-1 can't run on chunks so no merging
@@ -368,7 +368,7 @@ class ModerationIterator:
368
368
  postscore_df = postscore_df_chunk.copy(deep=True)
369
369
  for guard in self.pipeline.get_postscore_guards():
370
370
  if not self._guard_can_work_on_chunk(guard):
371
- metric_column_name = guard.get_metric_column_name(GuardStage.RESPONSE)
371
+ metric_column_name = guard.metric_column_name
372
372
  if metric_column_name in postscore_df_assembled.columns:
373
373
  postscore_df[metric_column_name] = postscore_df_assembled[metric_column_name]
374
374
  if guard.has_latency_custom_metric():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: datarobot-moderations
3
- Version: 11.2.1
3
+ Version: 11.2.2
4
4
  Summary: DataRobot Monitoring and Moderation framework
5
5
  License: DataRobot Tool and Utility Agreement
6
6
  Author: DataRobot
@@ -15,7 +15,7 @@ Requires-Dist: aiohttp (>=3.9.5)
15
15
  Requires-Dist: backoff (>=2.2.1)
16
16
  Requires-Dist: datarobot (>=3.6.0)
17
17
  Requires-Dist: datarobot-predict (>=1.9.6)
18
- Requires-Dist: deepeval (==2.7.9)
18
+ Requires-Dist: deepeval (>=3.3.5)
19
19
  Requires-Dist: langchain (>=0.1.12)
20
20
  Requires-Dist: langchain-nvidia-ai-endpoints (>=0.3.9)
21
21
  Requires-Dist: langchain-openai (>=0.1.7)
@@ -2,9 +2,9 @@ datarobot_dome/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,58
2
2
  datarobot_dome/async_http_client.py,sha256=wkB4irwvnchNGzO1bk2C_HWM-GOSB3AUn5TXKl-X0ZI,9649
3
3
  datarobot_dome/chat_helper.py,sha256=BzvtUyZSZxzOqq-5a2wQKhHhr2kMlcP1MFrHaDAeD_o,9671
4
4
  datarobot_dome/constants.py,sha256=vM2_JkXbn4dkWARCqxNfLriSo0E05LDXVrwNktptpuc,10416
5
- datarobot_dome/drum_integration.py,sha256=HresblJwlCk_sRnWReWQWeZMg5rYzKTA2hjmy1Rcn6U,40553
6
- datarobot_dome/guard.py,sha256=1INYx17n9ToiB5bzI-jIReUUuqkK_ucxpOx4jQLts6g,33264
7
- datarobot_dome/guard_executor.py,sha256=AOI8MZeZETHMoFgBePe0wa2vE9d2975MYQnEDHLZL7s,35462
5
+ datarobot_dome/drum_integration.py,sha256=BnhAP-D4AaEeh4ferZ-qXnORuWQzYzw9qKAZUTZZnJU,40542
6
+ datarobot_dome/guard.py,sha256=ecpHnIOCEniTMgnVnqlYuU6HnR4baP9ruWaczv5q2lA,34496
7
+ datarobot_dome/guard_executor.py,sha256=ox5_jOHcqMaxaaagIYJJHhCwEI7Wg-rUEiu5rutsfVU,35363
8
8
  datarobot_dome/guard_helpers.py,sha256=ajxm-w7MS7eN5DMMO-jbbzjcOYMZ-LvhO53n2NI5_Fk,16773
9
9
  datarobot_dome/guards/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,583
10
10
  datarobot_dome/guards/guard_llm_mixin.py,sha256=VovlpNZjWIGamF4SSvLF5lzOFyApH5IoOiB_qtCmRg0,12216
@@ -14,11 +14,11 @@ datarobot_dome/metrics/citation_metrics.py,sha256=l2mnV1gz7nQeJ_yfaS4dcP3DFWf0p5
14
14
  datarobot_dome/metrics/factory.py,sha256=7caa8paI9LuFXDgguXdC4on28V7IwwIsKJT2Z-Aps8A,2187
15
15
  datarobot_dome/metrics/metric_scorer.py,sha256=uJ_IJRw7ZFHueg8xjsaXbt0ypO7JiydZ0WapCp96yng,2540
16
16
  datarobot_dome/pipeline/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,583
17
- datarobot_dome/pipeline/llm_pipeline.py,sha256=g7PAiLOMADr2DQFrtg2NrUj4u_tcvnoiJXrBR8xWsmY,18789
17
+ datarobot_dome/pipeline/llm_pipeline.py,sha256=DMZ4gu88MiSSEQtshDyHOzT3R2Seuf8UqZ7A36QHj3M,18772
18
18
  datarobot_dome/pipeline/pipeline.py,sha256=7UmvrZtNxTGewpgM4cf2oThHPoJSarEU1Dyp7xEsASU,17401
19
19
  datarobot_dome/pipeline/vdb_pipeline.py,sha256=q3c_Z-hGUqhH6j6n8VpS3wZiBIkWgpRDsBnyJyZhiw4,9855
20
20
  datarobot_dome/runtime.py,sha256=FD8wXOweqoQVzbZMh-mucL66xT2kGxPsJUGAcJBgwxw,1468
21
- datarobot_dome/streaming.py,sha256=6nYvh6SoxPRLfO6GGdEoHsQuyLP9oX1lDMe8IeGo4lw,17801
22
- datarobot_moderations-11.2.1.dist-info/METADATA,sha256=fEyM5I3z0qS9dT2ofZ3J8UAN_ybm2SBF_46mifEHIpA,4742
23
- datarobot_moderations-11.2.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
24
- datarobot_moderations-11.2.1.dist-info/RECORD,,
21
+ datarobot_dome/streaming.py,sha256=DkvKEH0yN0aPEWMTAjMFJB3Kx4iLGdjUMQU1pAplbeg,17751
22
+ datarobot_moderations-11.2.2.dist-info/METADATA,sha256=YLN3wvaq5UGP5hnJAD34DxbvACuGuH-RGUE_zCJbfBs,4742
23
+ datarobot_moderations-11.2.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
24
+ datarobot_moderations-11.2.2.dist-info/RECORD,,