datarobot-moderations 11.2.11__py3-none-any.whl → 11.2.12__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.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -254,8 +254,9 @@ class GuardLLMType:
254
254
  AMAZON = "amazon"
255
255
  DATAROBOT = "datarobot"
256
256
  NIM = "nim"
257
+ LLM_GATEWAY = "llmGateway"
257
258
 
258
- ALL = [OPENAI, AZURE_OPENAI, GOOGLE, AMAZON, DATAROBOT, NIM]
259
+ ALL = [OPENAI, AZURE_OPENAI, GOOGLE, AMAZON, DATAROBOT, NIM, LLM_GATEWAY]
259
260
 
260
261
 
261
262
  class GoogleModel:
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -31,6 +31,7 @@ from datarobot_dome.constants import GuardStage
31
31
  from datarobot_dome.constants import GuardTimeoutAction
32
32
  from datarobot_dome.constants import GuardType
33
33
  from datarobot_dome.constants import ModerationEventTypes
34
+ from datarobot_dome.constants import NemoEvaluatorType
34
35
  from datarobot_dome.constants import OOTBType
35
36
  from datarobot_dome.guard_helpers import calculate_agent_goal_accuracy
36
37
  from datarobot_dome.guard_helpers import calculate_agent_guideline_adherence
@@ -43,6 +44,7 @@ from datarobot_dome.guard_helpers import get_token_count
43
44
  from datarobot_dome.guard_helpers import nemo_response_stage_input_formatter
44
45
  from datarobot_dome.guard_helpers import nemo_response_stage_output_formatter
45
46
  from datarobot_dome.guards import ModelGuard
47
+ from datarobot_dome.guards import NeMoEvaluatorGuard
46
48
  from datarobot_dome.guards import NeMoGuard
47
49
  from datarobot_dome.guards import OOTBAgentGoalAccuracyGuard
48
50
  from datarobot_dome.guards import OOTBCostMetric
@@ -88,6 +90,7 @@ class AsyncGuardExecutor:
88
90
  GuardType.MODEL: "run_model_guard",
89
91
  GuardType.OOTB: "run_ootb_guard",
90
92
  GuardType.NEMO_GUARDRAILS: "run_nemo_guard",
93
+ GuardType.NEMO_EVALUATOR: "run_nemo_evaluator_guard",
91
94
  }
92
95
 
93
96
  def __init__(self, pipeline):
@@ -680,6 +683,62 @@ class AsyncGuardExecutor:
680
683
  copy_df = self._dont_intervene(guard, copy_df, stage)
681
684
  return copy_df
682
685
 
686
+ async def run_nemo_evaluator_guard(self, guard: NeMoEvaluatorGuard, copy_df, stage):
687
+ if not isinstance(guard, NeMoEvaluatorGuard):
688
+ raise ValueError(
689
+ f"Guard object should be of type NeMoEvaluatorGuard, got: {type(guard)}"
690
+ )
691
+ if guard.nemo_evaluator_type != NemoEvaluatorType.LLM_JUDGE and stage == GuardStage.PROMPT:
692
+ raise ValueError(
693
+ f"NeMoEvaluatorGuard of type {guard.nemo_evaluator_type} "
694
+ f"can only be applied to response stage"
695
+ )
696
+
697
+ # get column names
698
+ prompt_column_name = self.pipeline.get_input_column(GuardStage.PROMPT)
699
+ response_column_name = self.pipeline.get_input_column(GuardStage.RESPONSE)
700
+ citation_column_names = get_citation_columns(copy_df.columns)
701
+
702
+ # check citation / reference context columns exist when required
703
+ if (
704
+ guard.nemo_evaluator_type
705
+ in [
706
+ NemoEvaluatorType.CONTEXT_RELEVANCE,
707
+ NemoEvaluatorType.RESPONSE_GROUNDEDNESS,
708
+ NemoEvaluatorType.FAITHFULNESS,
709
+ ]
710
+ and not citation_column_names
711
+ ):
712
+ raise ValueError(
713
+ f"NeMoEvaluatorGuard of type {guard.nemo_evaluator_type} is configured without "
714
+ f"citation columns. Input Column Names: {', '.join(copy_df.columns.to_list())}."
715
+ )
716
+
717
+ # compute score
718
+ scores = await asyncio.gather(
719
+ *(
720
+ guard.evaluate(
721
+ prompt=row.get(prompt_column_name),
722
+ response=row.get(response_column_name),
723
+ retrieved_contexts=[
724
+ row[column]
725
+ for column in citation_column_names
726
+ if row.get(column) is not None
727
+ ],
728
+ )
729
+ for row in copy_df.to_dict(orient="records")
730
+ )
731
+ )
732
+ copy_df[guard.metric_column_name] = scores
733
+
734
+ # handle intervention
735
+ if self._should_intervene(guard):
736
+ copy_df, _ = self._intervene(guard, copy_df, stage, guard.metric_column_name)
737
+ else:
738
+ copy_df = self._dont_intervene(guard, copy_df, stage)
739
+
740
+ return copy_df
741
+
683
742
  def run_guards(self, input_df, guards, stage):
684
743
  start_time = time.time()
685
744
  df = self.loop.run_until_complete(self.async_guard_executor(input_df, guards, stage))
@@ -756,6 +815,9 @@ class AsyncGuardExecutor:
756
815
  join_columns.add(self.pipeline.get_input_column(GuardStage.PROMPT))
757
816
  if guard.ootb_type in [OOTBType.AGENT_GOAL_ACCURACY, OOTBType.TASK_ADHERENCE]:
758
817
  join_columns.add(AGENTIC_PIPELINE_INTERACTIONS_ATTR)
818
+ elif stage == GuardStage.RESPONSE and isinstance(guard, NeMoEvaluatorGuard):
819
+ join_columns.add(self.pipeline.get_input_column(GuardStage.PROMPT))
820
+ join_columns = join_columns.union(set(get_citation_columns(_input_df.columns)))
759
821
  copy_df = _input_df[list(join_columns)].copy(deep=True)
760
822
  return copy_df, join_columns
761
823
 
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -10,8 +10,18 @@
10
10
  # https://www.datarobot.com/wp-content/uploads/2021/07/DataRobot-Tool-and-Utility-Agreement.pdf.
11
11
  # ---------------------------------------------------------------------------------
12
12
  from functools import cached_property
13
+ from typing import Optional
13
14
 
15
+ import requests
14
16
  from nemo_microservices import AsyncNeMoMicroservices
17
+ from nemo_microservices.types import EvaluationConfigParam
18
+ from nemo_microservices.types import EvaluationTargetParam
19
+ from nemo_microservices.types import LiveEvaluation
20
+ from nemo_microservices.types import MetricConfigParam
21
+ from nemo_microservices.types import TaskConfigParam
22
+
23
+ from datarobot_dome.constants import GuardLLMType
24
+ from datarobot_dome.guard_helpers import get_datarobot_endpoint_and_token
15
25
 
16
26
  from .base import Guard
17
27
 
@@ -22,6 +32,7 @@ class NeMoEvaluatorGuard(Guard):
22
32
  self.nemo_evaluator_type = config["nemo_evaluator_type"]
23
33
  self._llm_type = config["llm_type"]
24
34
  self.llm_deployment_id = config.get("deployment_id")
35
+ self.llm_gateway_model_id = config.get("llm_gateway_model_id")
25
36
 
26
37
  @cached_property
27
38
  def _client(self) -> AsyncNeMoMicroservices:
@@ -31,43 +42,288 @@ class NeMoEvaluatorGuard(Guard):
31
42
  """
32
43
  return AsyncNeMoMicroservices(base_url="http://localhost:8080")
33
44
 
45
+ @staticmethod
46
+ def _get_default_model_id(deployment_id: str) -> str:
47
+ """Get id of first model as default from a deployment that responds to /models endpoint."""
48
+ datarobot_endpoint, datarobot_api_token = get_datarobot_endpoint_and_token()
49
+ response = requests.get(
50
+ f"{datarobot_endpoint}/deployments/{deployment_id}/directAccess/models",
51
+ headers={"Authorization": f"Bearer {datarobot_api_token}"},
52
+ )
53
+ if response.status_code != 200:
54
+ raise ValueError(f"Unable to query for default model for deployment {deployment_id}")
55
+ try:
56
+ return response.json()["data"][0]["id"]
57
+ except (requests.JSONDecodeError, KeyError, IndexError, TypeError):
58
+ raise ValueError(f"Unable to select default model for deployment {deployment_id}")
59
+
60
+ @cached_property
61
+ def llm_judge_api_endpoint(self) -> dict:
62
+ """LLM Judge API endpoint, to be passed to NeMo evaluator."""
63
+ datarobot_endpoint, datarobot_api_token = get_datarobot_endpoint_and_token()
64
+ if self.llm_type == GuardLLMType.DATAROBOT:
65
+ url = f"{datarobot_endpoint}/deployments/{self.llm_deployment_id}/chat/completions"
66
+ model_id = self._get_default_model_id(self.llm_deployment_id)
67
+ elif self.llm_type == GuardLLMType.LLM_GATEWAY:
68
+ url = f"{datarobot_endpoint}/genai/llmgw/chat/completions"
69
+ model_id = self.llm_gateway_model_id
70
+ else:
71
+ raise ValueError(
72
+ f"LLM type {self.llm_type} is not supported by NeMo Evaluator based guards."
73
+ )
74
+ return {"url": url, "api_key": datarobot_api_token, "model_id": model_id}
75
+
34
76
  def has_average_score_custom_metric(self) -> bool:
35
77
  return False
36
78
 
37
- async def evaluate(self, prompt: str, response: str) -> float:
79
+ async def evaluate(
80
+ self,
81
+ *,
82
+ prompt: Optional[str],
83
+ response: Optional[str],
84
+ retrieved_contexts: Optional[list[str]],
85
+ ) -> float:
38
86
  raise NotImplementedError
39
87
 
88
+ def _extract_score(self, evaluation: LiveEvaluation) -> int | float:
89
+ task = evaluation.result.tasks[self.nemo_evaluator_type]
90
+ metric = task.metrics[self.nemo_evaluator_type]
91
+ score = metric.scores[self.nemo_evaluator_type]
92
+ return score.value
93
+
40
94
 
41
95
  class NeMoLLMJudgeGuard(NeMoEvaluatorGuard):
42
96
  def __init__(self, config: dict, stage=None):
43
97
  super().__init__(config, stage)
98
+ self.nemo_llm_judge_config = config.get("nemo_llm_judge_config", {})
99
+
100
+ async def evaluate(self, *, prompt: str, response: str, **kwargs) -> float:
101
+ system_prompt = self.nemo_llm_judge_config["system_prompt"]
102
+ user_prompt = self.nemo_llm_judge_config["user_prompt"]
103
+ score_parsing_regex = self.nemo_llm_judge_config["score_parsing_regex"]
104
+
105
+ config = EvaluationConfigParam(
106
+ type="custom",
107
+ tasks={
108
+ self.nemo_evaluator_type: TaskConfigParam(
109
+ type="data",
110
+ metrics={
111
+ self.nemo_evaluator_type: MetricConfigParam(
112
+ type="llm-judge",
113
+ params={
114
+ "model": {"api_endpoint": self.llm_judge_api_endpoint},
115
+ "template": {
116
+ "messages": [
117
+ {"role": "system", "content": system_prompt},
118
+ {"role": "user", "content": user_prompt},
119
+ ]
120
+ },
121
+ "scores": {
122
+ self.nemo_evaluator_type: {
123
+ "type": "int",
124
+ "parser": {"type": "regex", "pattern": score_parsing_regex},
125
+ }
126
+ },
127
+ },
128
+ )
129
+ },
130
+ )
131
+ },
132
+ )
133
+ target = EvaluationTargetParam(
134
+ type="rows", rows=[{"promptText": prompt, "responseText": response}]
135
+ )
136
+ evaluation = await self._client.evaluation.live(config=config, target=target)
137
+ return self._extract_score(evaluation)
44
138
 
45
139
 
46
140
  class NeMoContextRelevanceGuard(NeMoEvaluatorGuard):
47
- def __init__(self, config: dict, stage=None):
48
- super().__init__(config, stage)
141
+ async def evaluate(self, *, prompt: str, retrieved_contexts: list[str], **kwargs) -> float:
142
+ config = EvaluationConfigParam(
143
+ type="custom",
144
+ tasks={
145
+ self.nemo_evaluator_type: TaskConfigParam(
146
+ type="data",
147
+ metrics={
148
+ self.nemo_evaluator_type: MetricConfigParam(
149
+ type=self.nemo_evaluator_type,
150
+ params={
151
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
152
+ },
153
+ )
154
+ },
155
+ )
156
+ },
157
+ )
158
+ target = EvaluationTargetParam(
159
+ type="rows",
160
+ rows=[{"user_input": prompt, "retrieved_contexts": retrieved_contexts}],
161
+ )
162
+ evaluation = await self._client.evaluation.live(config=config, target=target)
163
+ return self._extract_score(evaluation)
49
164
 
50
165
 
51
166
  class NeMoResponseGroundednessGuard(NeMoEvaluatorGuard):
52
- def __init__(self, config: dict, stage=None):
53
- super().__init__(config, stage)
167
+ async def evaluate(self, *, response: str, retrieved_contexts: list[str], **kwargs) -> float:
168
+ config = EvaluationConfigParam(
169
+ type="custom",
170
+ tasks={
171
+ self.nemo_evaluator_type: TaskConfigParam(
172
+ type="data",
173
+ metrics={
174
+ self.nemo_evaluator_type: MetricConfigParam(
175
+ type=self.nemo_evaluator_type,
176
+ params={
177
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
178
+ },
179
+ )
180
+ },
181
+ )
182
+ },
183
+ )
184
+ target = EvaluationTargetParam(
185
+ type="rows",
186
+ rows=[{"response": response, "retrieved_contexts": retrieved_contexts}],
187
+ )
188
+ evaluation = await self._client.evaluation.live(config=config, target=target)
189
+ return self._extract_score(evaluation)
54
190
 
55
191
 
56
192
  class NeMoTopicAdherenceGuard(NeMoEvaluatorGuard):
57
193
  def __init__(self, config: dict, stage=None):
58
194
  super().__init__(config, stage)
195
+ self.nemo_topic_adherence_config = config["nemo_topic_adherence_config"]
196
+
197
+ async def evaluate(self, *, prompt: str, response: str, **kwargs) -> float:
198
+ config = EvaluationConfigParam(
199
+ type="custom",
200
+ tasks={
201
+ self.nemo_evaluator_type: TaskConfigParam(
202
+ type="data",
203
+ metrics={
204
+ self.nemo_evaluator_type: MetricConfigParam(
205
+ type=self.nemo_evaluator_type,
206
+ params={
207
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
208
+ "metric_mode": self.nemo_topic_adherence_config["metric_mode"],
209
+ },
210
+ )
211
+ },
212
+ )
213
+ },
214
+ )
215
+ target = EvaluationTargetParam(
216
+ type="rows",
217
+ rows=[
218
+ {
219
+ "user_input": [
220
+ {"content": prompt, "type": "human"},
221
+ {"content": response, "type": "ai"},
222
+ ],
223
+ "reference_topics": self.nemo_topic_adherence_config["reference_topics"],
224
+ }
225
+ ],
226
+ )
227
+ evaluation = await self._client.evaluation.live(config=config, target=target)
228
+ return self._extract_score(evaluation)
59
229
 
60
230
 
61
231
  class NeMoAgentGoalAccuracyGuard(NeMoEvaluatorGuard):
62
- def __init__(self, config: dict, stage=None):
63
- super().__init__(config, stage)
232
+ async def evaluate(self, *, prompt: str, response: str, **kwargs) -> float:
233
+ config = EvaluationConfigParam(
234
+ type="custom",
235
+ tasks={
236
+ self.nemo_evaluator_type: TaskConfigParam(
237
+ type="data",
238
+ metrics={
239
+ self.nemo_evaluator_type: MetricConfigParam(
240
+ type=self.nemo_evaluator_type,
241
+ params={
242
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
243
+ "use_reference": False,
244
+ },
245
+ )
246
+ },
247
+ )
248
+ },
249
+ )
250
+ target = EvaluationTargetParam(
251
+ type="rows",
252
+ rows=[
253
+ {
254
+ "user_input": [
255
+ {"content": prompt, "type": "human"},
256
+ {"content": response, "type": "ai"},
257
+ ],
258
+ }
259
+ ],
260
+ )
261
+ evaluation = await self._client.evaluation.live(config=config, target=target)
262
+ return self._extract_score(evaluation)
64
263
 
65
264
 
66
265
  class NeMoResponseRelevancyGuard(NeMoEvaluatorGuard):
67
266
  def __init__(self, config: dict, stage=None):
68
267
  super().__init__(config, stage)
268
+ self.response_relevancy_config = config["nemo_response_relevancy_config"]
269
+
270
+ @cached_property
271
+ def embedding_judge_api_endpoint(self) -> dict:
272
+ """Embedding judge API endpoint, to be passed to NeMo evaluator."""
273
+ datarobot_endpoint, datarobot_api_token = get_datarobot_endpoint_and_token()
274
+ deployment_id = self.response_relevancy_config["embedding_deployment_id"]
275
+ url = f"{datarobot_endpoint}/deployments/{deployment_id}/directAccess/nim/v1/"
276
+ return {"url": url, "api_key": datarobot_api_token, "model_id": ""}
277
+
278
+ async def evaluate(
279
+ self, *, prompt: str, response: str, retrieved_context: Optional[list[str]]
280
+ ) -> float:
281
+ config = EvaluationConfigParam(
282
+ type="custom",
283
+ tasks={
284
+ self.nemo_evaluator_type: TaskConfigParam(
285
+ type="data",
286
+ metrics={
287
+ self.nemo_evaluator_type: MetricConfigParam(
288
+ type=self.nemo_evaluator_type,
289
+ params={
290
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
291
+ "judge_embeddings": {
292
+ "model": {"api_endpoint": self.embedding_judge_api_endpoint},
293
+ },
294
+ },
295
+ )
296
+ },
297
+ )
298
+ },
299
+ )
300
+ row = {"user_input": prompt, "response": response}
301
+ if retrieved_context:
302
+ row["retrieved_contexts"] = retrieved_context
303
+ target = EvaluationTargetParam(type="rows", rows=[row])
304
+ evaluation = await self._client.evaluation.live(config=config, target=target)
305
+ return self._extract_score(evaluation)
69
306
 
70
307
 
71
308
  class NeMoFaithfulnessGuard(NeMoEvaluatorGuard):
72
- def __init__(self, config: dict, stage=None):
73
- super().__init__(config, stage)
309
+ async def evaluate(self, *, prompt: str, response: str, retrieved_contexts: list[str]) -> float:
310
+ config = EvaluationConfigParam(
311
+ type="custom",
312
+ tasks={
313
+ self.nemo_evaluator_type: TaskConfigParam(
314
+ type="data",
315
+ metrics={
316
+ self.nemo_evaluator_type: MetricConfigParam(
317
+ type=self.nemo_evaluator_type,
318
+ params={
319
+ "judge": {"model": {"api_endpoint": self.llm_judge_api_endpoint}},
320
+ },
321
+ )
322
+ },
323
+ )
324
+ },
325
+ )
326
+ row = {"user_input": prompt, "response": response, "retrieved_contexts": retrieved_contexts}
327
+ target = EvaluationTargetParam(type="rows", rows=[row])
328
+ evaluation = await self._client.evaluation.live(config=config, target=target)
329
+ return self._extract_score(evaluation)
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -87,6 +87,8 @@ class NeMoGuard(Guard, GuardLLMMixin):
87
87
  raise NotImplementedError
88
88
  elif self.llm_type == GuardLLMType.DATAROBOT:
89
89
  raise NotImplementedError
90
+ elif self.llm_type == GuardLLMType.LLM_GATEWAY:
91
+ raise NotImplementedError
90
92
  elif self.llm_type == GuardLLMType.NIM:
91
93
  if config.get("deployment_id") is None:
92
94
  if self.openai_api_base is None:
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -35,6 +35,7 @@ MAX_REGEX_LENGTH = 255
35
35
  MAX_URL_LENGTH = 255
36
36
  MAX_TOKEN_LENGTH = 255
37
37
  MAX_GUIDELINE_LENGTH = 4096
38
+ MAX_REFERENCE_TOPIC_LENGTH = 4096
38
39
 
39
40
  cost_metric_trafaret = t.Dict(
40
41
  {
@@ -72,6 +73,30 @@ model_info_trafaret = t.Dict(
72
73
  )
73
74
 
74
75
 
76
+ nemo_llm_judge_config_trafaret = t.Dict(
77
+ {
78
+ t.Key("system_prompt", optional=False): t.String(),
79
+ t.Key("user_prompt", optional=False): t.String(),
80
+ t.Key("score_parsing_regex", optional=False): t.String(max_length=MAX_REGEX_LENGTH),
81
+ },
82
+ )
83
+
84
+ nemo_topic_adherence_config_trafaret = t.Dict(
85
+ {
86
+ t.Key("metric_mode", optional=False): t.Enum("f1", "recall", "precision"),
87
+ t.Key("reference_topics", optional=False): t.List(
88
+ t.String(max_length=MAX_REFERENCE_TOPIC_LENGTH)
89
+ ),
90
+ },
91
+ )
92
+
93
+ nemo_response_relevancy_config_trafaret = t.Dict(
94
+ {
95
+ t.Key("embedding_deployment_id", optional=False): t.String(max_length=OBJECT_ID_LENGTH),
96
+ },
97
+ )
98
+
99
+
75
100
  model_guard_intervention_trafaret = t.Dict(
76
101
  {
77
102
  t.Key("comparand", to_name="comparand", optional=False): t.Or(
@@ -135,7 +160,15 @@ guard_trafaret = t.Dict(
135
160
  t.Key("deployment_id", to_name="deployment_id", optional=True): t.Or(
136
161
  t.String(max_length=OBJECT_ID_LENGTH), t.Null
137
162
  ),
163
+ t.Key("llm_gateway_model_id", to_name="llm_gateway_model_id", optional=True): t.Or(
164
+ t.String, t.Null
165
+ ),
138
166
  t.Key("model_info", to_name="model_info", optional=True): model_info_trafaret,
167
+ t.Key("nemo_llm_judge_config", optional=True): nemo_llm_judge_config_trafaret,
168
+ t.Key("nemo_topic_adherence_config", optional=True): nemo_topic_adherence_config_trafaret,
169
+ t.Key(
170
+ "nemo_response_relevancy_config", optional=True
171
+ ): nemo_response_relevancy_config_trafaret,
139
172
  t.Key("intervention", to_name="intervention", optional=True): t.Or(
140
173
  guard_intervention_trafaret, t.Null
141
174
  ),
datarobot_dome/llm.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
datarobot_dome/runtime.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  # ---------------------------------------------------------------------------------
2
2
  # Copyright (c) 2026 DataRobot, Inc. and its affiliates. All rights reserved.
3
- # Last updated 2025.
3
+ # Last updated 2026.
4
4
  #
5
5
  # DataRobot, Inc. Confidential.
6
6
  # This is proprietary source code of DataRobot, Inc. and its affiliates.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datarobot-moderations
3
- Version: 11.2.11
3
+ Version: 11.2.12
4
4
  Summary: DataRobot Monitoring and Moderation framework
5
5
  License: DataRobot Tool and Utility Agreement
6
6
  Author: DataRobot
@@ -25,7 +25,7 @@ Requires-Dist: llama-index-llms-bedrock-converse (>=0.1.6)
25
25
  Requires-Dist: llama-index-llms-langchain (>=0.1.3)
26
26
  Requires-Dist: llama-index-llms-vertex (>=0.1.5)
27
27
  Requires-Dist: nemo-microservices (>=1.5.0,<2.0.0)
28
- Requires-Dist: nemoguardrails (>=0.9.0)
28
+ Requires-Dist: nemoguardrails (>=0.9.0,<=0.17.0)
29
29
  Requires-Dist: nest-asyncio (>=1.6.0)
30
30
  Requires-Dist: numpy (>=1.25.0)
31
31
  Requires-Dist: openai (>=1.14.3)
@@ -0,0 +1,30 @@
1
+ datarobot_dome/__init__.py,sha256=gpWJizDEzOPlZO0E2nRbRBJagAMTBVTtvMqfZnhs7LM,583
2
+ datarobot_dome/async_http_client.py,sha256=7ljpkXtOBcgfI3HGeHVdDJBw9dOBiQ7f_jIXbP8axK8,9863
3
+ datarobot_dome/chat_helper.py,sha256=0oEHbw4SI4vSsIWt2_r4zLufdL5gZhGPWo3AbO1XsOA,9671
4
+ datarobot_dome/constants.py,sha256=Djtqloy9yGQKWqWDyboEOCb8iuYFJeMVO048f2W3AmM,11448
5
+ datarobot_dome/drum_integration.py,sha256=xs_F5XGCNN1g8EUR9-UQJGbmRZwOav6tyoBXonjwcog,46480
6
+ datarobot_dome/guard_executor.py,sha256=3ShUWBispcn6Z60EddSv1SP8H5IenDbm3JKQnl6tBq8,40315
7
+ datarobot_dome/guard_factory.py,sha256=s74_N0pPIP03u79NvPoYtBRilUxawuFL3a8djM7N4ic,6081
8
+ datarobot_dome/guard_helpers.py,sha256=Frhuuq-yCb5xpSWnz-D7r3f5wrImmFJDuribqBGSx54,17581
9
+ datarobot_dome/guards/__init__.py,sha256=oV8EBIYzNuZjiXSL2pfk-JCKQKKr0UB1_yzN_6q-cFk,1287
10
+ datarobot_dome/guards/base.py,sha256=DEG8knC0Q0fHJ0j3tGlogeMam2YyFMXDvojoMkb-TMU,10646
11
+ datarobot_dome/guards/guard_llm_mixin.py,sha256=dy1IuSqEMD41pi8Ed20-lUUrEcLCY7GUHBypIAUJIeg,12041
12
+ datarobot_dome/guards/model_guard.py,sha256=xaaZCAPH6r5UgfJ_2cElzBXTHsVWgH6IvTM7sfzBz18,2970
13
+ datarobot_dome/guards/nemo_evaluator.py,sha256=GSp50N8uahmoHii4f3mwNHW8BqnsM1Lamek-ZjS-KXc,13996
14
+ datarobot_dome/guards/nemo_guard.py,sha256=4qGjV3XzHYfh4tvQvNc99ndOenaOZRGGciUkslApKPo,7216
15
+ datarobot_dome/guards/ootb_guard.py,sha256=5LUFZf179_5nPrrt6uqD8BThBwipY4Ume8alI28yMFA,8469
16
+ datarobot_dome/guards/validation.py,sha256=vm21fkRvts9_9j7iJlFlQNnFzynymIuNsoSzqYJErlw,9554
17
+ datarobot_dome/llm.py,sha256=Q-gC9vC8eWu5uAGNhdE3jfGz643VGRuLA-Pz5kQwago,5719
18
+ datarobot_dome/metrics/__init__.py,sha256=gpWJizDEzOPlZO0E2nRbRBJagAMTBVTtvMqfZnhs7LM,583
19
+ datarobot_dome/metrics/citation_metrics.py,sha256=nfL7fQB5E2GaQPuZ9gqHoqmyIHuM-UEYWvDloQAdwvY,4652
20
+ datarobot_dome/metrics/factory.py,sha256=TzEL-a-o_58_2so-N-0RPw8pMXnaW2QKu-y0aXF3rbw,2153
21
+ datarobot_dome/metrics/metric_scorer.py,sha256=JJp8WR6sKTXuCiLs96QDTIzY7QgCs8QK2Q_N5uh1HbE,2540
22
+ datarobot_dome/pipeline/__init__.py,sha256=gpWJizDEzOPlZO0E2nRbRBJagAMTBVTtvMqfZnhs7LM,583
23
+ datarobot_dome/pipeline/llm_pipeline.py,sha256=Ll51TgGbz_ooX4FJ2oRir5Y4ITmcf9Nz6nhyzZ_Ko7I,20981
24
+ datarobot_dome/pipeline/pipeline.py,sha256=DMtqYZMZeUhhdIUEBY59D12LWIsk_Jc89_IjvHsZAn0,19486
25
+ datarobot_dome/pipeline/vdb_pipeline.py,sha256=yrTn7M4IT8Q_e4Cv61haFSUx2_CAs25dftgHywfWGCw,9835
26
+ datarobot_dome/runtime.py,sha256=J3undH6VM5Pao2PZqjfRtVGeVx0nkqw80hYpRRZUTkY,1468
27
+ datarobot_dome/streaming.py,sha256=ov-IubMA1RfY38jg1PNG-tcuViHPgX8t9VmKz6d9lOs,18248
28
+ datarobot_moderations-11.2.12.dist-info/METADATA,sha256=vdqm7PmRvWIAP7ZclLGwDpefb7tCmieW6hvYgrIf6T0,4864
29
+ datarobot_moderations-11.2.12.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
30
+ datarobot_moderations-11.2.12.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.3.0
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,30 +0,0 @@
1
- datarobot_dome/__init__.py,sha256=S5kGePu3juoQk4ztKosOjtJyOwRqzN5quavyuO79Vvg,583
2
- datarobot_dome/async_http_client.py,sha256=g6smItjY7YX7v8WwjOGJrlEpYmv596W6QUXAQ5SlUBQ,9863
3
- datarobot_dome/chat_helper.py,sha256=maSxpTESdKCeo8jtLID6zquICxymzEOnrpuvqsfx9Dk,9671
4
- datarobot_dome/constants.py,sha256=Mt_IFjIyMRmp0huRb8AN9MYqGf9OSgWB8WWQ7iqcx9I,11404
5
- datarobot_dome/drum_integration.py,sha256=tg_rpwlClc0Dt1_X-bHG3qEKAwbaPJu_qb4VyA1lUFg,46480
6
- datarobot_dome/guard_executor.py,sha256=z62P4HS0PGiKX1AAKxxTBuWMiNjdFgsqJKlpnvWcPSI,37607
7
- datarobot_dome/guard_factory.py,sha256=g92bQ1zqlDJ5lpjDc1s60Is5RlFPbs0HkExgPgoIbg8,6081
8
- datarobot_dome/guard_helpers.py,sha256=B5v0nP5wZk9am_-rDRWuuk6jYuaYVh4t9ClHQM-O7c4,17581
9
- datarobot_dome/guards/__init__.py,sha256=sL2DO-IvQkS3pgpurfmbQf_Ot-5yyyTFp0RiH0pNjOA,1287
10
- datarobot_dome/guards/base.py,sha256=0eIr3uAeIIQ8-YnBVM1z452HOyE7wyeqIuNgeYVhVN0,10646
11
- datarobot_dome/guards/guard_llm_mixin.py,sha256=QnrQjyBrgKlDZ4yPy10kdDzleuQ4h54aGld8EykCweQ,12041
12
- datarobot_dome/guards/model_guard.py,sha256=2bTQYFNuLYT169ex17cclyznirHtbqtSpOSnkP_Sh5E,2970
13
- datarobot_dome/guards/nemo_evaluator.py,sha256=85-_V4aTLA-Ry8_rWjKI9IMlC9Nparwm_KvUy08cwVw,2497
14
- datarobot_dome/guards/nemo_guard.py,sha256=E50OS6tdw5PnUX_DY6U-zEkUuP6T-63YTVYOgdvvK2Y,7114
15
- datarobot_dome/guards/ootb_guard.py,sha256=c7SKb7zy9cMBRiP9eSrZJsAgQYFyMygjEBhdn1YZfT8,8469
16
- datarobot_dome/guards/validation.py,sha256=39W4wM7g6lAuVnM078gRvXFx_sYe9-YioN8T600EXv0,8367
17
- datarobot_dome/llm.py,sha256=e6dCK-apbr3l4Njztgm8my8vorFvvw1L7MbaHUiCOZ0,5719
18
- datarobot_dome/metrics/__init__.py,sha256=S5kGePu3juoQk4ztKosOjtJyOwRqzN5quavyuO79Vvg,583
19
- datarobot_dome/metrics/citation_metrics.py,sha256=q-uSJKNQjLizdpiju7e1qgVPQVu3SJHDm4Abc8e4m9k,4652
20
- datarobot_dome/metrics/factory.py,sha256=C7M_hhN6z-_Q8LWfuGhuU_gUc87TJHmvYoY6wFC6O3w,2153
21
- datarobot_dome/metrics/metric_scorer.py,sha256=pFWkOv1-O6zdCQOdFJwIYTvJkJOzJ2LqKiizVI1cKHA,2540
22
- datarobot_dome/pipeline/__init__.py,sha256=S5kGePu3juoQk4ztKosOjtJyOwRqzN5quavyuO79Vvg,583
23
- datarobot_dome/pipeline/llm_pipeline.py,sha256=DzSNxNH8uu46IX-cCYMhVck6yWdCBqGbr9AJbI6tSUs,20981
24
- datarobot_dome/pipeline/pipeline.py,sha256=TUzTux9BRQnUhiHr0yhB8nm4CsOoPNTDALZcAo8KmVE,19486
25
- datarobot_dome/pipeline/vdb_pipeline.py,sha256=z72xMm5gVfAYJ3vqWEy190AORrXFsJNcbrZ3y_Biod4,9835
26
- datarobot_dome/runtime.py,sha256=4G23IWzu6QSHEpy3INlb3s9mHNxsZlSalOHV4gN6L18,1468
27
- datarobot_dome/streaming.py,sha256=NRykFbv7gJQ02brZ9u5rwTTKMq6REibcLtgTw-18294,18248
28
- datarobot_moderations-11.2.11.dist-info/METADATA,sha256=Erh64WdPsSUZxRyqnnlEyKdviIAXfLBi2d_MZoYs9XE,4855
29
- datarobot_moderations-11.2.11.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
30
- datarobot_moderations-11.2.11.dist-info/RECORD,,