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
ibm_watsonx_gov/providers/llmevalkit/function_calling/metrics/trajectory/trajectory_metrics.json
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "trajectory_objective_satisfaction",
|
|
4
|
+
"task_description": "As an expert evaluator specializing in user satisfaction assessment, your task is to comprehensively evaluate a complete agent trajectory from initial user request to final response. Your evaluation must focus on USER SATISFACTION - how well the agent fulfilled the user's underlying needs, expectations, and objectives.\n\n## Core Evaluation Philosophy:\nUser satisfaction goes beyond technical correctness. A trajectory can have perfect tool calls but still leave the user unsatisfied if it misses their intent, provides incomplete information, or delivers a poor user experience. Conversely, a trajectory with minor technical imperfections might still achieve high user satisfaction if it addresses the core need effectively.\n\n## Evaluation Dimensions:\n\n### 1. OBJECTIVE UNDERSTANDING (Weight: 25%)\n- Did the agent correctly interpret the user's explicit request?\n- Did the agent identify and address implicit needs or context?\n- Was the scope of the request properly understood (narrow vs. broad)?\n- Did the agent recognize the urgency or priority level?\n\n### 2. STRATEGY & APPROACH (Weight: 20%)\n- Was the chosen approach logical and efficient for the user's goal?\n- Did the agent select the most appropriate tools and sequence?\n- Was the strategy adapted based on intermediate results?\n- Did the agent avoid unnecessary complexity or redundancy?\n\n### 3. INFORMATION COMPLETENESS (Weight: 20%)\n- Did the agent gather all necessary information to satisfy the user's need?\n- Were follow-up questions asked when requirements were ambiguous?\n- Was the information comprehensive enough for the user to take action?\n- Did the agent identify and fill information gaps proactively?\n\n### 4. EXECUTION QUALITY (Weight: 15%)\n- Were tool calls executed correctly with appropriate parameters?\n- Did the agent handle errors, exceptions, or unexpected responses gracefully?\n- Was the execution efficient without unnecessary steps?\n- Did the agent validate results and ensure data accuracy?\n\n### 5. USER EXPERIENCE (Weight: 15%)\n- Was the interaction smooth and intuitive from the user's perspective?\n- Did the agent communicate progress and intermediate findings clearly?\n- Was the response time reasonable for the complexity of the request?\n- Did the agent maintain appropriate context throughout the interaction?\n\n### 6. FINAL DELIVERABLE (Weight: 5%)\n- Was the final answer directly actionable for the user?\n- Did the response format match user expectations and needs?\n- Was the information presented clearly and organized logically?\n- Did the agent provide appropriate next steps or recommendations?\n\n## Scoring Rubric:\n\n**Score 5 (Exceptional User Satisfaction):**\n- User's objective completely fulfilled with excellence\n- Proactive identification and addressing of implicit needs\n- Optimal strategy with flawless execution\n- Superior user experience with clear communication\n- Final deliverable exceeds expectations\n\n**Score 4 (High User Satisfaction):**\n- User's objective well satisfied with minor gaps\n- Good understanding of needs with mostly appropriate approach\n- Solid execution with minimal inefficiencies\n- Good user experience with clear communication\n- Final deliverable meets expectations well\n\n**Score 3 (Moderate User Satisfaction):**\n- User's basic objective met but with notable limitations\n- Adequate understanding but missed some nuances\n- Reasonable approach but with some inefficiencies or gaps\n- Acceptable user experience but could be clearer\n- Final deliverable is functional but incomplete\n\n**Score 2 (Low User Satisfaction):**\n- User's objective partially met with significant gaps\n- Limited understanding of user needs or context\n- Poor strategy or execution with multiple issues\n- Confusing or frustrating user experience\n- Final deliverable requires substantial additional work\n\n**Score 1 (Very Low User Satisfaction):**\n- User's objective largely unmet or misunderstood\n- Fundamental misinterpretation of user needs\n- Inappropriate strategy or failed execution\n- Poor user experience with unclear communication\n- Final deliverable is unusable or incorrect\n\n## Special Considerations:\n\n**Context Sensitivity:** Consider the user's domain expertise, urgency, and specific use case when evaluating satisfaction.\n\n**Error Recovery:** Evaluate how well the agent recovered from errors or adapted when initial approaches failed.\n\n**Efficiency vs. Thoroughness:** Balance the user's need for quick results against the need for comprehensive information.\n\n**Communication Style:** Assess whether the agent's communication style matched the user's apparent preferences and expertise level.\n\nYour evaluation should prioritize the user's perspective: Would a real user be satisfied with this interaction? Would they achieve their goal and have a positive experience?",
|
|
5
|
+
"jsonschema": {
|
|
6
|
+
"title": "trajectory_objective_satisfaction",
|
|
7
|
+
"description": "Comprehensive assessment of user satisfaction with the agent's trajectory performance.",
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"objective_understanding_score": {
|
|
11
|
+
"type": "integer",
|
|
12
|
+
"minimum": 1,
|
|
13
|
+
"maximum": 5,
|
|
14
|
+
"description": "Score for how well the agent understood the user's explicit and implicit objectives (1-5)."
|
|
15
|
+
},
|
|
16
|
+
"strategy_approach_score": {
|
|
17
|
+
"type": "integer",
|
|
18
|
+
"minimum": 1,
|
|
19
|
+
"maximum": 5,
|
|
20
|
+
"description": "Score for the appropriateness and efficiency of the agent's strategy and approach (1-5)."
|
|
21
|
+
},
|
|
22
|
+
"information_completeness_score": {
|
|
23
|
+
"type": "integer",
|
|
24
|
+
"minimum": 1,
|
|
25
|
+
"maximum": 5,
|
|
26
|
+
"description": "Score for how completely the agent gathered and provided necessary information (1-5)."
|
|
27
|
+
},
|
|
28
|
+
"execution_quality_score": {
|
|
29
|
+
"type": "integer",
|
|
30
|
+
"minimum": 1,
|
|
31
|
+
"maximum": 5,
|
|
32
|
+
"description": "Score for the technical quality and correctness of tool usage and execution (1-5)."
|
|
33
|
+
},
|
|
34
|
+
"user_experience_score": {
|
|
35
|
+
"type": "integer",
|
|
36
|
+
"minimum": 1,
|
|
37
|
+
"maximum": 5,
|
|
38
|
+
"description": "Score for the overall user experience, communication clarity, and interaction flow (1-5)."
|
|
39
|
+
},
|
|
40
|
+
"final_deliverable_score": {
|
|
41
|
+
"type": "integer",
|
|
42
|
+
"minimum": 1,
|
|
43
|
+
"maximum": 5,
|
|
44
|
+
"description": "Score for the quality, usefulness, and completeness of the final response (1-5)."
|
|
45
|
+
},
|
|
46
|
+
"evidence": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "Detailed evidence from the trajectory supporting your evaluation. Cite specific user messages, tool calls, tool outputs, and agent responses. Organize by evaluation dimension."
|
|
49
|
+
},
|
|
50
|
+
"explanation": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Comprehensive explanation of your scoring across all dimensions. Explain how each dimension contributed to user satisfaction and identify key strengths and weaknesses."
|
|
53
|
+
},
|
|
54
|
+
"user_satisfaction_analysis": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Focused analysis on user satisfaction: Would the user be satisfied with this interaction? What would their experience be like? What would they think about the agent's performance?"
|
|
57
|
+
},
|
|
58
|
+
"output": {
|
|
59
|
+
"type": "integer",
|
|
60
|
+
"minimum": 1,
|
|
61
|
+
"maximum": 5,
|
|
62
|
+
"description": "Overall user satisfaction score (1-5) calculated as weighted average: Objective Understanding (25%) + Strategy & Approach (20%) + Information Completeness (20%) + Execution Quality (15%) + User Experience (15%) + Final Deliverable (5%)."
|
|
63
|
+
},
|
|
64
|
+
"confidence": {
|
|
65
|
+
"type": "number",
|
|
66
|
+
"minimum": 0,
|
|
67
|
+
"maximum": 1,
|
|
68
|
+
"description": "Your confidence in this evaluation, from 0.0 to 1.0. Consider factors like trajectory clarity, completeness of information, and evaluation complexity."
|
|
69
|
+
},
|
|
70
|
+
"correction": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "If user satisfaction could be improved, provide specific, actionable recommendations organized by dimension. Focus on changes that would most impact user satisfaction. If no improvements needed, return empty string."
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"required": [
|
|
76
|
+
"objective_understanding_score",
|
|
77
|
+
"strategy_approach_score",
|
|
78
|
+
"information_completeness_score",
|
|
79
|
+
"execution_quality_score",
|
|
80
|
+
"user_experience_score",
|
|
81
|
+
"final_deliverable_score",
|
|
82
|
+
"evidence",
|
|
83
|
+
"explanation",
|
|
84
|
+
"user_satisfaction_analysis",
|
|
85
|
+
"output",
|
|
86
|
+
"confidence",
|
|
87
|
+
"correction"
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
"examples": [
|
|
91
|
+
{
|
|
92
|
+
"trajectory": "User: I need to book a flight from NYC to London for next Friday and find a good hotel near the airport.\n\nAgent: I'll help you book a flight and find a hotel. Let me start by searching for flights.\n\nTool Call: search_flights(origin=\"NYC\", destination=\"London\", date=\"2024-01-19\")\nTool Output: {\"flights\": [{\"airline\": \"BA\", \"price\": \"$650\", \"departure\": \"10:00 AM\", \"arrival\": \"10:00 PM\", \"flight_id\": \"BA123\"}]}\n\nAgent: I found a British Airways flight for $650. Let me book this for you and then find hotels.\n\nTool Call: book_flight(flight_id=\"BA123\", passenger_name=\"John Smith\")\nTool Output: {\"booking_confirmed\": true, \"confirmation_code\": \"ABC123\"}\n\nTool Call: search_hotels(location=\"London Heathrow Airport\", checkin=\"2024-01-19\", checkout=\"2024-01-21\")\nTool Output: {\"hotels\": [{\"name\": \"Hilton Heathrow\", \"price\": \"$180/night\", \"rating\": 4.2, \"distance\": \"0.5 miles from airport\"}]}\n\nAgent: Perfect! I've booked your flight (confirmation ABC123) and found the Hilton Heathrow for $180/night, just 0.5 miles from the airport. Your flight departs NYC at 10 AM and arrives in London at 10 PM. Would you like me to book the hotel as well?",
|
|
93
|
+
"expected_output": {
|
|
94
|
+
"objective_understanding_score": 5,
|
|
95
|
+
"strategy_approach_score": 5,
|
|
96
|
+
"information_completeness_score": 4,
|
|
97
|
+
"execution_quality_score": 5,
|
|
98
|
+
"user_experience_score": 5,
|
|
99
|
+
"final_deliverable_score": 4,
|
|
100
|
+
"evidence": "OBJECTIVE UNDERSTANDING: Agent correctly identified both flight booking and hotel search requirements. Properly interpreted 'next Friday' as a specific date and 'near the airport' as location preference.\n\nSTRATEGY & APPROACH: Logical sequence - search flights first, book the selected flight, then search for hotels. Efficient approach without unnecessary steps.\n\nINFORMATION COMPLETENESS: Gathered flight details, booking confirmation, and hotel options. Minor gap: didn't ask about passenger preferences (meal, seat) or hotel booking confirmation.\n\nEXECUTION QUALITY: All tool calls executed correctly with appropriate parameters. Successful flight booking with confirmation code.\n\nUSER EXPERIENCE: Clear communication throughout, provided confirmation details, proactively offered next step (hotel booking).\n\nFINAL DELIVERABLE: Provided actionable information with confirmation code and hotel option, but left hotel booking incomplete.",
|
|
101
|
+
"explanation": "This trajectory demonstrates high user satisfaction across most dimensions. The agent understood both explicit requests (flight + hotel), used an efficient strategy, and executed tools correctly. The user experience was smooth with clear communication and proactive next steps. Minor deduction for not completing the hotel booking or asking about preferences, but overall the user would be very satisfied with getting their flight booked and having a good hotel option presented.",
|
|
102
|
+
"user_satisfaction_analysis": "The user would be highly satisfied with this interaction. They got their primary need (flight booking) completed successfully with a confirmation code, and received a relevant hotel recommendation. The agent was efficient, clear, and proactive. The only minor frustration might be needing a follow-up to complete the hotel booking, but the overall experience would be very positive.",
|
|
103
|
+
"output": 5,
|
|
104
|
+
"confidence": 0.9,
|
|
105
|
+
"correction": "To achieve perfect user satisfaction: 1) Ask about passenger preferences (meal, seat selection) during booking, 2) Proactively book the hotel or clearly ask for confirmation to proceed, 3) Provide more hotel options for comparison."
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"trajectory": "User: What's the weather like in Paris today and should I bring an umbrella?\n\nAgent: I'll check the weather in Paris for you.\n\nTool Call: get_weather(location=\"Paris\", date=\"today\")\nTool Output: {\"temperature\": \"18°C\", \"condition\": \"partly cloudy\", \"humidity\": \"65%\", \"wind\": \"10 km/h\"}\n\nAgent: The weather in Paris today is 18°C and partly cloudy with 65% humidity and 10 km/h wind.",
|
|
110
|
+
"expected_output": {
|
|
111
|
+
"objective_understanding_score": 2,
|
|
112
|
+
"strategy_approach_score": 3,
|
|
113
|
+
"information_completeness_score": 2,
|
|
114
|
+
"execution_quality_score": 4,
|
|
115
|
+
"user_experience_score": 2,
|
|
116
|
+
"final_deliverable_score": 2,
|
|
117
|
+
"evidence": "OBJECTIVE UNDERSTANDING: Agent only addressed the weather query but completely ignored the umbrella question, which was the user's primary practical concern.\n\nSTRATEGY & APPROACH: Basic approach of getting weather data was correct, but no strategy for addressing the umbrella decision.\n\nINFORMATION COMPLETENESS: Missing critical information: precipitation probability, rain forecast, and umbrella recommendation. The weather data alone doesn't answer the user's question.\n\nEXECUTION QUALITY: Tool call was executed correctly with proper parameters and returned valid data.\n\nUSER EXPERIENCE: Poor - user asked a specific practical question about umbrella but got only raw weather data without actionable advice.\n\nFINAL DELIVERABLE: Incomplete response that doesn't help the user make the umbrella decision they asked about.",
|
|
118
|
+
"explanation": "This trajectory shows poor user satisfaction despite technically correct tool usage. The agent failed to understand that the user's real need was a practical recommendation about bringing an umbrella, not just weather data. The response leaves the user to interpret the data themselves, which doesn't fulfill their objective of getting actionable advice.",
|
|
119
|
+
"user_satisfaction_analysis": "The user would be frustrated with this interaction. They asked a simple, practical question about whether to bring an umbrella, but received only raw weather data without the recommendation they needed. They would likely need to ask a follow-up question or make the decision themselves, indicating the agent failed to provide value.",
|
|
120
|
+
"output": 2,
|
|
121
|
+
"confidence": 0.95,
|
|
122
|
+
"correction": "To improve user satisfaction: 1) Directly answer the umbrella question based on weather conditions, 2) Get precipitation probability/rain forecast data, 3) Provide clear recommendation: 'Based on partly cloudy conditions with no rain expected, you likely don't need an umbrella, but consider bringing one if you'll be out all day as conditions can change.'"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"trajectory": "User: I'm planning a dinner party for 8 people this Saturday. Can you help me find a good restaurant that takes reservations and suggest a wine pairing?\n\nAgent: I'd be happy to help you plan your dinner party! Let me search for restaurants that can accommodate your group.\n\nTool Call: search_restaurants(location=\"user_location\", party_size=8, date=\"2024-01-20\", accepts_reservations=true)\nTool Output: {\"restaurants\": [{\"name\": \"Bistro Laurent\", \"cuisine\": \"French\", \"rating\": 4.6, \"price_range\": \"$$$\", \"availability\": \"7:00 PM, 8:30 PM\"}, {\"name\": \"Mama Rosa's\", \"cuisine\": \"Italian\", \"rating\": 4.3, \"price_range\": \"$$\", \"availability\": \"6:00 PM, 9:00 PM\"}]}\n\nAgent: Great! I found two excellent options for your party of 8:\n\n1. **Bistro Laurent** (French, 4.6★, $$$) - Available at 7:00 PM or 8:30 PM\n2. **Mama Rosa's** (Italian, 4.3★, $$) - Available at 6:00 PM or 9:00 PM\n\nFor wine pairings, let me get some recommendations based on the cuisine:\n\nTool Call: get_wine_recommendations(cuisine=\"French\", occasion=\"dinner_party\", group_size=8)\nTool Output: {\"wines\": [{\"name\": \"Châteauneuf-du-Pape Rouge\", \"type\": \"red\", \"price\": \"$45\", \"description\": \"Full-bodied red perfect for French cuisine\"}, {\"name\": \"Sancerre\", \"type\": \"white\", \"price\": \"$35\", \"description\": \"Crisp white that pairs well with appetizers\"}]}\n\nTool Call: get_wine_recommendations(cuisine=\"Italian\", occasion=\"dinner_party\", group_size=8)\nTool Output: {\"wines\": [{\"name\": \"Chianti Classico\", \"type\": \"red\", \"price\": \"$28\", \"description\": \"Classic Italian red, great with pasta and meat dishes\"}, {\"name\": \"Pinot Grigio\", \"type\": \"white\", \"price\": \"$22\", \"description\": \"Light, refreshing white perfect for Italian fare\"}]}\n\nAgent: Here are wine pairing suggestions for each restaurant:\n\n**For Bistro Laurent (French):**\n- Châteauneuf-du-Pape Rouge ($45) - Full-bodied red perfect for French cuisine\n- Sancerre ($35) - Crisp white for appetizers\n\n**For Mama Rosa's (Italian):**\n- Chianti Classico ($28) - Classic Italian red for pasta/meat dishes \n- Pinot Grigio ($22) - Light, refreshing white\n\nBoth restaurants look excellent for your dinner party. Bistro Laurent offers a more upscale French experience, while Mama Rosa's provides great Italian food at a more moderate price point. Would you like me to help you make a reservation at either restaurant?",
|
|
127
|
+
"expected_output": {
|
|
128
|
+
"objective_understanding_score": 5,
|
|
129
|
+
"strategy_approach_score": 5,
|
|
130
|
+
"information_completeness_score": 5,
|
|
131
|
+
"execution_quality_score": 5,
|
|
132
|
+
"user_experience_score": 5,
|
|
133
|
+
"final_deliverable_score": 5,
|
|
134
|
+
"evidence": "OBJECTIVE UNDERSTANDING: Perfect comprehension of both explicit needs (restaurant reservation for 8 people) and implicit needs (good options, wine pairing advice for dinner party context).\n\nSTRATEGY & APPROACH: Excellent strategy - search restaurants first with specific criteria, then get targeted wine recommendations for each cuisine type. Logical, efficient sequence.\n\nINFORMATION COMPLETENESS: Comprehensive information provided - restaurant options with ratings, prices, availability, plus specific wine pairings with prices and descriptions for each cuisine.\n\nEXECUTION QUALITY: All tool calls executed perfectly with appropriate parameters. Smart approach to get wine recommendations for both cuisine types.\n\nUSER EXPERIENCE: Outstanding communication - clear formatting, helpful comparisons, proactive offer to make reservations. Information presented in actionable format.\n\nFINAL DELIVERABLE: Complete solution addressing all user needs with clear options and next steps.",
|
|
135
|
+
"explanation": "This trajectory exemplifies exceptional user satisfaction. The agent demonstrated perfect understanding of the dinner party context, used an optimal strategy to gather comprehensive information, and presented everything in a clear, actionable format. The user received exactly what they needed to make an informed decision about both restaurant and wine selection.",
|
|
136
|
+
"user_satisfaction_analysis": "The user would be extremely satisfied with this interaction. They received exactly what they asked for - good restaurant options with availability and wine pairing suggestions - plus additional valuable context like ratings and prices. The agent was proactive in offering to help with the next step (making reservations). This interaction would likely exceed the user's expectations.",
|
|
137
|
+
"output": 5,
|
|
138
|
+
"confidence": 0.95,
|
|
139
|
+
"correction": ""
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"trajectory": "User: I need to transfer $500 to my friend John's account. His account number is 123456789.\n\nAgent: I can help you transfer money. Let me process this transfer.\n\nTool Call: transfer_money(amount=500, recipient_account=\"123456789\", sender_account=\"user_account\")\nTool Output: {\"error\": \"Insufficient funds. Current balance: $200\"}\n\nAgent: I'm sorry, but the transfer couldn't be completed because you have insufficient funds. Your current balance is $200, but you're trying to transfer $500.\n\nTool Call: get_account_options(account=\"user_account\")\nTool Output: {\"options\": [\"overdraft_protection\", \"line_of_credit\", \"transfer_from_savings\"]}\n\nAgent: I see you have some options available:\n1. Overdraft protection\n2. Line of credit \n3. Transfer from savings account\n\nWould you like me to help you explore any of these options to complete the transfer?",
|
|
144
|
+
"expected_output": {
|
|
145
|
+
"objective_understanding_score": 4,
|
|
146
|
+
"strategy_approach_score": 4,
|
|
147
|
+
"information_completeness_score": 3,
|
|
148
|
+
"execution_quality_score": 4,
|
|
149
|
+
"user_experience_score": 4,
|
|
150
|
+
"final_deliverable_score": 3,
|
|
151
|
+
"evidence": "OBJECTIVE UNDERSTANDING: Agent correctly understood the transfer request and recipient details. Good recognition that user wants to complete the transfer despite initial failure.\n\nSTRATEGY & APPROACH: Good initial approach, and smart recovery by checking available options after the failure. Proactive problem-solving approach.\n\nINFORMATION COMPLETENESS: Provided current balance and available options, but missing details about costs/terms of each option, and didn't check savings balance for transfer option.\n\nEXECUTION QUALITY: Tool calls executed correctly. Good error handling and appropriate follow-up query for solutions.\n\nUSER EXPERIENCE: Clear communication about the problem and potential solutions. Maintained helpful tone despite the failure.\n\nFINAL DELIVERABLE: Identified the problem and provided options, but left user to decide without sufficient information to make an informed choice.",
|
|
152
|
+
"explanation": "This trajectory shows good user satisfaction with effective problem-solving. The agent handled the error gracefully and proactively offered solutions. However, user satisfaction is limited by incomplete information about the options presented - the user needs more details to make an informed decision about how to proceed.",
|
|
153
|
+
"user_satisfaction_analysis": "The user would have moderate satisfaction. While they'd appreciate the agent's proactive approach to solving the insufficient funds problem, they'd likely be frustrated by not having enough information about the options (costs, terms, savings balance) to make a decision. They'd need to ask follow-up questions to proceed.",
|
|
154
|
+
"output": 4,
|
|
155
|
+
"confidence": 0.85,
|
|
156
|
+
"correction": "To improve user satisfaction: 1) Provide details about each option (fees, interest rates, terms), 2) Check savings account balance if transfer from savings is an option, 3) Make a specific recommendation based on the user's situation, 4) Offer to proceed with the recommended option if user agrees."
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
Dict,
|
|
4
|
+
List,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from llmevalkit.function_calling.pipeline.types import (
|
|
8
|
+
ToolCall,
|
|
9
|
+
ToolSpec,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# ────────────────────────────────────────────────────────────────────────────────
|
|
14
|
+
# Adapter definitions
|
|
15
|
+
# ────────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BaseAdapter:
|
|
19
|
+
"""Abstract adapter to unify different API spec and call representations."""
|
|
20
|
+
|
|
21
|
+
def get_tools_inventory(self) -> List[Dict[str, Any]]:
|
|
22
|
+
raise NotImplementedError
|
|
23
|
+
|
|
24
|
+
def get_tools_inventory_summary(self) -> List[Dict[str, Any]]:
|
|
25
|
+
raise NotImplementedError
|
|
26
|
+
|
|
27
|
+
def get_tool_spec(self, tool_name: str) -> Dict[str, Any]:
|
|
28
|
+
raise NotImplementedError
|
|
29
|
+
|
|
30
|
+
def get_call_dict(self) -> Dict[str, Any]:
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
def get_function_name(self) -> str:
|
|
34
|
+
raise NotImplementedError
|
|
35
|
+
|
|
36
|
+
def get_parameters(self) -> Dict[str, Any]:
|
|
37
|
+
raise NotImplementedError
|
|
38
|
+
|
|
39
|
+
def get_param_spec_snippet(self, param_name: str) -> Dict[str, Any]:
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class OpenAIAdapter(BaseAdapter):
|
|
44
|
+
"""Adapter for ToolSpec + ToolCall inputs."""
|
|
45
|
+
|
|
46
|
+
def __init__(self, specs: List[ToolSpec], call: ToolCall):
|
|
47
|
+
self.specs = specs
|
|
48
|
+
self.call = call
|
|
49
|
+
|
|
50
|
+
def get_tools_inventory(self) -> List[Dict[str, Any]]:
|
|
51
|
+
return [spec.model_dump() for spec in self.specs]
|
|
52
|
+
|
|
53
|
+
def get_tools_inventory_summary(self) -> List[Dict[str, Any]]:
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
"tool_name": spec.function.name,
|
|
57
|
+
"tool_description": spec.function.description,
|
|
58
|
+
"tool_parameters": {
|
|
59
|
+
prop_name: prop_d["type"]
|
|
60
|
+
for prop_name, prop_d in spec.function.parameters.get(
|
|
61
|
+
"properties", {}
|
|
62
|
+
).items()
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
for spec in self.specs
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
def get_tool_spec(self, tool_name: str) -> Dict[str, Any]:
|
|
69
|
+
tool = next((t for t in self.specs if t.function.name == tool_name), None)
|
|
70
|
+
return tool.function.model_dump() if tool else {}
|
|
71
|
+
|
|
72
|
+
def get_call_dict(self) -> Dict[str, Any]:
|
|
73
|
+
call_dict = {
|
|
74
|
+
"id": self.call.id,
|
|
75
|
+
"type": "function",
|
|
76
|
+
"function": {
|
|
77
|
+
"name": self.call.function.name,
|
|
78
|
+
"arguments": self.call.function.arguments,
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
return call_dict
|
|
82
|
+
|
|
83
|
+
def get_function_name(self) -> str:
|
|
84
|
+
return self.call.function.name
|
|
85
|
+
|
|
86
|
+
def get_parameters(self) -> Dict[str, Any]:
|
|
87
|
+
return self.call.function.parsed_arguments
|
|
88
|
+
|
|
89
|
+
def get_param_spec_snippet(self, param_name: str) -> Dict[str, Any]:
|
|
90
|
+
spec = next(
|
|
91
|
+
(s for s in self.specs if s.function.name == self.get_function_name()), None
|
|
92
|
+
)
|
|
93
|
+
if not spec:
|
|
94
|
+
return {"type": "object", "properties": {}, "required": []}
|
|
95
|
+
props = spec.function.parameters.get("properties", spec.function.parameters)
|
|
96
|
+
if param_name not in props:
|
|
97
|
+
return {"type": "object", "properties": {}, "required": []}
|
|
98
|
+
return {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"properties": {param_name: props[param_name]},
|
|
101
|
+
"required": [param_name],
|
|
102
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any, Dict, List, Optional, Union
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from llmevalkit.llm import LLMClient
|
|
6
|
+
from llmevalkit.function_calling.pipeline.static_checker import evaluate_static
|
|
7
|
+
from llmevalkit.function_calling.pipeline.semantic_checker import SemanticChecker
|
|
8
|
+
from llmevalkit.function_calling.pipeline.types import (
|
|
9
|
+
FunctionCallMetric,
|
|
10
|
+
FunctionCallInput,
|
|
11
|
+
PipelineResult,
|
|
12
|
+
StaticResult,
|
|
13
|
+
SemanticResult,
|
|
14
|
+
ToolSpec,
|
|
15
|
+
ToolCall,
|
|
16
|
+
StaticMetricResult,
|
|
17
|
+
SemanticCategoryResult,
|
|
18
|
+
TrajectoryPipelineInput,
|
|
19
|
+
TrajectoryPipelineResult,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Default metric JSON paths
|
|
23
|
+
_METRICS_DIR = Path(__file__).parent.parent / "metrics"
|
|
24
|
+
_DEFAULT_GENERAL = _METRICS_DIR / "function_call" / "general_metrics.json"
|
|
25
|
+
_DEFAULT_GENERAL_RUNTIME = (
|
|
26
|
+
_METRICS_DIR / "function_call" / "general_metrics_runtime.json"
|
|
27
|
+
)
|
|
28
|
+
_DEFAULT_FUNCSEL = (
|
|
29
|
+
_METRICS_DIR / "function_selection" / "function_selection_metrics.json"
|
|
30
|
+
)
|
|
31
|
+
_DEFAULT_FUNCSEL_RUNTIME = (
|
|
32
|
+
_METRICS_DIR / "function_selection" / "function_selection_metrics_runtime.json"
|
|
33
|
+
)
|
|
34
|
+
_DEFAULT_PARAM = _METRICS_DIR / "parameter" / "parameter_metrics.json"
|
|
35
|
+
_DEFAULT_PARAM_RUNTIME = _METRICS_DIR / "parameter" / "parameter_metrics_runtime.json"
|
|
36
|
+
_DEFAULT_TRAJECTORY = _METRICS_DIR / "trajectory" / "trajectory_metrics.json"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ReflectionPipeline:
|
|
40
|
+
"""
|
|
41
|
+
High-level orchestration for function-call reflection.
|
|
42
|
+
|
|
43
|
+
Modes:
|
|
44
|
+
• static_only: schema checks
|
|
45
|
+
• semantic_only: LLM metrics + transforms
|
|
46
|
+
• run: full static -> semantic -> assemble -> PipelineResult
|
|
47
|
+
|
|
48
|
+
Supports sync & async, custom JSON overrides, and any registered LLM.
|
|
49
|
+
runtime_pipeline: if set to true, use faster prompts (no actionable recommendations, shorter explanations)
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
metrics_client: LLMClient,
|
|
55
|
+
codegen_client: Optional[LLMClient] = None,
|
|
56
|
+
general_metrics: Optional[
|
|
57
|
+
Union[Path, List[FunctionCallMetric], List[str]]
|
|
58
|
+
] = _DEFAULT_GENERAL_RUNTIME,
|
|
59
|
+
function_metrics: Optional[
|
|
60
|
+
Union[Path, List[FunctionCallMetric], List[str]]
|
|
61
|
+
] = _DEFAULT_FUNCSEL_RUNTIME,
|
|
62
|
+
parameter_metrics: Optional[
|
|
63
|
+
Union[Path, List[FunctionCallMetric], List[str]]
|
|
64
|
+
] = _DEFAULT_PARAM_RUNTIME,
|
|
65
|
+
trajectory_metrics: Optional[
|
|
66
|
+
Union[Path, List[FunctionCallMetric], List[str]]
|
|
67
|
+
] = _DEFAULT_TRAJECTORY,
|
|
68
|
+
transform_enabled: Optional[bool] = False,
|
|
69
|
+
runtime_pipeline: Optional[bool] = True,
|
|
70
|
+
use_examples: Optional[bool] = True,
|
|
71
|
+
):
|
|
72
|
+
|
|
73
|
+
self.metrics_client = metrics_client
|
|
74
|
+
if codegen_client is None:
|
|
75
|
+
self.codegen_client = metrics_client
|
|
76
|
+
else:
|
|
77
|
+
self.codegen_client = codegen_client
|
|
78
|
+
|
|
79
|
+
self.general_metrics = general_metrics
|
|
80
|
+
self.function_metrics = function_metrics
|
|
81
|
+
self.parameter_metrics = parameter_metrics
|
|
82
|
+
self.trajectory_metrics = trajectory_metrics
|
|
83
|
+
|
|
84
|
+
metrics_definitions = []
|
|
85
|
+
|
|
86
|
+
for metrics, default_path in [
|
|
87
|
+
(
|
|
88
|
+
self.general_metrics,
|
|
89
|
+
_DEFAULT_GENERAL_RUNTIME if runtime_pipeline else _DEFAULT_GENERAL,
|
|
90
|
+
),
|
|
91
|
+
(
|
|
92
|
+
self.function_metrics,
|
|
93
|
+
_DEFAULT_FUNCSEL_RUNTIME if runtime_pipeline else _DEFAULT_FUNCSEL,
|
|
94
|
+
),
|
|
95
|
+
(
|
|
96
|
+
self.parameter_metrics,
|
|
97
|
+
_DEFAULT_PARAM_RUNTIME if runtime_pipeline else _DEFAULT_PARAM,
|
|
98
|
+
),
|
|
99
|
+
(
|
|
100
|
+
self.trajectory_metrics,
|
|
101
|
+
_DEFAULT_TRAJECTORY,
|
|
102
|
+
),
|
|
103
|
+
]:
|
|
104
|
+
if not metrics:
|
|
105
|
+
metrics_definitions.append(None)
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
# Handle metric names list
|
|
109
|
+
if isinstance(metrics, list) and all(isinstance(x, str) for x in metrics):
|
|
110
|
+
# Load the default JSON file
|
|
111
|
+
if not default_path.is_file():
|
|
112
|
+
raise FileNotFoundError(
|
|
113
|
+
f"Default metrics file not found: {default_path}"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
with default_path.open("r") as f_in:
|
|
117
|
+
all_metrics = json.load(f_in)
|
|
118
|
+
|
|
119
|
+
# Filter metrics by name
|
|
120
|
+
filtered_metrics = [
|
|
121
|
+
metric for metric in all_metrics if metric.get("name") in metrics
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
# Remove examples from prompts if requested
|
|
125
|
+
if not use_examples:
|
|
126
|
+
for metric in filtered_metrics:
|
|
127
|
+
metric.pop("examples", None)
|
|
128
|
+
|
|
129
|
+
if len(filtered_metrics) != len(metrics):
|
|
130
|
+
found_names = {metric.get("name") for metric in filtered_metrics}
|
|
131
|
+
missing = set(metrics) - found_names
|
|
132
|
+
raise ValueError(f"Metrics not found: {missing}")
|
|
133
|
+
|
|
134
|
+
metrics_definitions.append(filtered_metrics)
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
# Handle Path or List[FunctionCallMetric] (existing logic)
|
|
138
|
+
if not isinstance(metrics, (Path, list)):
|
|
139
|
+
raise TypeError(
|
|
140
|
+
"metrics must be Path, List[FunctionCallMetric], List[str], or None"
|
|
141
|
+
)
|
|
142
|
+
if isinstance(metrics, list) and all(
|
|
143
|
+
isinstance(x, FunctionCallMetric) for x in metrics
|
|
144
|
+
):
|
|
145
|
+
metrics_definitions.append([metric.model_dump() for metric in metrics])
|
|
146
|
+
else:
|
|
147
|
+
if not metrics.is_file():
|
|
148
|
+
raise FileNotFoundError(f"Metrics file not found: {metrics}")
|
|
149
|
+
with metrics.open("r", encoding="utf8") as f:
|
|
150
|
+
metrics_definitions.append(json.load(f))
|
|
151
|
+
|
|
152
|
+
gen_defs, fun_defs, par_defs, traj_defs = None, None, None, None
|
|
153
|
+
|
|
154
|
+
if metrics_definitions:
|
|
155
|
+
gen_defs = metrics_definitions[0]
|
|
156
|
+
if len(metrics_definitions) >= 2:
|
|
157
|
+
fun_defs = metrics_definitions[1]
|
|
158
|
+
if len(metrics_definitions) >= 3:
|
|
159
|
+
par_defs = metrics_definitions[2]
|
|
160
|
+
if len(metrics_definitions) >= 4:
|
|
161
|
+
traj_defs = metrics_definitions[3]
|
|
162
|
+
|
|
163
|
+
# 3) Initialize semantic checker
|
|
164
|
+
self.semantic_checker = SemanticChecker(
|
|
165
|
+
general_metrics=gen_defs,
|
|
166
|
+
function_metrics=fun_defs,
|
|
167
|
+
parameter_metrics=par_defs,
|
|
168
|
+
trajectory_metrics=traj_defs,
|
|
169
|
+
metrics_client=self.metrics_client,
|
|
170
|
+
codegen_client=self.codegen_client,
|
|
171
|
+
transform_enabled=transform_enabled,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
@staticmethod
|
|
175
|
+
def static_only(
|
|
176
|
+
inventory: List[ToolSpec],
|
|
177
|
+
call: ToolCall,
|
|
178
|
+
) -> StaticResult:
|
|
179
|
+
"""
|
|
180
|
+
Run schema-based static checks.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
StaticResult with per-check results and final_decision.
|
|
184
|
+
"""
|
|
185
|
+
try:
|
|
186
|
+
return evaluate_static(inventory, call)
|
|
187
|
+
except Exception as e:
|
|
188
|
+
return StaticResult(
|
|
189
|
+
metrics={
|
|
190
|
+
"json_schema_validation": StaticMetricResult(
|
|
191
|
+
description="Invalid JSON schema",
|
|
192
|
+
valid=False,
|
|
193
|
+
explanation=f"error parsing JSON schema: {str(e)}",
|
|
194
|
+
)
|
|
195
|
+
},
|
|
196
|
+
final_decision=False,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def semantic_sync(
|
|
200
|
+
self,
|
|
201
|
+
conversation: Union[str, List[Dict[str, str]]],
|
|
202
|
+
inventory: List[ToolSpec],
|
|
203
|
+
call: ToolCall,
|
|
204
|
+
retries: Optional[int] = 2,
|
|
205
|
+
transform_enabled: Optional[bool] = None,
|
|
206
|
+
) -> SemanticResult:
|
|
207
|
+
"""
|
|
208
|
+
Synchronous LLM-based semantic metrics (+ optional transforms).
|
|
209
|
+
"""
|
|
210
|
+
# delegate to SemanticChecker
|
|
211
|
+
return self.semantic_checker.run_sync(
|
|
212
|
+
inventory,
|
|
213
|
+
call,
|
|
214
|
+
conversation,
|
|
215
|
+
retries=retries,
|
|
216
|
+
transform_enabled=transform_enabled,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
async def semantic_async(
|
|
220
|
+
self,
|
|
221
|
+
conversation: Union[str, List[Dict[str, str]]],
|
|
222
|
+
inventory: List[ToolSpec],
|
|
223
|
+
call: ToolCall,
|
|
224
|
+
retries: Optional[int] = 2,
|
|
225
|
+
max_parallel: Optional[int] = 10,
|
|
226
|
+
transform_enabled: Optional[bool] = None,
|
|
227
|
+
) -> SemanticResult:
|
|
228
|
+
"""
|
|
229
|
+
Async LLM-based semantic metrics (+ optional transforms).
|
|
230
|
+
"""
|
|
231
|
+
return await self.semantic_checker.run_async(
|
|
232
|
+
inventory,
|
|
233
|
+
call,
|
|
234
|
+
conversation,
|
|
235
|
+
retries=retries,
|
|
236
|
+
max_parallel=max_parallel,
|
|
237
|
+
transform_enabled=transform_enabled,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
def run_sync(
|
|
241
|
+
self,
|
|
242
|
+
conversation: Union[str, List[Dict[str, str]]],
|
|
243
|
+
inventory: List[ToolSpec],
|
|
244
|
+
call: ToolCall,
|
|
245
|
+
continue_on_static: Optional[bool] = False,
|
|
246
|
+
retries: Optional[int] = 1,
|
|
247
|
+
transform_enabled: Optional[bool] = None,
|
|
248
|
+
) -> PipelineResult:
|
|
249
|
+
"""
|
|
250
|
+
Full sync pipeline: static -> semantic -> assemble PipelineResult.
|
|
251
|
+
"""
|
|
252
|
+
static_res = self.static_only(inventory, call)
|
|
253
|
+
|
|
254
|
+
if not static_res.final_decision and not continue_on_static:
|
|
255
|
+
inputs = FunctionCallInput(
|
|
256
|
+
conversation_context=conversation,
|
|
257
|
+
tools_inventory=inventory,
|
|
258
|
+
tool_call=call,
|
|
259
|
+
)
|
|
260
|
+
return PipelineResult(
|
|
261
|
+
inputs=inputs,
|
|
262
|
+
static=static_res,
|
|
263
|
+
semantic=SemanticResult(
|
|
264
|
+
general=None,
|
|
265
|
+
function_selection=None,
|
|
266
|
+
parameter=None,
|
|
267
|
+
transform=None,
|
|
268
|
+
),
|
|
269
|
+
overall_valid=False,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
semantic_res = self.semantic_sync(
|
|
273
|
+
conversation, inventory, call, retries, transform_enabled
|
|
274
|
+
)
|
|
275
|
+
return PipelineResult(
|
|
276
|
+
inputs=FunctionCallInput(
|
|
277
|
+
conversation_context=conversation,
|
|
278
|
+
tools_inventory=inventory,
|
|
279
|
+
tool_call=call,
|
|
280
|
+
),
|
|
281
|
+
static=static_res,
|
|
282
|
+
semantic=semantic_res,
|
|
283
|
+
overall_valid=True,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
async def run_async(
|
|
287
|
+
self,
|
|
288
|
+
conversation: Union[str, List[Dict[str, str]]],
|
|
289
|
+
inventory: List[ToolSpec],
|
|
290
|
+
call: ToolCall,
|
|
291
|
+
continue_on_static: Optional[bool] = False,
|
|
292
|
+
retries: Optional[int] = 1,
|
|
293
|
+
max_parallel: Optional[int] = 10,
|
|
294
|
+
transform_enabled: Optional[bool] = None,
|
|
295
|
+
) -> PipelineResult:
|
|
296
|
+
"""
|
|
297
|
+
Full async pipeline: static -> semantic -> assemble PipelineResult.
|
|
298
|
+
"""
|
|
299
|
+
static_res = self.static_only(inventory, call)
|
|
300
|
+
|
|
301
|
+
if not static_res.final_decision and not continue_on_static:
|
|
302
|
+
inputs = FunctionCallInput(
|
|
303
|
+
conversation_context=conversation,
|
|
304
|
+
tools_inventory=inventory,
|
|
305
|
+
tool_call=call,
|
|
306
|
+
)
|
|
307
|
+
return PipelineResult(
|
|
308
|
+
inputs=inputs,
|
|
309
|
+
static=static_res,
|
|
310
|
+
semantic=SemanticResult(
|
|
311
|
+
general=None,
|
|
312
|
+
function_selection=None,
|
|
313
|
+
parameter=None,
|
|
314
|
+
transform=None,
|
|
315
|
+
),
|
|
316
|
+
overall_valid=False,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
semantic_res = await self.semantic_async(
|
|
320
|
+
conversation, inventory, call, retries, max_parallel, transform_enabled
|
|
321
|
+
)
|
|
322
|
+
return PipelineResult(
|
|
323
|
+
inputs=FunctionCallInput(
|
|
324
|
+
conversation_context=conversation,
|
|
325
|
+
tools_inventory=inventory,
|
|
326
|
+
tool_call=call,
|
|
327
|
+
),
|
|
328
|
+
static=static_res,
|
|
329
|
+
semantic=semantic_res,
|
|
330
|
+
overall_valid=True,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
async def run_trajectory_async(
|
|
334
|
+
self,
|
|
335
|
+
trajectory: Union[str, List[Dict[str, str]]],
|
|
336
|
+
tool_inventory: List[Dict[str, Any]],
|
|
337
|
+
retries: Optional[int] = 1,
|
|
338
|
+
max_parallel: Optional[int] = 10,
|
|
339
|
+
) -> TrajectoryPipelineResult:
|
|
340
|
+
"""
|
|
341
|
+
Run trajectory evaluation asynchronously.
|
|
342
|
+
"""
|
|
343
|
+
result = await self.semantic_checker.run_trajectory_async(
|
|
344
|
+
trajectory=trajectory,
|
|
345
|
+
tool_inventory=tool_inventory,
|
|
346
|
+
retries=retries,
|
|
347
|
+
max_parallel=max_parallel,
|
|
348
|
+
)
|
|
349
|
+
return TrajectoryPipelineResult(
|
|
350
|
+
inputs=TrajectoryPipelineInput(
|
|
351
|
+
trajectory=trajectory,
|
|
352
|
+
tool_inventory=tool_inventory,
|
|
353
|
+
),
|
|
354
|
+
result=result,
|
|
355
|
+
)
|