datarobot-moderations 11.1.14__py3-none-any.whl → 11.1.16__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.
@@ -69,6 +69,8 @@ LLM_CONTEXT_COLUMN_NAME = "_LLM_CONTEXT"
69
69
  PROMPT_TOKEN_COUNT_COLUMN_NAME_FROM_USAGE = "prompt_token_count_from_usage"
70
70
  RESPONSE_TOKEN_COUNT_COLUMN_NAME_FROM_USAGE = "response_token_count_from_usage"
71
71
 
72
+ SPAN_PREFIX = "datarobot.guard"
73
+
72
74
 
73
75
  class TargetType(str, Enum):
74
76
  """Target types that may be handed to moderations from DRUM -- casing must align."""
@@ -26,6 +26,7 @@ from openai.types.chat import ChatCompletionChunk
26
26
  from openai.types.chat.chat_completion import ChatCompletion
27
27
  from openai.types.chat.chat_completion import Choice
28
28
  from openai.types.chat.chat_completion_message import ChatCompletionMessage
29
+ from opentelemetry import trace
29
30
 
30
31
  from datarobot_dome.chat_helper import add_citations_to_df
31
32
  from datarobot_dome.chat_helper import add_token_count_columns_to_df
@@ -57,6 +58,9 @@ from datarobot_dome.pipeline.vdb_pipeline import VDBPipeline
57
58
  from datarobot_dome.streaming import ModerationIterator
58
59
  from datarobot_dome.streaming import StreamingContextBuilder
59
60
 
61
+ tracer = trace.get_tracer(__name__)
62
+
63
+
60
64
  _logger = logging.getLogger("drum_integration")
61
65
 
62
66
 
@@ -508,7 +512,7 @@ def build_predictions_df_from_completion(data, pipeline, chat_completion):
508
512
  if pipeline_interactions:
509
513
  predictions_df[AGENTIC_PIPELINE_INTERACTIONS_ATTR] = pipeline_interactions
510
514
  else:
511
- predictions_df[AGENTIC_PIPELINE_INTERACTIONS_ATTR] = [np.nan] * len(predictions_df)
515
+ predictions_df[AGENTIC_PIPELINE_INTERACTIONS_ATTR] = [None] * len(predictions_df)
512
516
 
513
517
  source_object = chat_completion
514
518
  elif isinstance(chat_completion, Iterable):
@@ -661,6 +665,37 @@ def _is_llm_requesting_user_tool_call(completion):
661
665
  return False, completion
662
666
 
663
667
 
668
+ def __get_otel_values(guards_list, stage, result_df):
669
+ guard_values = {}
670
+ for guard in guards_list:
671
+ if not guard.has_average_score_custom_metric():
672
+ continue
673
+ guard_metric_column_name = guard.get_metric_column_name(stage)
674
+ if guard_metric_column_name not in result_df.columns:
675
+ _logger.warning(f"Missing column: {guard_metric_column_name} in result_df")
676
+ continue
677
+ guard_values[guard.get_span_column_name(stage)] = result_df[
678
+ guard_metric_column_name
679
+ ].tolist()[0]
680
+ return guard_values
681
+
682
+
683
+ def report_otel_evaluation_set_metric(pipeline, result_df):
684
+ current_span = trace.get_current_span()
685
+ if not current_span:
686
+ _logger.warning("No currently active span found to report evaluation set metric")
687
+ return
688
+
689
+ prompt_values = __get_otel_values(pipeline.get_prescore_guards(), GuardStage.PROMPT, result_df)
690
+ response_values = __get_otel_values(
691
+ pipeline.get_postscore_guards(), GuardStage.RESPONSE, result_df
692
+ )
693
+
694
+ final_value = {"prompt_guards": prompt_values, "response_guards": response_values}
695
+
696
+ current_span.set_attribute("datarobot.moderation.evaluation", json.dumps(final_value))
697
+
698
+
664
699
  def guard_chat_wrapper(
665
700
  completion_create_params, model, pipeline, drum_chat_fn, association_id=None, **kwargs
666
701
  ):
@@ -723,6 +758,7 @@ def guard_chat_wrapper(
723
758
  completion = _set_moderation_attribute_to_completion(
724
759
  pipeline, chat_completion, result_df, association_id=association_id
725
760
  )
761
+ report_otel_evaluation_set_metric(pipeline, result_df)
726
762
  return completion
727
763
 
728
764
  replaced_prompt_column_name = f"replaced_{prompt_column_name}"
@@ -802,6 +838,7 @@ def guard_chat_wrapper(
802
838
  ) / result_df.shape[0]
803
839
 
804
840
  response_message, finish_reason = get_response_message_and_finish_reason(pipeline, postscore_df)
841
+ report_otel_evaluation_set_metric(pipeline, result_df)
805
842
 
806
843
  final_completion = build_non_streaming_chat_completion(
807
844
  response_message, finish_reason, extra_attributes
datarobot_dome/guard.py CHANGED
@@ -35,6 +35,7 @@ from datarobot_dome.constants import FAITHFULLNESS_COLUMN_NAME
35
35
  from datarobot_dome.constants import NEMO_GUARD_COLUMN_NAME
36
36
  from datarobot_dome.constants import NEMO_GUARDRAILS_DIR
37
37
  from datarobot_dome.constants import ROUGE_1_COLUMN_NAME
38
+ from datarobot_dome.constants import SPAN_PREFIX
38
39
  from datarobot_dome.constants import TASK_ADHERENCE_SCORE_COLUMN_NAME
39
40
  from datarobot_dome.constants import TOKEN_COUNT_COLUMN_NAME
40
41
  from datarobot_dome.constants import AwsModel
@@ -48,11 +49,13 @@ from datarobot_dome.constants import GuardStage
48
49
  from datarobot_dome.constants import GuardTimeoutAction
49
50
  from datarobot_dome.constants import GuardType
50
51
  from datarobot_dome.constants import OOTBType
52
+ from datarobot_dome.guard_helpers import DEFAULT_OPEN_AI_API_VERSION
51
53
  from datarobot_dome.guard_helpers import ModerationDeepEvalLLM
52
54
  from datarobot_dome.guard_helpers import get_azure_openai_client
53
55
  from datarobot_dome.guard_helpers import get_chat_nvidia_llm
54
56
  from datarobot_dome.guard_helpers import get_datarobot_endpoint_and_token
55
- from datarobot_dome.guard_helpers import try_to_fallback_to_llm_gateway
57
+ from datarobot_dome.guard_helpers import get_llm_gateway_client
58
+ from datarobot_dome.guard_helpers import use_llm_gateway_inference
56
59
  from datarobot_dome.guards.guard_llm_mixin import GuardLLMMixin
57
60
 
58
61
  MAX_GUARD_NAME_LENGTH = 255
@@ -141,6 +144,7 @@ guard_intervention_trafaret = t.Dict(
141
144
  additional_guard_config_trafaret = t.Dict(
142
145
  {
143
146
  t.Key("cost", to_name="cost", optional=True): t.Or(cost_metric_trafaret, t.Null),
147
+ t.Key("tool_call", to_name="tool_call", optional=True): t.Or(t.Any(), t.Null),
144
148
  }
145
149
  )
146
150
 
@@ -366,6 +370,21 @@ class Guard(ABC):
366
370
  def get_comparand(self):
367
371
  return self.intervention.threshold
368
372
 
373
+ def get_enforced_span_attribute_name(self, stage):
374
+ intervention_action = self.get_intervention_action()
375
+ if intervention_action in [GuardAction.BLOCK, GuardAction.REPORT]:
376
+ return f"{SPAN_PREFIX}.{stage.lower()}.{intervention_action}ed"
377
+ elif intervention_action == GuardAction.REPLACE:
378
+ return f"{SPAN_PREFIX}.{stage.lower()}.replaced"
379
+ else:
380
+ raise NotImplementedError
381
+
382
+ def get_span_column_name(self, _):
383
+ raise NotImplementedError
384
+
385
+ def get_span_attribute_name(self, _):
386
+ raise NotImplementedError
387
+
369
388
 
370
389
  class GuardModelInfo:
371
390
  def __init__(self, model_config: dict):
@@ -434,6 +453,15 @@ class ModelGuard(Guard):
434
453
  raise NotImplementedError("Missing model_info for model guard")
435
454
  return self.get_stage_str(stage) + "_" + self._model_info.target_name
436
455
 
456
+ def get_span_column_name(self, _):
457
+ if self.model_info is None:
458
+ raise NotImplementedError("Missing model_info for model guard")
459
+ # Typically 0th index is the target name
460
+ return self._model_info.target_name.split("_")[0]
461
+
462
+ def get_span_attribute_name(self, stage):
463
+ return f"{SPAN_PREFIX}.{stage.lower()}.{self.get_span_column_name(stage)}"
464
+
437
465
  def has_average_score_custom_metric(self) -> bool:
438
466
  """A couple ModelGuard types do not have an average score metric"""
439
467
  return self.model_info.target_type not in [
@@ -459,12 +487,18 @@ class NeMoGuard(Guard, GuardLLMMixin):
459
487
  self.openai_api_base = config.get("openai_api_base")
460
488
  self.openai_deployment_id = config.get("openai_deployment_id")
461
489
  llm_id = None
490
+ credentials = None
491
+ use_llm_gateway = use_llm_gateway_inference(self._llm_type)
462
492
  try:
463
493
  self.openai_api_key = self.get_openai_api_key(config, self._llm_type)
464
494
  if self._llm_type != GuardLLMType.NIM and self.openai_api_key is None:
465
495
  raise ValueError("OpenAI API key is required for NeMo Guardrails")
466
496
 
467
497
  if self.llm_type == GuardLLMType.OPENAI:
498
+ credentials = {
499
+ "credential_type": "openai",
500
+ "api_key": self.openai_api_key,
501
+ }
468
502
  os.environ["OPENAI_API_KEY"] = self.openai_api_key
469
503
  llm = None
470
504
  elif self.llm_type == GuardLLMType.AZURE_OPENAI:
@@ -472,6 +506,12 @@ class NeMoGuard(Guard, GuardLLMMixin):
472
506
  raise ValueError("Azure OpenAI API base url is required for LLM Guard")
473
507
  if self.openai_deployment_id is None:
474
508
  raise ValueError("Azure OpenAI deployment ID is required for LLM Guard")
509
+ credentials = {
510
+ "credential_type": "azure_openai",
511
+ "api_base": self.openai_api_base,
512
+ "api_version": DEFAULT_OPEN_AI_API_VERSION,
513
+ "api_key": self.openai_api_key,
514
+ }
475
515
  azure_openai_client = get_azure_openai_client(
476
516
  openai_api_key=self.openai_api_key,
477
517
  openai_api_base=self.openai_api_base,
@@ -512,15 +552,20 @@ class NeMoGuard(Guard, GuardLLMMixin):
512
552
  raise ValueError(f"Invalid LLMType: {self.llm_type}")
513
553
 
514
554
  except Exception as e:
515
- llm = try_to_fallback_to_llm_gateway(
516
- # Currently only OPENAI and AZURE_OPENAI are supported by NeMoGuard
517
- # For Bedrock and Vertex the model in the config is actually the LLM ID
518
- # For OpenAI we use the default model defined in get_llm_gateway_client
519
- # For Azure we use the deployment ID
555
+ # no valid user credentials provided, raise if not using LLM Gateway
556
+ credentials = None
557
+ if not use_llm_gateway:
558
+ raise e
559
+
560
+ if use_llm_gateway:
561
+ # Currently only OPENAI and AZURE_OPENAI are supported by NeMoGuard
562
+ # For Bedrock and Vertex the model in the config is actually the LLM ID
563
+ # For OpenAI we use the default model defined in get_llm_gateway_client
564
+ # For Azure we use the deployment ID
565
+ llm = get_llm_gateway_client(
520
566
  llm_id=llm_id,
521
567
  openai_deployment_id=self.openai_deployment_id,
522
- llm_type=self.llm_type,
523
- e=e,
568
+ credentials=credentials,
524
569
  )
525
570
 
526
571
  # Use guard stage to determine whether to read from prompt/response subdirectory
@@ -566,6 +611,19 @@ class OOTBGuard(Guard):
566
611
  else:
567
612
  raise NotImplementedError(f"No metric column name defined for {self._ootb_type} guard")
568
613
 
614
+ def get_span_column_name(self, _):
615
+ if self._ootb_type == OOTBType.TOKEN_COUNT:
616
+ return TOKEN_COUNT_COLUMN_NAME
617
+ elif self._ootb_type == OOTBType.ROUGE_1:
618
+ return ROUGE_1_COLUMN_NAME
619
+ elif self._ootb_type == OOTBType.CUSTOM_METRIC:
620
+ return self.name
621
+ else:
622
+ raise NotImplementedError(f"No span attribute name defined for {self._ootb_type} guard")
623
+
624
+ def get_span_attribute_name(self, stage):
625
+ return f"{SPAN_PREFIX}.{stage.lower()}.{self.get_span_column_name(stage)}"
626
+
569
627
 
570
628
  class OOTBCostMetric(OOTBGuard):
571
629
  def __init__(self, config, stage):
@@ -603,6 +661,12 @@ class OOTBCostMetric(OOTBGuard):
603
661
  ),
604
662
  }
605
663
 
664
+ def get_span_column_name(self, _):
665
+ return f"{COST_COLUMN_NAME}.{self.currency.lower()}"
666
+
667
+ def get_span_attribute_name(self, _):
668
+ return f"{SPAN_PREFIX}.{self._stage.lower()}.{self.get_span_column_name(_)}"
669
+
606
670
 
607
671
  class FaithfulnessGuard(OOTBGuard, GuardLLMMixin):
608
672
  def __init__(self, config: dict, stage=None):
@@ -624,6 +688,12 @@ class FaithfulnessGuard(OOTBGuard, GuardLLMMixin):
624
688
  def faithfulness_evaluator(self):
625
689
  return self._evaluator
626
690
 
691
+ def get_span_column_name(self, _):
692
+ return FAITHFULLNESS_COLUMN_NAME
693
+
694
+ def get_span_attribute_name(self, _):
695
+ return f"{SPAN_PREFIX}.{self._stage.lower()}.{self.get_span_column_name(_)}"
696
+
627
697
 
628
698
  class AgentGoalAccuracyGuard(OOTBGuard, GuardLLMMixin):
629
699
  def __init__(self, config: dict, stage=None):
@@ -645,6 +715,12 @@ class AgentGoalAccuracyGuard(OOTBGuard, GuardLLMMixin):
645
715
  def accuracy_scorer(self):
646
716
  return self.scorer
647
717
 
718
+ def get_span_column_name(self, _):
719
+ return AGENT_GOAL_ACCURACY_COLUMN_NAME
720
+
721
+ def get_span_attribute_name(self, _):
722
+ return f"{SPAN_PREFIX}.{self._stage.lower()}.{self.get_span_column_name(_)}"
723
+
648
724
 
649
725
  class TaskAdherenceGuard(OOTBGuard, GuardLLMMixin):
650
726
  def __init__(self, config: dict, stage=None):
@@ -666,6 +742,12 @@ class TaskAdherenceGuard(OOTBGuard, GuardLLMMixin):
666
742
  def task_adherence_scorer(self):
667
743
  return self.scorer
668
744
 
745
+ def get_span_column_name(self, _):
746
+ return TASK_ADHERENCE_SCORE_COLUMN_NAME
747
+
748
+ def get_span_attribute_name(self, _):
749
+ return f"{SPAN_PREFIX}.{self._stage.lower()}.{self.get_span_column_name(_)}"
750
+
669
751
 
670
752
  class GuardFactory:
671
753
  @classmethod
@@ -34,7 +34,6 @@ from datarobot_dome.constants import ModerationEventTypes
34
34
  from datarobot_dome.constants import OOTBType
35
35
  from datarobot_dome.guard import AgentGoalAccuracyGuard
36
36
  from datarobot_dome.guard import FaithfulnessGuard
37
- from datarobot_dome.guard import Guard
38
37
  from datarobot_dome.guard import ModelGuard
39
38
  from datarobot_dome.guard import NeMoGuard
40
39
  from datarobot_dome.guard import OOTBCostMetric
@@ -113,6 +112,25 @@ class AsyncGuardExecutor:
113
112
  span.set_attribute("datarobot.moderation.guard.latency", latency)
114
113
  if guard.has_latency_custom_metric():
115
114
  self.pipeline.report_guard_latency(guard, latency)
115
+ if guard.has_average_score_custom_metric():
116
+ metric_column_name = guard.get_metric_column_name(stage)
117
+ if metric_column_name in df.columns:
118
+ span.set_attribute(
119
+ guard.get_span_attribute_name(stage),
120
+ df[metric_column_name].tolist()[0],
121
+ )
122
+ if guard.get_intervention_action():
123
+ (
124
+ enforced_column_name,
125
+ _,
126
+ _,
127
+ ) = self._get_enforced_and_action_column_names(
128
+ guard.get_intervention_action(), self.pipeline.get_input_column(stage)
129
+ )
130
+ span.set_attribute(
131
+ guard.get_enforced_span_attribute_name(stage),
132
+ df[enforced_column_name].tolist()[0],
133
+ )
116
134
 
117
135
  return df, latency
118
136
 
@@ -204,7 +222,7 @@ class AsyncGuardExecutor:
204
222
  # and "Response_toxicity_toxic_PREDICTION", if toxicity is configured for both
205
223
  # prompts and responses
206
224
  copy_df.rename(
207
- columns={metric_column: Guard.get_stage_str(stage) + "_" + metric_column},
225
+ columns={metric_column: guard.get_metric_column_name(stage)},
208
226
  inplace=True,
209
227
  )
210
228
  except Exception as ex:
@@ -47,7 +47,7 @@ from datarobot_dome.llm import DataRobotLLM
47
47
  # but for ROUGE-1 guard, UI allows the user to configure value between
48
48
  # 0 and 1, so making scaling factor 1.
49
49
  SCALING_FACTOR = 1
50
- DEFAULT_OPEN_AI_API_VERSION = "2023-03-15-preview"
50
+ DEFAULT_OPEN_AI_API_VERSION = "2024-10-21"
51
51
 
52
52
  _logger = logging.getLogger(LOGGER_NAME_PREFIX + ".guard_helpers")
53
53
 
@@ -195,8 +195,10 @@ def get_llm_gateway_client(
195
195
  model: str | None = None,
196
196
  llm_id: str | None = None,
197
197
  openai_deployment_id: str | None = None,
198
+ credentials: dict | None = None,
198
199
  ) -> ChatOpenAI:
199
200
  """The LLM gateway client enables chat completions with DR provided credentials and metering.
201
+ User provided credentials are optional and passed to the completion request as json string.
200
202
 
201
203
  Providing model is always required due to openai's chat api.
202
204
  llm_id and deployment_id override model if provided.
@@ -208,7 +210,8 @@ def get_llm_gateway_client(
208
210
  model=model or "azure/gpt-4o",
209
211
  api_key=datarobot_api_token,
210
212
  base_url=f"{datarobot_endpoint}/genai/llmgw",
211
- max_retries=0, # retries are handled by the LLM Gateway
213
+ # retries are handled by the LLM Gateway
214
+ max_retries=0,
212
215
  default_headers={
213
216
  # used for metering
214
217
  "Client-Id": "moderations",
@@ -217,28 +220,24 @@ def get_llm_gateway_client(
217
220
  # optional model overrides
218
221
  "deployment_id": openai_deployment_id,
219
222
  "llm_id": llm_id,
223
+ # optional user provided credentials
224
+ "credential_json": json.dumps(credentials) if credentials else None,
220
225
  },
221
226
  )
222
227
  return client
223
228
 
224
229
 
225
- def try_to_fallback_to_llm_gateway(
226
- llm_id: str | None,
227
- openai_deployment_id: str | None,
228
- llm_type: GuardLLMType,
229
- e: Exception,
230
- ) -> ChatOpenAI:
231
- # USE the LLM gateway if its runtime parameter is available and enabled
232
- # DO NOT USE the gateway if user provided credentials are specified
233
- # which is the case if no exception was raised trying to create the LLM
234
- # DATAROBOT and NIM LLM types are not supported by the gateway
235
- if not json.loads(os.environ.get("ENABLE_LLM_GATEWAY_INFERENCE", "false")) or llm_type in [
230
+ def use_llm_gateway_inference(llm_type: GuardLLMType):
231
+ """
232
+ USE the LLM gateway if its runtime parameter is available and enabled
233
+ DATAROBOT and NIM LLM types are not supported by the gateway
234
+ """
235
+ if json.loads(os.environ.get("ENABLE_LLM_GATEWAY_INFERENCE", "false")) and llm_type not in [
236
236
  GuardLLMType.DATAROBOT,
237
237
  GuardLLMType.NIM,
238
238
  ]:
239
- raise e
240
- llm = get_llm_gateway_client(llm_id=llm_id, openai_deployment_id=openai_deployment_id)
241
- return llm
239
+ return True
240
+ return False
242
241
 
243
242
 
244
243
  def get_azure_openai_client(
@@ -400,7 +399,7 @@ def calculate_agent_goal_accuracy(
400
399
  interactions: str,
401
400
  response: str,
402
401
  ):
403
- if interactions is None:
402
+ if interactions is None or interactions == "":
404
403
  # If interactions are missing - we use prompt and response to gauge the
405
404
  # goal accuracy
406
405
  sample = MultiTurnSample(
@@ -22,11 +22,13 @@ from datarobot_dome.constants import SECRET_DEFINITION_PREFIX
22
22
  from datarobot_dome.constants import GuardLLMType
23
23
  from datarobot_dome.constants import GuardType
24
24
  from datarobot_dome.constants import OOTBType
25
+ from datarobot_dome.guard_helpers import DEFAULT_OPEN_AI_API_VERSION
25
26
  from datarobot_dome.guard_helpers import get_azure_openai_client
26
27
  from datarobot_dome.guard_helpers import get_bedrock_client
27
28
  from datarobot_dome.guard_helpers import get_datarobot_llm
29
+ from datarobot_dome.guard_helpers import get_llm_gateway_client
28
30
  from datarobot_dome.guard_helpers import get_vertex_client
29
- from datarobot_dome.guard_helpers import try_to_fallback_to_llm_gateway
31
+ from datarobot_dome.guard_helpers import use_llm_gateway_inference
30
32
 
31
33
  basic_credential_trafaret = t.Dict(
32
34
  {
@@ -156,6 +158,8 @@ class GuardLLMMixin:
156
158
  openai_api_base = config.get("openai_api_base")
157
159
  openai_deployment_id = config.get("openai_deployment_id")
158
160
  llm_id = None
161
+ credentials = None
162
+ use_llm_gateway = use_llm_gateway_inference(llm_type)
159
163
  try:
160
164
  if llm_type in [GuardLLMType.OPENAI, GuardLLMType.AZURE_OPENAI]:
161
165
  openai_api_key = self.get_openai_api_key(config, llm_type)
@@ -163,6 +167,10 @@ class GuardLLMMixin:
163
167
  raise ValueError("OpenAI API key is required for Faithfulness guard")
164
168
 
165
169
  if llm_type == GuardLLMType.OPENAI:
170
+ credentials = {
171
+ "credential_type": "openai",
172
+ "api_key": openai_api_key,
173
+ }
166
174
  os.environ["OPENAI_API_KEY"] = openai_api_key
167
175
  llm = "default"
168
176
  elif llm_type == GuardLLMType.AZURE_OPENAI:
@@ -170,6 +178,12 @@ class GuardLLMMixin:
170
178
  raise ValueError("OpenAI API base url is required for LLM Guard")
171
179
  if openai_deployment_id is None:
172
180
  raise ValueError("OpenAI deployment ID is required for LLM Guard")
181
+ credentials = {
182
+ "credential_type": "azure_openai",
183
+ "api_key": openai_api_key,
184
+ "api_base": openai_api_base,
185
+ "api_version": DEFAULT_OPEN_AI_API_VERSION,
186
+ }
173
187
  azure_openai_client = get_azure_openai_client(
174
188
  openai_api_key=openai_api_key,
175
189
  openai_api_base=openai_api_base,
@@ -182,9 +196,15 @@ class GuardLLMMixin:
182
196
  raise ValueError("Google model is required for LLM Guard")
183
197
  if config.get("google_region") is None:
184
198
  raise ValueError("Google region is required for LLM Guard")
199
+ service_account_info = self.get_google_service_account(config)
200
+ credentials = {
201
+ "credential_type": "google_vertex_ai",
202
+ "region": config["google_region"],
203
+ "service_account_info": service_account_info,
204
+ }
185
205
  llm = get_vertex_client(
186
206
  google_model=llm_id,
187
- google_service_account=self.get_google_service_account(config),
207
+ google_service_account=service_account_info,
188
208
  google_region=config["google_region"],
189
209
  )
190
210
  elif llm_type == GuardLLMType.AMAZON:
@@ -194,6 +214,13 @@ class GuardLLMMixin:
194
214
  if config.get("aws_region") is None:
195
215
  raise ValueError("AWS region is required for LLM Guard")
196
216
  credential_config = self.get_aws_account(config)
217
+ credentials = {
218
+ "credential_type": "amazon_bedrock",
219
+ "access_key_id": credential_config["aws_access_key_id"],
220
+ "secret_access_key": credential_config["aws_secret_access_key"],
221
+ "session_token": credential_config["aws_session_token"],
222
+ "region": config["aws_region"],
223
+ }
197
224
  llm = get_bedrock_client(
198
225
  aws_model=llm_id,
199
226
  aws_access_key_id=credential_config["aws_access_key_id"],
@@ -219,14 +246,19 @@ class GuardLLMMixin:
219
246
  raise ValueError(f"Invalid LLMType: {llm_type}")
220
247
 
221
248
  except Exception as e:
222
- llm = try_to_fallback_to_llm_gateway(
223
- # For Bedrock and Vertex the model in the config is actually the LLM ID
224
- # For OpenAI we use the default model defined in get_llm_gateway_client
225
- # For Azure we use the deployment ID
249
+ # no valid user credentials provided, raise if not using LLM Gateway
250
+ credentials = None
251
+ if not use_llm_gateway:
252
+ raise e
253
+
254
+ if use_llm_gateway:
255
+ # For Bedrock and Vertex the model in the config is actually the LLM ID
256
+ # For OpenAI we use the default model defined in get_llm_gateway_client
257
+ # For Azure we use the deployment ID
258
+ llm = get_llm_gateway_client(
226
259
  llm_id=llm_id,
227
260
  openai_deployment_id=openai_deployment_id,
228
- llm_type=llm_type,
229
- e=e,
261
+ credentials=credentials,
230
262
  )
231
263
 
232
264
  return llm
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: datarobot-moderations
3
- Version: 11.1.14
3
+ Version: 11.1.16
4
4
  Summary: DataRobot Monitoring and Moderation framework
5
5
  License: DataRobot Tool and Utility Agreement
6
6
  Author: DataRobot
@@ -1,13 +1,13 @@
1
1
  datarobot_dome/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,583
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
- datarobot_dome/constants.py,sha256=vDU7En5Nd1bbfRIr02ReFtzZDqEg4RGCT7gdw3P0LO0,9007
5
- datarobot_dome/drum_integration.py,sha256=gRn2sQCmRs0RH0tVOdHX6amxGEX1R6WqEtOF2zdBtC4,40693
6
- datarobot_dome/guard.py,sha256=afcJSSo509aHHvM6nm-QTKzQjuWE7VzgpihenDaAf3w,29921
7
- datarobot_dome/guard_executor.py,sha256=9SuefqQRpJ_4fFm62YOPixg0Fi9z-mzR5eMPeknBT2Y,34642
8
- datarobot_dome/guard_helpers.py,sha256=VkNaoMAWAEggodpl7KmWZTM6H9H6e9Ny3Rl2HBXZnfM,16353
4
+ datarobot_dome/constants.py,sha256=mnSa8rUAha4XlsS2lwPmFCkH2RzfSL_MMkErsWHqIbA,9040
5
+ datarobot_dome/drum_integration.py,sha256=nULpLYVMiS5vihfNUyuq-nvZpgXrQibQbVu2UMAscu8,42102
6
+ datarobot_dome/guard.py,sha256=1INYx17n9ToiB5bzI-jIReUUuqkK_ucxpOx4jQLts6g,33264
7
+ datarobot_dome/guard_executor.py,sha256=AOI8MZeZETHMoFgBePe0wa2vE9d2975MYQnEDHLZL7s,35462
8
+ datarobot_dome/guard_helpers.py,sha256=Bfdi8gow2_TAVzRHYUDqEfcG5bWx2KR1dnpxt9E850Y,16311
9
9
  datarobot_dome/guards/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,583
10
- datarobot_dome/guards/guard_llm_mixin.py,sha256=ON-zuVL3xhQmXv0rFkalWrW_Q67Wwya2IQerHO8WkKU,10694
10
+ datarobot_dome/guards/guard_llm_mixin.py,sha256=VovlpNZjWIGamF4SSvLF5lzOFyApH5IoOiB_qtCmRg0,12216
11
11
  datarobot_dome/llm.py,sha256=L02OvTrflmD34-FrfXebfF-zzKTeuin7fpne1Cl5psg,5719
12
12
  datarobot_dome/metrics/__init__.py,sha256=B5Rx8_CNCNsOpxBbRj27XOXCfRZmvmrAR-NzlzIKnDw,583
13
13
  datarobot_dome/metrics/citation_metrics.py,sha256=q0hTMWuk6wy_jqk2UjFPON3kU94HN3W2vxr9giJ8O8E,3544
@@ -18,6 +18,6 @@ datarobot_dome/pipeline/llm_pipeline.py,sha256=fOp_OJnQMDUJH-LKv12kEqli-EqfHjAiS
18
18
  datarobot_dome/pipeline/pipeline.py,sha256=_pZ_4K2LMnfYCYj_ur9EwJzo3T-pbO6lFYz1O-_3uQ4,16491
19
19
  datarobot_dome/pipeline/vdb_pipeline.py,sha256=WTOGn1qe_ZvEcdlvHgeXxl2xTqp7GjfL13c6S-FmAfM,5146
20
20
  datarobot_dome/streaming.py,sha256=6nYvh6SoxPRLfO6GGdEoHsQuyLP9oX1lDMe8IeGo4lw,17801
21
- datarobot_moderations-11.1.14.dist-info/METADATA,sha256=39J7-G34lxk7ULqxroi3K0RekSNmaiCnPW5OvvMzWDk,4827
22
- datarobot_moderations-11.1.14.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
23
- datarobot_moderations-11.1.14.dist-info/RECORD,,
21
+ datarobot_moderations-11.1.16.dist-info/METADATA,sha256=WBOhNlF-pwpbJ2PvlkhwqlKbF3vtWkbNdu6vjqvmvaQ,4827
22
+ datarobot_moderations-11.1.16.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
23
+ datarobot_moderations-11.1.16.dist-info/RECORD,,