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,426 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import asyncio
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any, Callable, Dict, List, Optional, Type, TypeVar, Union
|
|
5
|
+
|
|
6
|
+
# Import from parent module to ensure singleton registry
|
|
7
|
+
from llmevalkit.llm import _REGISTRY
|
|
8
|
+
from .types import GenerationMode, GenerationArgs, ParameterMapper
|
|
9
|
+
|
|
10
|
+
T = TypeVar("T", bound="LLMClient")
|
|
11
|
+
Hook = Callable[[str, Dict[str, Any]], None]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def register_llm(name: str) -> Callable[[Type[T]], Type[T]]:
|
|
15
|
+
"""
|
|
16
|
+
Register an LLM client class with the global registry.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
name: Unique identifier for the client
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Decorator function that registers the class
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def deco(cls: Type["LLMClient"]) -> Type["LLMClient"]:
|
|
26
|
+
_REGISTRY[name] = cls
|
|
27
|
+
return cls
|
|
28
|
+
|
|
29
|
+
return deco
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_llm(name: str) -> Type["LLMClient"]:
|
|
33
|
+
"""
|
|
34
|
+
Retrieve an LLM client class from the global registry.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
name: Identifier for the client
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
LLMClient class
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
ValueError: If no client is registered under the given name
|
|
44
|
+
"""
|
|
45
|
+
if not _REGISTRY:
|
|
46
|
+
# Import providers to populate registry
|
|
47
|
+
from llmevalkit.llm import _import_providers
|
|
48
|
+
|
|
49
|
+
_import_providers()
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
return _REGISTRY[name]
|
|
53
|
+
except KeyError:
|
|
54
|
+
available = list(_REGISTRY.keys())
|
|
55
|
+
raise ValueError(
|
|
56
|
+
f"No LLMClient registered under '{name}'. "
|
|
57
|
+
f"Available clients: {available}"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def list_available_llms() -> List[str]:
|
|
62
|
+
"""
|
|
63
|
+
List all registered LLM client names.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
List of registered LLM client names
|
|
67
|
+
"""
|
|
68
|
+
if not _REGISTRY:
|
|
69
|
+
# Import providers to populate registry
|
|
70
|
+
from llmevalkit.llm import _import_providers
|
|
71
|
+
|
|
72
|
+
_import_providers()
|
|
73
|
+
|
|
74
|
+
return list(_REGISTRY.keys())
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class MethodConfig:
|
|
78
|
+
"""
|
|
79
|
+
Configuration for a provider method.
|
|
80
|
+
|
|
81
|
+
Attributes:
|
|
82
|
+
path: Dot-delimited attribute path on the client (e.g. "chat.completions.create").
|
|
83
|
+
prompt_arg: Name of the parameter used for the prompt/messages.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(self, path: str, prompt_arg: str) -> None:
|
|
87
|
+
self.path = path
|
|
88
|
+
self.prompt_arg = prompt_arg
|
|
89
|
+
|
|
90
|
+
def resolve(self, client: Any) -> Callable[..., Any]:
|
|
91
|
+
"""
|
|
92
|
+
Traverse `path` on `client` to retrieve the bound callable.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
AttributeError: if any attribute in the path is missing.
|
|
96
|
+
TypeError: if the resolved attribute is not callable.
|
|
97
|
+
"""
|
|
98
|
+
obj: Any = client
|
|
99
|
+
for attr in self.path.split("."):
|
|
100
|
+
obj = getattr(obj, attr, None)
|
|
101
|
+
if obj is None:
|
|
102
|
+
raise AttributeError(
|
|
103
|
+
f"Could not resolve method path '{self.path}' on {client}"
|
|
104
|
+
)
|
|
105
|
+
if not callable(obj):
|
|
106
|
+
raise TypeError(f"Resolved '{self.path}' is not callable on {client}")
|
|
107
|
+
return obj
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class LLMClient(ABC):
|
|
111
|
+
"""
|
|
112
|
+
Abstract base wrapper for any LLM provider.
|
|
113
|
+
|
|
114
|
+
Responsibilities:
|
|
115
|
+
- Accept an existing SDK client or construct one from kwargs.
|
|
116
|
+
- Register provider methods via MethodConfig.
|
|
117
|
+
- Provide sync/async/batch generate calls.
|
|
118
|
+
- Emit observability hooks.
|
|
119
|
+
- Parse raw responses into plain text.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
def __init__(
|
|
123
|
+
self,
|
|
124
|
+
*,
|
|
125
|
+
client: Optional[Any] = None,
|
|
126
|
+
client_needs_init: bool = False,
|
|
127
|
+
hooks: Optional[List[Hook]] = None,
|
|
128
|
+
**provider_kwargs: Any,
|
|
129
|
+
) -> None:
|
|
130
|
+
"""
|
|
131
|
+
Initialize the wrapper.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
client: Pre-initialized provider SDK instance.
|
|
135
|
+
client_needs_init: If True, client is not initialized and will be
|
|
136
|
+
initialized with provider_kwargs.
|
|
137
|
+
hooks: Callables(event_name, payload) for observability.
|
|
138
|
+
provider_kwargs: Passed to provider_class constructor if client is None.
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
TypeError: if `client` is provided but is not instance of provider_class.
|
|
142
|
+
RuntimeError: if provider_class instantiation fails.
|
|
143
|
+
"""
|
|
144
|
+
self._hooks: List[Hook] = hooks or []
|
|
145
|
+
self._method_configs: Dict[str, MethodConfig] = {}
|
|
146
|
+
self._parameter_mapper: Optional[ParameterMapper] = None
|
|
147
|
+
|
|
148
|
+
self._other_kwargs = provider_kwargs
|
|
149
|
+
if client is not None:
|
|
150
|
+
if not isinstance(client, self.provider_class()):
|
|
151
|
+
raise TypeError(
|
|
152
|
+
f"Expected client of type {self.provider_class().__name__}, "
|
|
153
|
+
f"got {type(client).__name__}"
|
|
154
|
+
)
|
|
155
|
+
self._client = client
|
|
156
|
+
else:
|
|
157
|
+
if client_needs_init:
|
|
158
|
+
sig = inspect.signature(self.provider_class().__init__)
|
|
159
|
+
init_kwargs = {
|
|
160
|
+
k: v
|
|
161
|
+
for k, v in provider_kwargs.items()
|
|
162
|
+
if k in sig.parameters and k != "self"
|
|
163
|
+
}
|
|
164
|
+
self._other_kwargs = {
|
|
165
|
+
k: v
|
|
166
|
+
for k, v in provider_kwargs.items()
|
|
167
|
+
if k not in sig.parameters and k != "self"
|
|
168
|
+
}
|
|
169
|
+
try:
|
|
170
|
+
self._client = self.provider_class()(**init_kwargs)
|
|
171
|
+
except Exception as e:
|
|
172
|
+
raise RuntimeError(
|
|
173
|
+
f"Failed to initialize {self.provider_class().__name__}: {e}"
|
|
174
|
+
) from e
|
|
175
|
+
else:
|
|
176
|
+
self._client = self.provider_class()
|
|
177
|
+
|
|
178
|
+
self._register_methods()
|
|
179
|
+
self._setup_parameter_mapper()
|
|
180
|
+
|
|
181
|
+
@classmethod
|
|
182
|
+
@abstractmethod
|
|
183
|
+
def provider_class(cls) -> Type:
|
|
184
|
+
"""
|
|
185
|
+
Underlying SDK client class, e.g. openai.OpenAI or litellm.LiteLLM.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
@abstractmethod
|
|
189
|
+
def _register_methods(self) -> None:
|
|
190
|
+
"""
|
|
191
|
+
Subclasses register MethodConfig entries by calling:
|
|
192
|
+
self.set_method_config(key, path, prompt_arg)
|
|
193
|
+
for keys: 'text', 'chat', 'text_async', 'chat_async'.
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
def _setup_parameter_mapper(self) -> None:
|
|
197
|
+
"""
|
|
198
|
+
Setup parameter mapping for the provider. Override in subclasses to configure
|
|
199
|
+
mapping from generic GenerationArgs to provider-specific parameters.
|
|
200
|
+
"""
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
def set_method_config(self, key: str, path: str, prompt_arg: str) -> None:
|
|
204
|
+
"""
|
|
205
|
+
Register how to invoke a provider method.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
key: Identifier ('text', 'chat', 'text_async', 'chat_async').
|
|
209
|
+
path: Dot-separated path on the SDK client.
|
|
210
|
+
prompt_arg: Name of the argument carrying the prompt/messages.
|
|
211
|
+
"""
|
|
212
|
+
self._method_configs[key] = MethodConfig(path, prompt_arg)
|
|
213
|
+
|
|
214
|
+
def get_method_config(self, key: str) -> MethodConfig:
|
|
215
|
+
"""
|
|
216
|
+
Retrieve a previously registered MethodConfig.
|
|
217
|
+
|
|
218
|
+
Raises:
|
|
219
|
+
KeyError: if no config exists for `key`.
|
|
220
|
+
"""
|
|
221
|
+
try:
|
|
222
|
+
return self._method_configs[key]
|
|
223
|
+
except KeyError:
|
|
224
|
+
raise KeyError(f"No method config registered under '{key}'")
|
|
225
|
+
|
|
226
|
+
def get_client(self) -> Any:
|
|
227
|
+
"""Return the raw underlying SDK client."""
|
|
228
|
+
return self._client
|
|
229
|
+
|
|
230
|
+
def _emit(self, event: str, payload: Dict[str, Any]) -> None:
|
|
231
|
+
"""Invoke all observability hooks, swallowing errors."""
|
|
232
|
+
for hook in self._hooks:
|
|
233
|
+
try:
|
|
234
|
+
hook(event, payload)
|
|
235
|
+
except Exception:
|
|
236
|
+
pass
|
|
237
|
+
|
|
238
|
+
def _filter_sensitive_args(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
239
|
+
"""
|
|
240
|
+
Filter out sensitive information from call arguments before logging.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
args: Dictionary of call arguments that may contain sensitive data
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
Filtered dictionary with sensitive keys masked or removed
|
|
247
|
+
"""
|
|
248
|
+
# Define sensitive keys that should be filtered out
|
|
249
|
+
sensitive_keys = {
|
|
250
|
+
# RITS-specific sensitive keys
|
|
251
|
+
"api_key",
|
|
252
|
+
"headers",
|
|
253
|
+
# IBM WatsonX AI sensitive keys
|
|
254
|
+
"project_id",
|
|
255
|
+
"credentials",
|
|
256
|
+
# General sensitive keys
|
|
257
|
+
"authorization",
|
|
258
|
+
"secret",
|
|
259
|
+
"password",
|
|
260
|
+
"key",
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
filtered_args = {}
|
|
264
|
+
for key, value in args.items():
|
|
265
|
+
if key.lower() in sensitive_keys or any(
|
|
266
|
+
sensitive in key.lower()
|
|
267
|
+
for sensitive in ["key", "secret", "auth", "credential"]
|
|
268
|
+
):
|
|
269
|
+
filtered_args[key] = "SECRET"
|
|
270
|
+
elif isinstance(value, dict) and key == "headers":
|
|
271
|
+
# Special handling for headers dict to filter out sensitive header values
|
|
272
|
+
filtered_headers = {}
|
|
273
|
+
for header_key, header_value in value.items():
|
|
274
|
+
if any(
|
|
275
|
+
sensitive in header_key.lower()
|
|
276
|
+
for sensitive in ["key", "auth", "secret"]
|
|
277
|
+
):
|
|
278
|
+
filtered_headers[header_key] = "SECRET"
|
|
279
|
+
else:
|
|
280
|
+
filtered_headers[header_key] = header_value
|
|
281
|
+
filtered_args[key] = filtered_headers
|
|
282
|
+
else:
|
|
283
|
+
filtered_args[key] = value
|
|
284
|
+
|
|
285
|
+
return filtered_args
|
|
286
|
+
|
|
287
|
+
@abstractmethod
|
|
288
|
+
def _parse_llm_response(self, raw: Any) -> str:
|
|
289
|
+
"""
|
|
290
|
+
Extract the generated text from a single raw response.
|
|
291
|
+
|
|
292
|
+
Raises:
|
|
293
|
+
ValueError: if extraction fails.
|
|
294
|
+
"""
|
|
295
|
+
|
|
296
|
+
def generate(
|
|
297
|
+
self,
|
|
298
|
+
prompt: Union[str, List[Dict[str, Any]]],
|
|
299
|
+
mode: Union[str, GenerationMode] = GenerationMode.CHAT,
|
|
300
|
+
generation_args: Optional[GenerationArgs] = None,
|
|
301
|
+
**kwargs: Any,
|
|
302
|
+
) -> str:
|
|
303
|
+
"""
|
|
304
|
+
Synchronous generation.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
prompt: Either a plain string or a list of chat messages dicts.
|
|
308
|
+
mode: Generation mode (text, chat, text_async, chat_async).
|
|
309
|
+
generation_args: Provider-agnostic generation arguments.
|
|
310
|
+
**kwargs: Additional provider-specific parameters.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
The generated text.
|
|
314
|
+
|
|
315
|
+
Raises:
|
|
316
|
+
KeyError: if no MethodConfig for `mode`.
|
|
317
|
+
Exception: if the underlying call or parsing fails.
|
|
318
|
+
"""
|
|
319
|
+
# Convert enum to string if needed
|
|
320
|
+
mode_str = mode.value if isinstance(mode, GenerationMode) else mode
|
|
321
|
+
|
|
322
|
+
# Convert single string prompt to chat format if in chat mode
|
|
323
|
+
if mode is GenerationMode.CHAT and isinstance(prompt, str):
|
|
324
|
+
prompt = [{"role": "user", "content": prompt}]
|
|
325
|
+
|
|
326
|
+
cfg = self.get_method_config(mode_str)
|
|
327
|
+
fn = cfg.resolve(self._client)
|
|
328
|
+
|
|
329
|
+
call_args = {cfg.prompt_arg: prompt, **kwargs}
|
|
330
|
+
|
|
331
|
+
# Map generic arguments to provider-specific parameters
|
|
332
|
+
if generation_args and self._parameter_mapper:
|
|
333
|
+
mapped_args = self._parameter_mapper.map_args(generation_args, mode_str)
|
|
334
|
+
# Provider-specific kwargs take precedence over mapped args
|
|
335
|
+
for k, v in mapped_args.items():
|
|
336
|
+
if k not in call_args:
|
|
337
|
+
call_args[k] = v
|
|
338
|
+
|
|
339
|
+
sig = inspect.signature(fn)
|
|
340
|
+
|
|
341
|
+
for k, v in self._other_kwargs.items():
|
|
342
|
+
if k not in call_args and k in sig.parameters:
|
|
343
|
+
call_args[k] = v
|
|
344
|
+
|
|
345
|
+
# Filter sensitive arguments before logging
|
|
346
|
+
filtered_args = self._filter_sensitive_args(call_args)
|
|
347
|
+
self._emit("before_generate", {"mode": mode_str, "args": filtered_args})
|
|
348
|
+
try:
|
|
349
|
+
raw = fn(**call_args)
|
|
350
|
+
except Exception as e:
|
|
351
|
+
self._emit("error", {"phase": "generate", "error": str(e)})
|
|
352
|
+
raise
|
|
353
|
+
text = self._parse_llm_response(raw)
|
|
354
|
+
self._emit("after_generate", {"mode": mode_str, "response": text})
|
|
355
|
+
return text
|
|
356
|
+
|
|
357
|
+
async def generate_async(
|
|
358
|
+
self,
|
|
359
|
+
prompt: Union[str, List[Dict[str, Any]]],
|
|
360
|
+
mode: Union[str, GenerationMode] = GenerationMode.CHAT_ASYNC,
|
|
361
|
+
generation_args: Optional[GenerationArgs] = None,
|
|
362
|
+
**kwargs: Any,
|
|
363
|
+
) -> str:
|
|
364
|
+
"""
|
|
365
|
+
Asynchronous generation.
|
|
366
|
+
|
|
367
|
+
Uses provider async method if registered, otherwise falls back to thread.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
prompt: string or messages list.
|
|
371
|
+
mode: Generation mode (text_async, chat_async).
|
|
372
|
+
generation_args: Provider-agnostic generation arguments.
|
|
373
|
+
**kwargs: Additional provider-specific parameters.
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
The generated text.
|
|
377
|
+
|
|
378
|
+
Raises:
|
|
379
|
+
Exception: if generation or parsing fails.
|
|
380
|
+
"""
|
|
381
|
+
# Convert enum to string if needed
|
|
382
|
+
mode_str = mode.value if isinstance(mode, GenerationMode) else mode
|
|
383
|
+
|
|
384
|
+
# Convert single string prompt to chat format if in chat mode
|
|
385
|
+
if mode is GenerationMode.CHAT_ASYNC and isinstance(prompt, str):
|
|
386
|
+
prompt = [{"role": "user", "content": prompt}]
|
|
387
|
+
|
|
388
|
+
if mode_str in self._method_configs:
|
|
389
|
+
cfg = self.get_method_config(mode_str)
|
|
390
|
+
fn = cfg.resolve(self._client)
|
|
391
|
+
|
|
392
|
+
call_args = {cfg.prompt_arg: prompt, **kwargs}
|
|
393
|
+
|
|
394
|
+
# Map generic arguments to provider-specific parameters
|
|
395
|
+
if generation_args and self._parameter_mapper:
|
|
396
|
+
mapped_args = self._parameter_mapper.map_args(generation_args, mode_str)
|
|
397
|
+
# Provider-specific kwargs take precedence over mapped args
|
|
398
|
+
for k, v in mapped_args.items():
|
|
399
|
+
if k not in call_args:
|
|
400
|
+
call_args[k] = v
|
|
401
|
+
|
|
402
|
+
sig = inspect.signature(fn)
|
|
403
|
+
|
|
404
|
+
for k, v in self._other_kwargs.items():
|
|
405
|
+
if k not in call_args and k in sig.parameters:
|
|
406
|
+
call_args[k] = v
|
|
407
|
+
|
|
408
|
+
# Filter sensitive arguments before logging
|
|
409
|
+
filtered_args = self._filter_sensitive_args(call_args)
|
|
410
|
+
self._emit(
|
|
411
|
+
"before_generate_async", {"mode": mode_str, "args": filtered_args}
|
|
412
|
+
)
|
|
413
|
+
try:
|
|
414
|
+
raw = await fn(**call_args)
|
|
415
|
+
except Exception as e:
|
|
416
|
+
self._emit("error", {"phase": "generate_async", "error": str(e)})
|
|
417
|
+
raise
|
|
418
|
+
text = self._parse_llm_response(raw)
|
|
419
|
+
self._emit("after_generate_async", {"mode": mode_str, "response": text})
|
|
420
|
+
return text
|
|
421
|
+
|
|
422
|
+
kwargs["mode"] = mode_str.replace("_async", "")
|
|
423
|
+
kwargs["generation_args"] = generation_args
|
|
424
|
+
|
|
425
|
+
# fallback to sync generate in thread
|
|
426
|
+
return await asyncio.to_thread(self.generate, prompt, **kwargs)
|