ibm-watsonx-gov 1.3.3__cp313-cp313-macosx_11_0_arm64.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.
- ibm_watsonx_gov/__init__.py +8 -0
- ibm_watsonx_gov/agent_catalog/__init__.py +8 -0
- ibm_watsonx_gov/agent_catalog/clients/__init__.py +14 -0
- ibm_watsonx_gov/agent_catalog/clients/ai_agent_client.py +333 -0
- ibm_watsonx_gov/agent_catalog/core/__init__.py +8 -0
- ibm_watsonx_gov/agent_catalog/core/agent_loader.py +202 -0
- ibm_watsonx_gov/agent_catalog/core/agents.py +134 -0
- ibm_watsonx_gov/agent_catalog/entities/__init__.py +8 -0
- ibm_watsonx_gov/agent_catalog/entities/ai_agent.py +599 -0
- ibm_watsonx_gov/agent_catalog/utils/__init__.py +8 -0
- ibm_watsonx_gov/agent_catalog/utils/constants.py +36 -0
- ibm_watsonx_gov/agent_catalog/utils/notebook_utils.py +70 -0
- ibm_watsonx_gov/ai_experiments/__init__.py +8 -0
- ibm_watsonx_gov/ai_experiments/ai_experiments_client.py +980 -0
- ibm_watsonx_gov/ai_experiments/utils/__init__.py +8 -0
- ibm_watsonx_gov/ai_experiments/utils/ai_experiment_utils.py +139 -0
- ibm_watsonx_gov/clients/__init__.py +0 -0
- ibm_watsonx_gov/clients/api_client.py +99 -0
- ibm_watsonx_gov/clients/segment_client.py +46 -0
- ibm_watsonx_gov/clients/usage_client.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/clients/wx_ai_client.py +87 -0
- ibm_watsonx_gov/config/__init__.py +14 -0
- ibm_watsonx_gov/config/agentic_ai_configuration.py +225 -0
- ibm_watsonx_gov/config/gen_ai_configuration.py +129 -0
- ibm_watsonx_gov/config/model_risk_configuration.py +173 -0
- ibm_watsonx_gov/config/predictive_ai_configuration.py +20 -0
- ibm_watsonx_gov/entities/__init__.py +8 -0
- ibm_watsonx_gov/entities/agentic_app.py +209 -0
- ibm_watsonx_gov/entities/agentic_evaluation_result.py +185 -0
- ibm_watsonx_gov/entities/ai_evaluation.py +290 -0
- ibm_watsonx_gov/entities/ai_experiment.py +419 -0
- ibm_watsonx_gov/entities/base_classes.py +134 -0
- ibm_watsonx_gov/entities/container.py +54 -0
- ibm_watsonx_gov/entities/credentials.py +633 -0
- ibm_watsonx_gov/entities/criteria.py +508 -0
- ibm_watsonx_gov/entities/enums.py +274 -0
- ibm_watsonx_gov/entities/evaluation_result.py +444 -0
- ibm_watsonx_gov/entities/foundation_model.py +490 -0
- ibm_watsonx_gov/entities/llm_judge.py +44 -0
- ibm_watsonx_gov/entities/locale.py +17 -0
- ibm_watsonx_gov/entities/mapping.py +49 -0
- ibm_watsonx_gov/entities/metric.py +211 -0
- ibm_watsonx_gov/entities/metric_threshold.py +36 -0
- ibm_watsonx_gov/entities/model_provider.py +329 -0
- ibm_watsonx_gov/entities/model_risk_result.py +43 -0
- ibm_watsonx_gov/entities/monitor.py +71 -0
- ibm_watsonx_gov/entities/prompt_setup.py +40 -0
- ibm_watsonx_gov/entities/state.py +22 -0
- ibm_watsonx_gov/entities/utils.py +99 -0
- ibm_watsonx_gov/evaluators/__init__.py +26 -0
- ibm_watsonx_gov/evaluators/agentic_evaluator.py +2725 -0
- ibm_watsonx_gov/evaluators/agentic_traces_evaluator.py +115 -0
- ibm_watsonx_gov/evaluators/base_evaluator.py +22 -0
- ibm_watsonx_gov/evaluators/impl/__init__.py +0 -0
- ibm_watsonx_gov/evaluators/impl/evaluate_metrics_impl.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/evaluators/impl/evaluate_model_risk_impl.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/evaluators/metrics_evaluator.py +187 -0
- ibm_watsonx_gov/evaluators/model_risk_evaluator.py +89 -0
- ibm_watsonx_gov/evaluators/traces_evaluator.py +93 -0
- ibm_watsonx_gov/metric_groups/answer_quality/answer_quality_decorator.py +66 -0
- ibm_watsonx_gov/metric_groups/content_safety/content_safety_decorator.py +76 -0
- ibm_watsonx_gov/metric_groups/readability/readability_decorator.py +59 -0
- ibm_watsonx_gov/metric_groups/retrieval_quality/retrieval_quality_decorator.py +63 -0
- ibm_watsonx_gov/metric_groups/usage/usage_decorator.py +58 -0
- ibm_watsonx_gov/metrics/__init__.py +74 -0
- ibm_watsonx_gov/metrics/answer_relevance/__init__.py +8 -0
- ibm_watsonx_gov/metrics/answer_relevance/answer_relevance_decorator.py +63 -0
- ibm_watsonx_gov/metrics/answer_relevance/answer_relevance_metric.py +260 -0
- ibm_watsonx_gov/metrics/answer_similarity/__init__.py +0 -0
- ibm_watsonx_gov/metrics/answer_similarity/answer_similarity_decorator.py +66 -0
- ibm_watsonx_gov/metrics/answer_similarity/answer_similarity_metric.py +219 -0
- ibm_watsonx_gov/metrics/average_precision/__init__.py +0 -0
- ibm_watsonx_gov/metrics/average_precision/average_precision_decorator.py +62 -0
- ibm_watsonx_gov/metrics/average_precision/average_precision_metric.py +174 -0
- ibm_watsonx_gov/metrics/base_metric_decorator.py +193 -0
- ibm_watsonx_gov/metrics/context_relevance/__init__.py +8 -0
- ibm_watsonx_gov/metrics/context_relevance/context_relevance_decorator.py +60 -0
- ibm_watsonx_gov/metrics/context_relevance/context_relevance_metric.py +414 -0
- ibm_watsonx_gov/metrics/cost/__init__.py +8 -0
- ibm_watsonx_gov/metrics/cost/cost_decorator.py +58 -0
- ibm_watsonx_gov/metrics/cost/cost_metric.py +155 -0
- ibm_watsonx_gov/metrics/duration/__init__.py +8 -0
- ibm_watsonx_gov/metrics/duration/duration_decorator.py +59 -0
- ibm_watsonx_gov/metrics/duration/duration_metric.py +111 -0
- ibm_watsonx_gov/metrics/evasiveness/__init__.py +8 -0
- ibm_watsonx_gov/metrics/evasiveness/evasiveness_decorator.py +61 -0
- ibm_watsonx_gov/metrics/evasiveness/evasiveness_metric.py +103 -0
- ibm_watsonx_gov/metrics/faithfulness/__init__.py +8 -0
- ibm_watsonx_gov/metrics/faithfulness/faithfulness_decorator.py +65 -0
- ibm_watsonx_gov/metrics/faithfulness/faithfulness_metric.py +254 -0
- ibm_watsonx_gov/metrics/hap/__init__.py +16 -0
- ibm_watsonx_gov/metrics/hap/hap_decorator.py +58 -0
- ibm_watsonx_gov/metrics/hap/hap_metric.py +98 -0
- ibm_watsonx_gov/metrics/hap/input_hap_metric.py +104 -0
- ibm_watsonx_gov/metrics/hap/output_hap_metric.py +110 -0
- ibm_watsonx_gov/metrics/harm/__init__.py +8 -0
- ibm_watsonx_gov/metrics/harm/harm_decorator.py +60 -0
- ibm_watsonx_gov/metrics/harm/harm_metric.py +103 -0
- ibm_watsonx_gov/metrics/harm_engagement/__init__.py +8 -0
- ibm_watsonx_gov/metrics/harm_engagement/harm_engagement_decorator.py +61 -0
- ibm_watsonx_gov/metrics/harm_engagement/harm_engagement_metric.py +103 -0
- ibm_watsonx_gov/metrics/hit_rate/__init__.py +0 -0
- ibm_watsonx_gov/metrics/hit_rate/hit_rate_decorator.py +59 -0
- ibm_watsonx_gov/metrics/hit_rate/hit_rate_metric.py +167 -0
- ibm_watsonx_gov/metrics/input_token_count/__init__.py +8 -0
- ibm_watsonx_gov/metrics/input_token_count/input_token_count_decorator.py +58 -0
- ibm_watsonx_gov/metrics/input_token_count/input_token_count_metric.py +112 -0
- ibm_watsonx_gov/metrics/jailbreak/__init__.py +8 -0
- ibm_watsonx_gov/metrics/jailbreak/jailbreak_decorator.py +60 -0
- ibm_watsonx_gov/metrics/jailbreak/jailbreak_metric.py +103 -0
- ibm_watsonx_gov/metrics/keyword_detection/keyword_detection_decorator.py +58 -0
- ibm_watsonx_gov/metrics/keyword_detection/keyword_detection_metric.py +111 -0
- ibm_watsonx_gov/metrics/llm_validation/__init__.py +8 -0
- ibm_watsonx_gov/metrics/llm_validation/evaluation_criteria.py +84 -0
- ibm_watsonx_gov/metrics/llm_validation/llm_validation_constants.py +24 -0
- ibm_watsonx_gov/metrics/llm_validation/llm_validation_decorator.py +54 -0
- ibm_watsonx_gov/metrics/llm_validation/llm_validation_impl.py +525 -0
- ibm_watsonx_gov/metrics/llm_validation/llm_validation_metric.py +258 -0
- ibm_watsonx_gov/metrics/llm_validation/llm_validation_prompts.py +106 -0
- ibm_watsonx_gov/metrics/llmaj/__init__.py +0 -0
- ibm_watsonx_gov/metrics/llmaj/llmaj_metric.py +298 -0
- ibm_watsonx_gov/metrics/ndcg/__init__.py +0 -0
- ibm_watsonx_gov/metrics/ndcg/ndcg_decorator.py +61 -0
- ibm_watsonx_gov/metrics/ndcg/ndcg_metric.py +166 -0
- ibm_watsonx_gov/metrics/output_token_count/__init__.py +8 -0
- ibm_watsonx_gov/metrics/output_token_count/output_token_count_decorator.py +58 -0
- ibm_watsonx_gov/metrics/output_token_count/output_token_count_metric.py +112 -0
- ibm_watsonx_gov/metrics/pii/__init__.py +16 -0
- ibm_watsonx_gov/metrics/pii/input_pii_metric.py +102 -0
- ibm_watsonx_gov/metrics/pii/output_pii_metric.py +107 -0
- ibm_watsonx_gov/metrics/pii/pii_decorator.py +59 -0
- ibm_watsonx_gov/metrics/pii/pii_metric.py +96 -0
- ibm_watsonx_gov/metrics/profanity/__init__.py +8 -0
- ibm_watsonx_gov/metrics/profanity/profanity_decorator.py +60 -0
- ibm_watsonx_gov/metrics/profanity/profanity_metric.py +103 -0
- ibm_watsonx_gov/metrics/prompt_safety_risk/__init__.py +8 -0
- ibm_watsonx_gov/metrics/prompt_safety_risk/prompt_safety_risk_decorator.py +57 -0
- ibm_watsonx_gov/metrics/prompt_safety_risk/prompt_safety_risk_metric.py +128 -0
- ibm_watsonx_gov/metrics/reciprocal_rank/__init__.py +0 -0
- ibm_watsonx_gov/metrics/reciprocal_rank/reciprocal_rank_decorator.py +62 -0
- ibm_watsonx_gov/metrics/reciprocal_rank/reciprocal_rank_metric.py +162 -0
- ibm_watsonx_gov/metrics/regex_detection/regex_detection_decorator.py +58 -0
- ibm_watsonx_gov/metrics/regex_detection/regex_detection_metric.py +106 -0
- ibm_watsonx_gov/metrics/retrieval_precision/__init__.py +0 -0
- ibm_watsonx_gov/metrics/retrieval_precision/retrieval_precision_decorator.py +62 -0
- ibm_watsonx_gov/metrics/retrieval_precision/retrieval_precision_metric.py +170 -0
- ibm_watsonx_gov/metrics/sexual_content/__init__.py +8 -0
- ibm_watsonx_gov/metrics/sexual_content/sexual_content_decorator.py +61 -0
- ibm_watsonx_gov/metrics/sexual_content/sexual_content_metric.py +103 -0
- ibm_watsonx_gov/metrics/social_bias/__init__.py +8 -0
- ibm_watsonx_gov/metrics/social_bias/social_bias_decorator.py +62 -0
- ibm_watsonx_gov/metrics/social_bias/social_bias_metric.py +103 -0
- ibm_watsonx_gov/metrics/status/__init__.py +0 -0
- ibm_watsonx_gov/metrics/status/status_metric.py +113 -0
- ibm_watsonx_gov/metrics/text_grade_level/__init__.py +8 -0
- ibm_watsonx_gov/metrics/text_grade_level/text_grade_level_decorator.py +59 -0
- ibm_watsonx_gov/metrics/text_grade_level/text_grade_level_metric.py +127 -0
- ibm_watsonx_gov/metrics/text_reading_ease/__init__.py +8 -0
- ibm_watsonx_gov/metrics/text_reading_ease/text_reading_ease_decorator.py +59 -0
- ibm_watsonx_gov/metrics/text_reading_ease/text_reading_ease_metric.py +123 -0
- ibm_watsonx_gov/metrics/tool_call_accuracy/__init__.py +0 -0
- ibm_watsonx_gov/metrics/tool_call_accuracy/tool_call_accuracy_decorator.py +67 -0
- ibm_watsonx_gov/metrics/tool_call_accuracy/tool_call_accuracy_metric.py +162 -0
- ibm_watsonx_gov/metrics/tool_call_parameter_accuracy/__init__.py +0 -0
- ibm_watsonx_gov/metrics/tool_call_parameter_accuracy/tool_call_parameter_accuracy_decorator.py +68 -0
- ibm_watsonx_gov/metrics/tool_call_parameter_accuracy/tool_call_parameter_accuracy_metric.py +151 -0
- ibm_watsonx_gov/metrics/tool_call_relevance/__init__.py +0 -0
- ibm_watsonx_gov/metrics/tool_call_relevance/tool_call_relevance_decorator.py +71 -0
- ibm_watsonx_gov/metrics/tool_call_relevance/tool_call_relevance_metric.py +166 -0
- ibm_watsonx_gov/metrics/tool_call_syntactic_accuracy/__init__.py +0 -0
- ibm_watsonx_gov/metrics/tool_call_syntactic_accuracy/tool_call_syntactic_accuracy_decorator.py +66 -0
- ibm_watsonx_gov/metrics/tool_call_syntactic_accuracy/tool_call_syntactic_accuracy_metric.py +121 -0
- ibm_watsonx_gov/metrics/topic_relevance/__init__.py +8 -0
- ibm_watsonx_gov/metrics/topic_relevance/topic_relevance_decorator.py +57 -0
- ibm_watsonx_gov/metrics/topic_relevance/topic_relevance_metric.py +106 -0
- ibm_watsonx_gov/metrics/unethical_behavior/__init__.py +8 -0
- ibm_watsonx_gov/metrics/unethical_behavior/unethical_behavior_decorator.py +61 -0
- ibm_watsonx_gov/metrics/unethical_behavior/unethical_behavior_metric.py +103 -0
- ibm_watsonx_gov/metrics/unsuccessful_requests/__init__.py +0 -0
- ibm_watsonx_gov/metrics/unsuccessful_requests/unsuccessful_requests_decorator.py +66 -0
- ibm_watsonx_gov/metrics/unsuccessful_requests/unsuccessful_requests_metric.py +128 -0
- ibm_watsonx_gov/metrics/user_id/__init__.py +0 -0
- ibm_watsonx_gov/metrics/user_id/user_id_metric.py +111 -0
- ibm_watsonx_gov/metrics/utils.py +440 -0
- ibm_watsonx_gov/metrics/violence/__init__.py +8 -0
- ibm_watsonx_gov/metrics/violence/violence_decorator.py +60 -0
- ibm_watsonx_gov/metrics/violence/violence_metric.py +103 -0
- ibm_watsonx_gov/prompt_evaluator/__init__.py +9 -0
- ibm_watsonx_gov/prompt_evaluator/impl/__init__.py +8 -0
- ibm_watsonx_gov/prompt_evaluator/impl/prompt_evaluator_impl.py +554 -0
- ibm_watsonx_gov/prompt_evaluator/impl/pta_lifecycle_evaluator.py +2332 -0
- ibm_watsonx_gov/prompt_evaluator/prompt_evaluator.py +262 -0
- ibm_watsonx_gov/providers/__init__.py +8 -0
- ibm_watsonx_gov/providers/detectors_provider.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/providers/detectors_provider.py +415 -0
- ibm_watsonx_gov/providers/eval_assist_provider.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/providers/eval_assist_provider.py +266 -0
- ibm_watsonx_gov/providers/inference_engines/__init__.py +0 -0
- ibm_watsonx_gov/providers/inference_engines/custom_inference_engine.py +165 -0
- ibm_watsonx_gov/providers/inference_engines/portkey_inference_engine.py +57 -0
- ibm_watsonx_gov/providers/llmevalkit/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/ciso_agent/main.py +516 -0
- ibm_watsonx_gov/providers/llmevalkit/ciso_agent/preprocess_log.py +111 -0
- ibm_watsonx_gov/providers/llmevalkit/ciso_agent/utils.py +186 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/README.md +411 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/__init__.py +27 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/README.md +306 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/__init__.py +89 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/__init__.py +30 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/base.py +411 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/code_agent.py +1254 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/exact_match.py +134 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/fuzzy_string.py +104 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/hybrid.py +516 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/comparators/llm_judge.py +1882 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/pipeline.py +387 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/types.py +178 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/comparison/utils.py +298 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/consts.py +33 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/__init__.py +31 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/base.py +26 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_call/__init__.py +4 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_call/general.py +46 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_call/general_metrics.json +783 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_call/general_metrics_runtime.json +580 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_selection/__init__.py +6 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_selection/function_selection.py +28 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_selection/function_selection_metrics.json +599 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/function_selection/function_selection_metrics_runtime.json +477 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/loader.py +259 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/parameter/__init__.py +7 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/parameter/parameter.py +52 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/parameter/parameter_metrics.json +613 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/parameter/parameter_metrics_runtime.json +489 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/trajectory/__init__.py +7 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/trajectory/trajectory.py +43 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/trajectory/trajectory_metrics.json +161 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/adapters.py +102 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/pipeline.py +355 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/semantic_checker.py +816 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/static_checker.py +297 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/transformation_prompts.py +509 -0
- ibm_watsonx_gov/providers/llmevalkit/function_calling/pipeline/types.py +596 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/README.md +375 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/__init__.py +137 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/base.py +426 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/output_parser.py +364 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/consts.py +7 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/ibm_watsonx_ai/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/ibm_watsonx_ai/ibm_watsonx_ai.py +656 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/litellm/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/litellm/litellm.py +509 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/litellm/rits.py +224 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/litellm/watsonx.py +60 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/mock_llm_client.py +75 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/openai/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/openai/openai.py +639 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/wxo_ai_gateway/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/wxo_ai_gateway/wxo_ai_gateway.py +134 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/providers/wxo_ai_gateway/wxo_ai_gateway_inference.py +214 -0
- ibm_watsonx_gov/providers/llmevalkit/llm/types.py +136 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/__init__.py +4 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/field.py +255 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/metric.py +332 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/metrics_runner.py +188 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/prompt.py +403 -0
- ibm_watsonx_gov/providers/llmevalkit/metrics/utils.py +46 -0
- ibm_watsonx_gov/providers/llmevalkit/prompt/__init__.py +0 -0
- ibm_watsonx_gov/providers/llmevalkit/prompt/runner.py +144 -0
- ibm_watsonx_gov/providers/tool_call_metric_provider.py +455 -0
- ibm_watsonx_gov/providers/unitxt_provider.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/tools/__init__.py +10 -0
- ibm_watsonx_gov/tools/clients/__init__.py +11 -0
- ibm_watsonx_gov/tools/clients/ai_tool_client.py +405 -0
- ibm_watsonx_gov/tools/clients/detector_client.py +82 -0
- ibm_watsonx_gov/tools/core/__init__.py +8 -0
- ibm_watsonx_gov/tools/core/tool_loader.py +237 -0
- ibm_watsonx_gov/tools/entities/__init__.py +8 -0
- ibm_watsonx_gov/tools/entities/ai_tools.py +435 -0
- ibm_watsonx_gov/tools/onboarding/create/answer_relevance_detector.json +57 -0
- ibm_watsonx_gov/tools/onboarding/create/chromadb_retrieval_tool.json +63 -0
- ibm_watsonx_gov/tools/onboarding/create/context_relevance_detector.json +57 -0
- ibm_watsonx_gov/tools/onboarding/create/duduckgo_search_tool.json +53 -0
- ibm_watsonx_gov/tools/onboarding/create/google_search_tool.json +62 -0
- ibm_watsonx_gov/tools/onboarding/create/hap_detector.json +70 -0
- ibm_watsonx_gov/tools/onboarding/create/jailbreak_detector.json +70 -0
- ibm_watsonx_gov/tools/onboarding/create/pii_detector.json +36 -0
- ibm_watsonx_gov/tools/onboarding/create/prompt_safety_risk_detector.json +69 -0
- ibm_watsonx_gov/tools/onboarding/create/topic_relevance_detector.json +57 -0
- ibm_watsonx_gov/tools/onboarding/create/weather_tool.json +39 -0
- ibm_watsonx_gov/tools/onboarding/create/webcrawler_tool.json +34 -0
- ibm_watsonx_gov/tools/onboarding/create/wikipedia_search_tool.json +53 -0
- ibm_watsonx_gov/tools/onboarding/delete/delete_tools.json +4 -0
- ibm_watsonx_gov/tools/onboarding/update/google_search_tool.json +38 -0
- ibm_watsonx_gov/tools/ootb/__init__.py +8 -0
- ibm_watsonx_gov/tools/ootb/detectors/__init__.py +8 -0
- ibm_watsonx_gov/tools/ootb/detectors/hap_detector_tool.py +109 -0
- ibm_watsonx_gov/tools/ootb/detectors/jailbreak_detector_tool.py +104 -0
- ibm_watsonx_gov/tools/ootb/detectors/pii_detector_tool.py +83 -0
- ibm_watsonx_gov/tools/ootb/detectors/prompt_safety_risk_detector_tool.py +111 -0
- ibm_watsonx_gov/tools/ootb/detectors/topic_relevance_detector_tool.py +101 -0
- ibm_watsonx_gov/tools/ootb/rag/__init__.py +8 -0
- ibm_watsonx_gov/tools/ootb/rag/answer_relevance_detector_tool.py +119 -0
- ibm_watsonx_gov/tools/ootb/rag/context_relevance_detector_tool.py +118 -0
- ibm_watsonx_gov/tools/ootb/search/__init__.py +8 -0
- ibm_watsonx_gov/tools/ootb/search/duckduckgo_search_tool.py +62 -0
- ibm_watsonx_gov/tools/ootb/search/google_search_tool.py +105 -0
- ibm_watsonx_gov/tools/ootb/search/weather_tool.py +95 -0
- ibm_watsonx_gov/tools/ootb/search/web_crawler_tool.py +69 -0
- ibm_watsonx_gov/tools/ootb/search/wikipedia_search_tool.py +63 -0
- ibm_watsonx_gov/tools/ootb/vectordb/__init__.py +8 -0
- ibm_watsonx_gov/tools/ootb/vectordb/chromadb_retriever_tool.py +111 -0
- ibm_watsonx_gov/tools/rest_api/__init__.py +10 -0
- ibm_watsonx_gov/tools/rest_api/restapi_tool.py +72 -0
- ibm_watsonx_gov/tools/schemas/__init__.py +10 -0
- ibm_watsonx_gov/tools/schemas/search_tool_schema.py +46 -0
- ibm_watsonx_gov/tools/schemas/vectordb_retrieval_schema.py +55 -0
- ibm_watsonx_gov/tools/utils/__init__.py +14 -0
- ibm_watsonx_gov/tools/utils/constants.py +69 -0
- ibm_watsonx_gov/tools/utils/display_utils.py +38 -0
- ibm_watsonx_gov/tools/utils/environment.py +108 -0
- ibm_watsonx_gov/tools/utils/package_utils.py +40 -0
- ibm_watsonx_gov/tools/utils/platform_url_mapping.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/tools/utils/python_utils.py +68 -0
- ibm_watsonx_gov/tools/utils/tool_utils.py +206 -0
- ibm_watsonx_gov/traces/__init__.py +8 -0
- ibm_watsonx_gov/traces/span_exporter.py +195 -0
- ibm_watsonx_gov/traces/span_node.py +251 -0
- ibm_watsonx_gov/traces/span_util.py +153 -0
- ibm_watsonx_gov/traces/trace_utils.py +1074 -0
- ibm_watsonx_gov/utils/__init__.py +8 -0
- ibm_watsonx_gov/utils/aggregation_util.py +346 -0
- ibm_watsonx_gov/utils/async_util.py +62 -0
- ibm_watsonx_gov/utils/authenticator.py +144 -0
- ibm_watsonx_gov/utils/constants.py +15 -0
- ibm_watsonx_gov/utils/errors.py +40 -0
- ibm_watsonx_gov/utils/gov_sdk_logger.py +39 -0
- ibm_watsonx_gov/utils/insights_generator.py +1285 -0
- ibm_watsonx_gov/utils/python_utils.py +425 -0
- ibm_watsonx_gov/utils/rest_util.py +73 -0
- ibm_watsonx_gov/utils/segment_batch_manager.py +162 -0
- ibm_watsonx_gov/utils/singleton_meta.py +25 -0
- ibm_watsonx_gov/utils/url_mapping.cpython-313-darwin.so +0 -0
- ibm_watsonx_gov/utils/validation_util.py +126 -0
- ibm_watsonx_gov/visualizations/__init__.py +13 -0
- ibm_watsonx_gov/visualizations/metric_descriptions.py +57 -0
- ibm_watsonx_gov/visualizations/model_insights.py +1304 -0
- ibm_watsonx_gov/visualizations/visualization_utils.py +75 -0
- ibm_watsonx_gov-1.3.3.dist-info/METADATA +93 -0
- ibm_watsonx_gov-1.3.3.dist-info/RECORD +353 -0
- ibm_watsonx_gov-1.3.3.dist-info/WHEEL +6 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------
|
|
2
|
+
# IBM Confidential
|
|
3
|
+
# Licensed Materials - Property of IBM
|
|
4
|
+
# 5737-H76, 5900-A3Q
|
|
5
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
6
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
7
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
8
|
+
# ----------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------
|
|
2
|
+
# IBM Confidential
|
|
3
|
+
# Licensed Materials - Property of IBM
|
|
4
|
+
# 5737-H76, 5900-A3Q
|
|
5
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
6
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
7
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
8
|
+
# ----------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
from typing import List
|
|
12
|
+
|
|
13
|
+
import pandas as pd
|
|
14
|
+
|
|
15
|
+
from ibm_watsonx_gov.entities.ai_experiment import Node
|
|
16
|
+
|
|
17
|
+
AI_SERVICE_QUALITY = "ai_service_quality"
|
|
18
|
+
CUSTOM_METRICS = "custom_metrics"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AIExperimentUtils:
|
|
22
|
+
""" Class for AI experiment related utility methods """
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def construct_result_attachment_payload(cls, evaluation_results: dict, nodes: List[Node] = None):
|
|
26
|
+
"""
|
|
27
|
+
Constructs payload for result attachment from experiment run's result
|
|
28
|
+
Args:
|
|
29
|
+
- evaluation_results: The dict of metrics from evaluators and custom.
|
|
30
|
+
|
|
31
|
+
Returns: The payload for result attachment and total number of records processed
|
|
32
|
+
"""
|
|
33
|
+
attachment_payload = {}
|
|
34
|
+
node_name_to_id_map = {}
|
|
35
|
+
if nodes is not None:
|
|
36
|
+
node_name_to_id_map = {node.name: node.id for node in nodes}
|
|
37
|
+
|
|
38
|
+
if not evaluation_results:
|
|
39
|
+
raise ValueError("Evaluation result is empty or missing.")
|
|
40
|
+
|
|
41
|
+
total_records = 0
|
|
42
|
+
agent_evaluation_result = {
|
|
43
|
+
"evaluation_result": {}
|
|
44
|
+
}
|
|
45
|
+
node_level_results = []
|
|
46
|
+
node_name_to_node_object = {}
|
|
47
|
+
|
|
48
|
+
# Separating agent level and node level metrics using the applies_to field in the result.
|
|
49
|
+
for monitor_name, metric_results in evaluation_results.items():
|
|
50
|
+
# If result for some monitor is empty, skipping it
|
|
51
|
+
if not metric_results:
|
|
52
|
+
continue
|
|
53
|
+
agent_level_metrics = []
|
|
54
|
+
node_level_metrics = defaultdict(list)
|
|
55
|
+
|
|
56
|
+
for metric_result in metric_results:
|
|
57
|
+
result_applies_to = metric_result.get(
|
|
58
|
+
"applies_to", "conversation")
|
|
59
|
+
metric_id = metric_result.get("name", "")
|
|
60
|
+
metric_result["id"] = metric_id
|
|
61
|
+
metric_result["name"] = metric_id.capitalize().replace(
|
|
62
|
+
"_", " ")
|
|
63
|
+
# If thresholds exist, add them to the run result
|
|
64
|
+
thresholds = metric_result.pop("thresholds", [])
|
|
65
|
+
if thresholds:
|
|
66
|
+
for threshold in thresholds:
|
|
67
|
+
metric_result[threshold.get(
|
|
68
|
+
"type")] = threshold.get("value")
|
|
69
|
+
|
|
70
|
+
if result_applies_to == "node":
|
|
71
|
+
node_name = metric_result.pop("node_name", "")
|
|
72
|
+
if node_name and result_applies_to == "node":
|
|
73
|
+
node_level_metrics[node_name].append(metric_result)
|
|
74
|
+
|
|
75
|
+
# agentic_result_components ["conversation", "message"]
|
|
76
|
+
else:
|
|
77
|
+
if total_records == 0:
|
|
78
|
+
total_records = metric_result.get("count")
|
|
79
|
+
metric_id = f"{metric_id}_for_{result_applies_to}" if monitor_name != CUSTOM_METRICS else metric_id
|
|
80
|
+
metric_result["id"] = metric_id
|
|
81
|
+
metric_result["name"] = metric_id.capitalize().replace(
|
|
82
|
+
"_", " ")
|
|
83
|
+
agent_level_metrics.append(metric_result)
|
|
84
|
+
|
|
85
|
+
# Constructing the agent level metrics result
|
|
86
|
+
agent_evaluation_result["evaluation_result"][monitor_name] = {
|
|
87
|
+
"metric_groups": cls.get_result_with_metric_groups(agent_level_metrics)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Constructing the node level metrics result
|
|
91
|
+
for node_name, metrics in node_level_metrics.items():
|
|
92
|
+
metric_groups_result = cls.get_result_with_metric_groups(
|
|
93
|
+
metrics)
|
|
94
|
+
|
|
95
|
+
if node_name not in node_name_to_node_object:
|
|
96
|
+
node_obj = {
|
|
97
|
+
"type": "tool",
|
|
98
|
+
"id": node_name_to_id_map.get(node_name, node_name),
|
|
99
|
+
"name": node_name,
|
|
100
|
+
"evaluation_result": {}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
node_obj["evaluation_result"][monitor_name] = {
|
|
104
|
+
"metric_groups": metric_groups_result
|
|
105
|
+
}
|
|
106
|
+
node_name_to_node_object[node_name] = node_obj
|
|
107
|
+
node_level_results.append(node_obj)
|
|
108
|
+
|
|
109
|
+
else:
|
|
110
|
+
node_obj = node_name_to_node_object[node_name]
|
|
111
|
+
node_obj["evaluation_result"][monitor_name] = {
|
|
112
|
+
"metric_groups": metric_groups_result
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
attachment_payload = {
|
|
116
|
+
"ai_application": agent_evaluation_result,
|
|
117
|
+
"nodes": node_level_results
|
|
118
|
+
}
|
|
119
|
+
return attachment_payload, total_records
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
def get_result_with_metric_groups(cls, metrics: list) -> list:
|
|
123
|
+
"""
|
|
124
|
+
Organises the result based on metric groups
|
|
125
|
+
Args:
|
|
126
|
+
- metrics: The list of metrics
|
|
127
|
+
|
|
128
|
+
Returns: The list containing metric groups and corresponding metrics for each group
|
|
129
|
+
"""
|
|
130
|
+
metric_groups_map = defaultdict(list)
|
|
131
|
+
for metric in metrics:
|
|
132
|
+
metric_group = metric.pop(
|
|
133
|
+
"group", "Other metrics").capitalize().replace("_", " ")
|
|
134
|
+
metric_groups_map[metric_group].append(metric)
|
|
135
|
+
|
|
136
|
+
metric_groups_result = [
|
|
137
|
+
{"name": group_name, "metrics": group_metrics} for group_name, group_metrics in metric_groups_map.items()]
|
|
138
|
+
|
|
139
|
+
return metric_groups_result
|
|
File without changes
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------
|
|
3
|
+
# IBM Confidential
|
|
4
|
+
# Licensed Materials - Property of IBM
|
|
5
|
+
# 5737-H76, 5900-A3Q
|
|
6
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
7
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
8
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
9
|
+
# ----------------------------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
from ibm_cloud_sdk_core.authenticators import (BearerTokenAuthenticator,
|
|
12
|
+
CloudPakForDataAuthenticator,
|
|
13
|
+
IAMAuthenticator)
|
|
14
|
+
from ibm_watson_openscale import APIClient as WOSClient
|
|
15
|
+
from ibm_watsonx_gov.clients.wx_ai_client import WXAIClient
|
|
16
|
+
from ibm_watsonx_gov.entities.credentials import Credentials
|
|
17
|
+
from ibm_watsonx_gov.entities.enums import Region
|
|
18
|
+
from ibm_watsonx_gov.utils.async_util import run_in_event_loop
|
|
19
|
+
from ibm_watsonx_gov.utils.segment_batch_manager import SegmentBatchManager
|
|
20
|
+
from ibm_watsonx_gov.utils.url_mapping import (WATSONX_REGION_URLS,
|
|
21
|
+
WOS_URL_MAPPING)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class APIClient():
|
|
25
|
+
"""
|
|
26
|
+
The IBM watsonx.governance sdk client. It is required to access the watsonx.governance APIs.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, credentials: Credentials | None = None):
|
|
30
|
+
self.credentials = credentials
|
|
31
|
+
self.is_cpd = False
|
|
32
|
+
if self.credentials.token:
|
|
33
|
+
authenticator = BearerTokenAuthenticator(
|
|
34
|
+
bearer_token=self.credentials.token)
|
|
35
|
+
if self.credentials.version:
|
|
36
|
+
self.is_cpd = True
|
|
37
|
+
elif self.credentials.version:
|
|
38
|
+
authenticator = CloudPakForDataAuthenticator(url=self.credentials.url,
|
|
39
|
+
username=self.credentials.username,
|
|
40
|
+
password=self.credentials.password,
|
|
41
|
+
apikey=self.credentials.api_key,
|
|
42
|
+
disable_ssl_verification=self.credentials.disable_ssl
|
|
43
|
+
)
|
|
44
|
+
self.is_cpd = True
|
|
45
|
+
elif self.credentials.region == Region.AP_SOUTH.value:
|
|
46
|
+
from ibm_cloud_sdk_core.authenticators import MCSPV2Authenticator
|
|
47
|
+
iam_url = WATSONX_REGION_URLS.get(
|
|
48
|
+
self.credentials.region).iam_url
|
|
49
|
+
authenticator = MCSPV2Authenticator(apikey=self.credentials.api_key, url=iam_url,
|
|
50
|
+
scope_id=self.credentials.scope_id, scope_collection_type=self.credentials.scope_collection_type)
|
|
51
|
+
else:
|
|
52
|
+
iam_url = WATSONX_REGION_URLS.get(
|
|
53
|
+
self.credentials.region).iam_url
|
|
54
|
+
authenticator = IAMAuthenticator(apikey=self.credentials.api_key,
|
|
55
|
+
url=iam_url,
|
|
56
|
+
disable_ssl_verification=self.credentials.disable_ssl)
|
|
57
|
+
if self.credentials.region in [Region.US_GOV_EAST1.value, "govcloudpreprod"]:
|
|
58
|
+
authenticator.token_manager.OPERATION_PATH = "/api/rest/mcsp/apikeys/token"
|
|
59
|
+
authenticator.token_manager.token_name = "token"
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
self.wos_client = WOSClient(
|
|
63
|
+
authenticator=authenticator,
|
|
64
|
+
service_url=self.credentials.url,
|
|
65
|
+
service_instance_id=self.credentials.service_instance_id,
|
|
66
|
+
)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
if "Multiple service instance id exists" in str(e) or "You are not authorized to access AI OpenScale instance" in str(e):
|
|
69
|
+
raise e
|
|
70
|
+
else:
|
|
71
|
+
if self.is_cpd:
|
|
72
|
+
dai_url = self.credentials.url
|
|
73
|
+
else:
|
|
74
|
+
dai_url = WATSONX_REGION_URLS.get(
|
|
75
|
+
self.credentials.region).dai_url
|
|
76
|
+
self.wos_client = WXAIClient(service_url=dai_url,
|
|
77
|
+
authenticator=authenticator,
|
|
78
|
+
disable_ssl_verification=self.credentials.disable_ssl,
|
|
79
|
+
is_cpd=self.is_cpd)
|
|
80
|
+
self.wos_client.validate_user()
|
|
81
|
+
|
|
82
|
+
# Adding segment event
|
|
83
|
+
segment_manager = SegmentBatchManager(api_client=self)
|
|
84
|
+
run_in_event_loop(segment_manager.track_event, {
|
|
85
|
+
"objectType": "API Client Initialization"})
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def credentials(self):
|
|
89
|
+
return self._credentials
|
|
90
|
+
|
|
91
|
+
@credentials.setter
|
|
92
|
+
def credentials(self, credentials):
|
|
93
|
+
"""
|
|
94
|
+
Setter for credentials object. If not provided, it will create a credentials object from environment variables.
|
|
95
|
+
"""
|
|
96
|
+
if not credentials:
|
|
97
|
+
self._credentials = Credentials.create_from_env()
|
|
98
|
+
else:
|
|
99
|
+
self._credentials = credentials
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------
|
|
2
|
+
# IBM Confidential
|
|
3
|
+
# Licensed Materials - Property of IBM
|
|
4
|
+
# 5737-H76, 5900-A3Q
|
|
5
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
6
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
7
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
8
|
+
# ----------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
import aiohttp
|
|
11
|
+
from ibm_watsonx_gov.utils.gov_sdk_logger import GovSDKLogger
|
|
12
|
+
from ibm_watsonx_gov.utils.python_utils import get_authenticator_token
|
|
13
|
+
|
|
14
|
+
logger = GovSDKLogger.get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SegmentClient():
|
|
18
|
+
|
|
19
|
+
def __init__(self, api_client):
|
|
20
|
+
self.api_client = api_client
|
|
21
|
+
|
|
22
|
+
async def trigger_segment_endpoint(self, segment_data):
|
|
23
|
+
try:
|
|
24
|
+
segment_publish_url = "{0}/v2/segment/events".format(
|
|
25
|
+
self.api_client.service_url)
|
|
26
|
+
|
|
27
|
+
iam_headers = {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
"accept": "application/json",
|
|
30
|
+
"Authorization": f"Bearer {get_authenticator_token(self.api_client.authenticator)}"
|
|
31
|
+
}
|
|
32
|
+
async with aiohttp.ClientSession() as session:
|
|
33
|
+
async with session.post(
|
|
34
|
+
url=segment_publish_url,
|
|
35
|
+
headers=iam_headers,
|
|
36
|
+
json=segment_data,
|
|
37
|
+
ssl=False
|
|
38
|
+
) as response:
|
|
39
|
+
text = await response.text()
|
|
40
|
+
logger.info(
|
|
41
|
+
f"Segment response: {response.status}, Body: {text}"
|
|
42
|
+
)
|
|
43
|
+
return response.status == 202
|
|
44
|
+
except Exception as ex:
|
|
45
|
+
logger.error(f"Failed to send segment events. Details: {ex}")
|
|
46
|
+
return False
|
|
Binary file
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------
|
|
3
|
+
# IBM Confidential
|
|
4
|
+
# Licensed Materials - Property of IBM
|
|
5
|
+
# 5737-H76, 5900-A3Q
|
|
6
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
7
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
8
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
9
|
+
# ----------------------------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
|
|
13
|
+
import jwt
|
|
14
|
+
import requests
|
|
15
|
+
from ibm_cloud_sdk_core.authenticators import (BearerTokenAuthenticator,
|
|
16
|
+
CloudPakForDataAuthenticator,
|
|
17
|
+
IAMAuthenticator)
|
|
18
|
+
from jwt.exceptions import DecodeError
|
|
19
|
+
from requests.exceptions import HTTPError
|
|
20
|
+
|
|
21
|
+
from ibm_watsonx_gov.utils.authenticator import Authenticator
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class WXAIClient():
|
|
25
|
+
"""
|
|
26
|
+
Client class to validate user entitlements
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, service_url: str, authenticator: CloudPakForDataAuthenticator | IAMAuthenticator | BearerTokenAuthenticator, disable_ssl_verification: bool, is_cpd: bool):
|
|
30
|
+
self.service_url = service_url
|
|
31
|
+
self.authenticator = authenticator
|
|
32
|
+
self.disable_ssl_verification = disable_ssl_verification
|
|
33
|
+
self.is_cpd = is_cpd
|
|
34
|
+
|
|
35
|
+
def validate_user(self):
|
|
36
|
+
entitlements_url = f"{self.service_url}/v2/entitlements"
|
|
37
|
+
# create a token using the authenticator
|
|
38
|
+
if isinstance(self.authenticator, BearerTokenAuthenticator):
|
|
39
|
+
bearer_token = self.authenticator.bearer_token
|
|
40
|
+
elif self.is_cpd and not isinstance(self.authenticator, BearerTokenAuthenticator):
|
|
41
|
+
creds = {
|
|
42
|
+
"url": self.service_url,
|
|
43
|
+
"username": self.authenticator.token_manager.username
|
|
44
|
+
}
|
|
45
|
+
if self.authenticator.token_manager.password:
|
|
46
|
+
creds.update(
|
|
47
|
+
{"password": self.authenticator.token_manager.password})
|
|
48
|
+
if self.authenticator.token_manager.apikey:
|
|
49
|
+
creds.update(
|
|
50
|
+
{"api_key": self.authenticator.token_manager.apikey})
|
|
51
|
+
|
|
52
|
+
auth = Authenticator(
|
|
53
|
+
credentials=creds,
|
|
54
|
+
use_cpd=self.is_cpd,
|
|
55
|
+
use_ssl=(not self.disable_ssl_verification),
|
|
56
|
+
)
|
|
57
|
+
bearer_token = auth.authenticate()
|
|
58
|
+
else:
|
|
59
|
+
bearer_token = self.authenticator.token_manager.get_token()
|
|
60
|
+
|
|
61
|
+
if not self.is_cpd:
|
|
62
|
+
# decode the token and get bss
|
|
63
|
+
try:
|
|
64
|
+
decoded_token = jwt.decode(bearer_token, options={
|
|
65
|
+
"verify_signature": False})
|
|
66
|
+
bss_account_id = decoded_token["account"]["bss"]
|
|
67
|
+
except jwt.InvalidTokenError as e:
|
|
68
|
+
raise DecodeError(
|
|
69
|
+
f"Failed while decoding the token. Token is invalid: {e}")
|
|
70
|
+
|
|
71
|
+
entitlements_url = f"{entitlements_url}?bss_account_id={bss_account_id}"
|
|
72
|
+
|
|
73
|
+
# call entitlements api and check for data_science_experience
|
|
74
|
+
response = requests.get(entitlements_url, headers={
|
|
75
|
+
"Authorization": f"Bearer {bearer_token}"}, verify=not self.disable_ssl_verification)
|
|
76
|
+
|
|
77
|
+
if response.status_code == 200:
|
|
78
|
+
response_json = json.loads(response.text)
|
|
79
|
+
dsx = response_json.get("entitlements", {}).get(
|
|
80
|
+
"data_science_experience")
|
|
81
|
+
if not dsx:
|
|
82
|
+
raise ValueError("User is not authorized.")
|
|
83
|
+
else:
|
|
84
|
+
return True
|
|
85
|
+
else:
|
|
86
|
+
raise HTTPError(
|
|
87
|
+
f"Request failed with status code: {response.status_code}")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------
|
|
2
|
+
# IBM Confidential
|
|
3
|
+
# Licensed Materials - Property of IBM
|
|
4
|
+
# 5737-H76, 5900-A3Q
|
|
5
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
6
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
7
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
8
|
+
# ----------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
from ..entities.credentials import (Credentials, WxAICredentials,
|
|
11
|
+
WxGovConsoleCredentials)
|
|
12
|
+
from .agentic_ai_configuration import AgenticAIConfiguration
|
|
13
|
+
from .gen_ai_configuration import GenAIConfiguration
|
|
14
|
+
from .model_risk_configuration import ModelRiskConfiguration
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------------------
|
|
2
|
+
# IBM Confidential
|
|
3
|
+
# Licensed Materials - Property of IBM
|
|
4
|
+
# 5737-H76, 5900-A3Q
|
|
5
|
+
# © Copyright IBM Corp. 2025 All Rights Reserved.
|
|
6
|
+
# US Government Users Restricted Rights - Use, duplication or disclosure restricted by
|
|
7
|
+
# GSA ADPSchedule Contract with IBM Corp.
|
|
8
|
+
# ----------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from typing import Annotated, Optional
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, Field, model_validator
|
|
14
|
+
from typing_extensions import Self
|
|
15
|
+
|
|
16
|
+
from ibm_watsonx_gov.config.gen_ai_configuration import GenAIConfiguration
|
|
17
|
+
from ibm_watsonx_gov.entities.enums import EvaluatorFields
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OTLPCollectorConfiguration(BaseModel):
|
|
21
|
+
"""
|
|
22
|
+
Defines the OTLPCollectorConfiguration class.
|
|
23
|
+
It contains the configuration settings for the OpenTelemetry Protocol collector.
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
1. Create OTLPCollectorConfiguration with default parameters
|
|
27
|
+
.. code-block:: python
|
|
28
|
+
|
|
29
|
+
oltp_config = OTLPCollectorConfiguration()
|
|
30
|
+
|
|
31
|
+
1. Create OTLPCollectorConfiguration by providing server endpoint details.
|
|
32
|
+
.. code-block:: python
|
|
33
|
+
|
|
34
|
+
oltp_config = OTLPCollectorConfiguration(app_name="app",
|
|
35
|
+
endpoint="https://hostname/ml/v1/traces",
|
|
36
|
+
timeout=10,
|
|
37
|
+
headers={"Authorization": "Bearer token"})
|
|
38
|
+
"""
|
|
39
|
+
app_name: Annotated[str | None,
|
|
40
|
+
Field(title="App Name",
|
|
41
|
+
description="Application name for tracing.")]
|
|
42
|
+
endpoint: Annotated[str | None,
|
|
43
|
+
Field(title="OTLP Endpoint",
|
|
44
|
+
description="The OTLP collector endpoint URL for sending trace data. Default value is 'http://localhost:4318/v1/traces'",
|
|
45
|
+
default="http://localhost:4318/v1/traces")]
|
|
46
|
+
insecure: Annotated[bool | None,
|
|
47
|
+
Field(title="Insecure Connection",
|
|
48
|
+
description="Whether to disable TLS for the exporter (i.e., use an insecure connection). Default is False.",
|
|
49
|
+
default=False)]
|
|
50
|
+
is_grpc: Annotated[bool | None,
|
|
51
|
+
Field(title="Use gRPC",
|
|
52
|
+
description="If True, use gRPC for exporting traces instead of HTTP. Default is False.",
|
|
53
|
+
default=False)]
|
|
54
|
+
timeout: Annotated[int | None,
|
|
55
|
+
Field(title="Timeout",
|
|
56
|
+
description="Timeout in milliseconds for sending telemetry data to the collector. Default is 100ms.",
|
|
57
|
+
default=100)]
|
|
58
|
+
headers: Annotated[dict[str, str] | None,
|
|
59
|
+
Field(title="Headers",
|
|
60
|
+
description="Headers needed to call the server.",
|
|
61
|
+
default_factory=dict)]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class TracingConfiguration(BaseModel):
|
|
65
|
+
"""
|
|
66
|
+
Defines the tracing configuration class.
|
|
67
|
+
Tracing configuration is required if the the evaluations are needed to be tracked in an experiment or if the agentic application traces should be sent to a Open Telemetry Collector.
|
|
68
|
+
One of project_id or space_id is required.
|
|
69
|
+
If the otlp_collector_config is provided, the traces are logged to Open Telemetry Collector, otherwise the traces are logged to file on disk.
|
|
70
|
+
If its required to log the traces to both collector and local file, provide the otlp_collector_config and set the flag log_traces_to_file to True.
|
|
71
|
+
|
|
72
|
+
Examples:
|
|
73
|
+
1. Create Tracing configuration to track the results in an experiment
|
|
74
|
+
.. code-block:: python
|
|
75
|
+
|
|
76
|
+
tracing_config = TracingConfiguration(project_id="...")
|
|
77
|
+
agentic_evaluator = AgenticEvaluator(tracing_configuration=tracing_config)
|
|
78
|
+
agentic_evaluator.track_experiment(name="my_experiment")
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
2. Create Tracing configuration to send traces to collector
|
|
82
|
+
.. code-block:: python
|
|
83
|
+
|
|
84
|
+
oltp_collector_config = OTLPCollectorConfiguration(endpoint="http://hostname:4318/v1/traces")
|
|
85
|
+
tracing_config = TracingConfiguration(space_id="...",
|
|
86
|
+
resource_attributes={
|
|
87
|
+
"wx-deployment-id": deployment_id,
|
|
88
|
+
"wx-instance-id": "wml-instance-id1",
|
|
89
|
+
"wx-ai-service-id": "ai-service-id1"},
|
|
90
|
+
otlp_collector_config=oltp_collector_config)
|
|
91
|
+
agentic_evaluator = AgenticEvaluator(tracing_configuration=tracing_config)
|
|
92
|
+
...
|
|
93
|
+
"""
|
|
94
|
+
project_id: Annotated[str | None,
|
|
95
|
+
Field(title="Project ID",
|
|
96
|
+
description="The project id.",
|
|
97
|
+
default=None)]
|
|
98
|
+
space_id: Annotated[str | None,
|
|
99
|
+
Field(title="Space ID",
|
|
100
|
+
description="The space id.",
|
|
101
|
+
default=None)]
|
|
102
|
+
resource_attributes: Annotated[dict[str, str] | None,
|
|
103
|
+
Field(title="Resource Attributes",
|
|
104
|
+
description="The resource attributes set in all the spans.",
|
|
105
|
+
default_factory=dict)]
|
|
106
|
+
otlp_collector_config: Annotated[OTLPCollectorConfiguration | None,
|
|
107
|
+
Field(title="OTLP Collector Config",
|
|
108
|
+
description="OTLP Collector configuration.",
|
|
109
|
+
default=None)]
|
|
110
|
+
log_traces_to_file: Annotated[bool | None,
|
|
111
|
+
Field(title="Log Traces to file",
|
|
112
|
+
description="The flag to enable logging of traces to a file. If set to True, the traces are logged to a file. Use the flag when its needed to log the traces to file and to be sent to the server simultaneously.",
|
|
113
|
+
default=False)]
|
|
114
|
+
|
|
115
|
+
@model_validator(mode="after")
|
|
116
|
+
def validate_fields(self) -> Self:
|
|
117
|
+
if not (self.project_id or self.space_id):
|
|
118
|
+
raise ValueError(
|
|
119
|
+
"The project or space id is required. Please provide one of them and retry.")
|
|
120
|
+
|
|
121
|
+
return self
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def create_from_env(cls):
|
|
125
|
+
# TODO get the default value and validate the tracing url env variable
|
|
126
|
+
tracing_url = os.getenv("WATSONX_TRACING_URL") or ""
|
|
127
|
+
project_id = os.getenv("PROJECT_ID")
|
|
128
|
+
space_id = os.getenv("SPACE_ID")
|
|
129
|
+
|
|
130
|
+
return TracingConfiguration(
|
|
131
|
+
tracing_url=tracing_url,
|
|
132
|
+
project_id=project_id,
|
|
133
|
+
space_id=space_id
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def enable_server_traces(self) -> bool:
|
|
138
|
+
# Check if otlp_collector_config field was set
|
|
139
|
+
return self.otlp_collector_config is not None
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def enable_local_traces(self) -> bool:
|
|
143
|
+
# if otlp_collector_config is not set, enable local traces
|
|
144
|
+
return self.log_traces_to_file or self.otlp_collector_config is None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class AgenticAIConfiguration(GenAIConfiguration):
|
|
148
|
+
"""
|
|
149
|
+
Defines the AgenticAIConfiguration class.
|
|
150
|
+
|
|
151
|
+
The configuration interface for Agentic AI tools and applications.
|
|
152
|
+
This is used to specify the fields mapping details in the data and other configuration parameters needed for evaluation.
|
|
153
|
+
|
|
154
|
+
Examples:
|
|
155
|
+
1. Create configuration with default parameters
|
|
156
|
+
.. code-block:: python
|
|
157
|
+
|
|
158
|
+
configuration = AgenticAIConfiguration()
|
|
159
|
+
|
|
160
|
+
2. Create configuration with parameters
|
|
161
|
+
.. code-block:: python
|
|
162
|
+
|
|
163
|
+
configuration = AgenticAIConfiguration(input_fields=["input"],
|
|
164
|
+
output_fields=["output"])
|
|
165
|
+
|
|
166
|
+
2. Create configuration with dict parameters
|
|
167
|
+
.. code-block:: python
|
|
168
|
+
|
|
169
|
+
config = {"input_fields": ["input"],
|
|
170
|
+
"output_fields": ["output"],
|
|
171
|
+
"context_fields": ["contexts"],
|
|
172
|
+
"reference_fields": ["reference"]}
|
|
173
|
+
configuration = AgenticAIConfiguration(**config)
|
|
174
|
+
"""
|
|
175
|
+
message_id_field: Annotated[Optional[str], Field(title="Message id field",
|
|
176
|
+
description="The message identifier field name. Default value is 'message_id'.",
|
|
177
|
+
examples=[
|
|
178
|
+
"message_id"],
|
|
179
|
+
default="message_id")]
|
|
180
|
+
|
|
181
|
+
conversation_id_field: Annotated[Optional[str], Field(title="Conversation id field",
|
|
182
|
+
description="The conversation identifier field name. Default value is 'conversation_id'.",
|
|
183
|
+
examples=[
|
|
184
|
+
"conversation_id"],
|
|
185
|
+
default="conversation_id")]
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def create_configuration(cls, *, app_config: Optional[Self],
|
|
189
|
+
method_config: Optional[Self],
|
|
190
|
+
defaults: list[EvaluatorFields],
|
|
191
|
+
add_record_fields: bool = True) -> Self:
|
|
192
|
+
"""
|
|
193
|
+
Creates a configuration object based on the provided parameters.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
app_config(Optional[Self]): The application configuration.
|
|
197
|
+
method_config(Optional[Self]): The method configuration.
|
|
198
|
+
defaults(list[EvaluatorFields]): The default fields to include in the configuration.
|
|
199
|
+
add_record_fields(bool, optional): Whether to add record fields to the configuration. Defaults to True.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Self: The created configuration object.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
if method_config is not None:
|
|
206
|
+
return method_config
|
|
207
|
+
|
|
208
|
+
if app_config is not None:
|
|
209
|
+
return app_config
|
|
210
|
+
|
|
211
|
+
mapping = EvaluatorFields.get_default_fields_mapping()
|
|
212
|
+
config = {field.value: mapping[field] for field in defaults}
|
|
213
|
+
|
|
214
|
+
if not add_record_fields:
|
|
215
|
+
return cls(**config)
|
|
216
|
+
|
|
217
|
+
system_fields = [EvaluatorFields.RECORD_ID_FIELD,
|
|
218
|
+
EvaluatorFields.RECORD_TIMESTAMP_FIELD,
|
|
219
|
+
EvaluatorFields.MESSAGE_ID_FIELD,
|
|
220
|
+
EvaluatorFields.CONVERSATION_ID_FIELD]
|
|
221
|
+
for field in system_fields:
|
|
222
|
+
if field not in defaults:
|
|
223
|
+
config[field.value] = EvaluatorFields.get_default_fields_mapping()[
|
|
224
|
+
field]
|
|
225
|
+
return cls(**config)
|