azure-ai-evaluation 1.0.1__py3-none-any.whl → 1.13.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of azure-ai-evaluation might be problematic. Click here for more details.
- azure/ai/evaluation/__init__.py +83 -14
- azure/ai/evaluation/_aoai/__init__.py +10 -0
- azure/ai/evaluation/_aoai/aoai_grader.py +140 -0
- azure/ai/evaluation/_aoai/label_grader.py +68 -0
- azure/ai/evaluation/_aoai/python_grader.py +86 -0
- azure/ai/evaluation/_aoai/score_model_grader.py +94 -0
- azure/ai/evaluation/_aoai/string_check_grader.py +66 -0
- azure/ai/evaluation/_aoai/text_similarity_grader.py +80 -0
- azure/ai/evaluation/_azure/__init__.py +3 -0
- azure/ai/evaluation/_azure/_clients.py +204 -0
- azure/ai/evaluation/_azure/_envs.py +207 -0
- azure/ai/evaluation/_azure/_models.py +227 -0
- azure/ai/evaluation/_azure/_token_manager.py +129 -0
- azure/ai/evaluation/_common/__init__.py +9 -1
- azure/ai/evaluation/_common/constants.py +124 -2
- azure/ai/evaluation/_common/evaluation_onedp_client.py +169 -0
- azure/ai/evaluation/_common/onedp/__init__.py +32 -0
- azure/ai/evaluation/_common/onedp/_client.py +166 -0
- azure/ai/evaluation/_common/onedp/_configuration.py +72 -0
- azure/ai/evaluation/_common/onedp/_model_base.py +1232 -0
- azure/ai/evaluation/_common/onedp/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/_serialization.py +2032 -0
- azure/ai/evaluation/_common/onedp/_types.py +21 -0
- azure/ai/evaluation/_common/onedp/_utils/__init__.py +6 -0
- azure/ai/evaluation/_common/onedp/_utils/model_base.py +1232 -0
- azure/ai/evaluation/_common/onedp/_utils/serialization.py +2032 -0
- azure/ai/evaluation/_common/onedp/_validation.py +66 -0
- azure/ai/evaluation/_common/onedp/_vendor.py +50 -0
- azure/ai/evaluation/_common/onedp/_version.py +9 -0
- azure/ai/evaluation/_common/onedp/aio/__init__.py +29 -0
- azure/ai/evaluation/_common/onedp/aio/_client.py +168 -0
- azure/ai/evaluation/_common/onedp/aio/_configuration.py +72 -0
- azure/ai/evaluation/_common/onedp/aio/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/aio/operations/__init__.py +49 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_operations.py +7143 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/models/__init__.py +358 -0
- azure/ai/evaluation/_common/onedp/models/_enums.py +447 -0
- azure/ai/evaluation/_common/onedp/models/_models.py +5963 -0
- azure/ai/evaluation/_common/onedp/models/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/operations/__init__.py +49 -0
- azure/ai/evaluation/_common/onedp/operations/_operations.py +8951 -0
- azure/ai/evaluation/_common/onedp/operations/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/py.typed +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_operations.py +34 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/__init__.py +22 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_operations.py +29 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/__init__.py +22 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_operations.py +29 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/_operations.py +34 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/rai_service.py +578 -69
- azure/ai/evaluation/_common/raiclient/__init__.py +34 -0
- azure/ai/evaluation/_common/raiclient/_client.py +128 -0
- azure/ai/evaluation/_common/raiclient/_configuration.py +87 -0
- azure/ai/evaluation/_common/raiclient/_model_base.py +1235 -0
- azure/ai/evaluation/_common/raiclient/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/_serialization.py +2050 -0
- azure/ai/evaluation/_common/raiclient/_version.py +9 -0
- azure/ai/evaluation/_common/raiclient/aio/__init__.py +29 -0
- azure/ai/evaluation/_common/raiclient/aio/_client.py +130 -0
- azure/ai/evaluation/_common/raiclient/aio/_configuration.py +87 -0
- azure/ai/evaluation/_common/raiclient/aio/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/_operations.py +981 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/models/__init__.py +60 -0
- azure/ai/evaluation/_common/raiclient/models/_enums.py +18 -0
- azure/ai/evaluation/_common/raiclient/models/_models.py +651 -0
- azure/ai/evaluation/_common/raiclient/models/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/raiclient/operations/_operations.py +1238 -0
- azure/ai/evaluation/_common/raiclient/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/py.typed +1 -0
- azure/ai/evaluation/_common/utils.py +505 -27
- azure/ai/evaluation/_constants.py +148 -0
- azure/ai/evaluation/_converters/__init__.py +3 -0
- azure/ai/evaluation/_converters/_ai_services.py +899 -0
- azure/ai/evaluation/_converters/_models.py +467 -0
- azure/ai/evaluation/_converters/_sk_services.py +495 -0
- azure/ai/evaluation/_eval_mapping.py +83 -0
- azure/ai/evaluation/_evaluate/_batch_run/__init__.py +10 -2
- azure/ai/evaluation/_evaluate/_batch_run/_run_submitter_client.py +176 -0
- azure/ai/evaluation/_evaluate/_batch_run/batch_clients.py +82 -0
- azure/ai/evaluation/_evaluate/_batch_run/code_client.py +18 -12
- azure/ai/evaluation/_evaluate/_batch_run/eval_run_context.py +19 -6
- azure/ai/evaluation/_evaluate/_batch_run/proxy_client.py +47 -22
- azure/ai/evaluation/_evaluate/_batch_run/target_run_context.py +18 -2
- azure/ai/evaluation/_evaluate/_eval_run.py +32 -46
- azure/ai/evaluation/_evaluate/_evaluate.py +1809 -142
- azure/ai/evaluation/_evaluate/_evaluate_aoai.py +992 -0
- azure/ai/evaluation/_evaluate/_telemetry/__init__.py +5 -90
- azure/ai/evaluation/_evaluate/_utils.py +237 -42
- azure/ai/evaluation/_evaluator_definition.py +76 -0
- azure/ai/evaluation/_evaluators/_bleu/_bleu.py +80 -28
- azure/ai/evaluation/_evaluators/_code_vulnerability/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_code_vulnerability/_code_vulnerability.py +119 -0
- azure/ai/evaluation/_evaluators/_coherence/_coherence.py +40 -4
- azure/ai/evaluation/_evaluators/_common/__init__.py +2 -0
- azure/ai/evaluation/_evaluators/_common/_base_eval.py +427 -29
- azure/ai/evaluation/_evaluators/_common/_base_multi_eval.py +63 -0
- azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +269 -12
- azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +74 -9
- azure/ai/evaluation/_evaluators/_common/_conversation_aggregators.py +49 -0
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +73 -53
- azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +35 -5
- azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +26 -5
- azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +35 -5
- azure/ai/evaluation/_evaluators/_content_safety/_violence.py +34 -4
- azure/ai/evaluation/_evaluators/_document_retrieval/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_document_retrieval/_document_retrieval.py +442 -0
- azure/ai/evaluation/_evaluators/_eci/_eci.py +6 -3
- azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +97 -70
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +39 -3
- azure/ai/evaluation/_evaluators/_gleu/_gleu.py +80 -25
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +230 -20
- azure/ai/evaluation/_evaluators/_groundedness/groundedness_with_query.prompty +30 -29
- azure/ai/evaluation/_evaluators/_groundedness/groundedness_without_query.prompty +19 -14
- azure/ai/evaluation/_evaluators/_intent_resolution/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_intent_resolution/_intent_resolution.py +196 -0
- azure/ai/evaluation/_evaluators/_intent_resolution/intent_resolution.prompty +275 -0
- azure/ai/evaluation/_evaluators/_meteor/_meteor.py +89 -36
- azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +22 -4
- azure/ai/evaluation/_evaluators/_qa/_qa.py +94 -35
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +100 -4
- azure/ai/evaluation/_evaluators/_relevance/relevance.prompty +154 -56
- azure/ai/evaluation/_evaluators/_response_completeness/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_response_completeness/_response_completeness.py +202 -0
- azure/ai/evaluation/_evaluators/_response_completeness/response_completeness.prompty +84 -0
- azure/ai/evaluation/_evaluators/_retrieval/_retrieval.py +39 -3
- azure/ai/evaluation/_evaluators/_rouge/_rouge.py +166 -26
- azure/ai/evaluation/_evaluators/_service_groundedness/_service_groundedness.py +38 -7
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +81 -85
- azure/ai/evaluation/_evaluators/_task_adherence/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_adherence/_task_adherence.py +226 -0
- azure/ai/evaluation/_evaluators/_task_adherence/task_adherence.prompty +101 -0
- azure/ai/evaluation/_evaluators/_task_completion/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_completion/_task_completion.py +177 -0
- azure/ai/evaluation/_evaluators/_task_completion/task_completion.prompty +220 -0
- azure/ai/evaluation/_evaluators/_task_navigation_efficiency/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_navigation_efficiency/_task_navigation_efficiency.py +384 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/_tool_call_accuracy.py +298 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/tool_call_accuracy.prompty +166 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/_tool_input_accuracy.py +263 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/tool_input_accuracy.prompty +76 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/_tool_output_utilization.py +225 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/tool_output_utilization.prompty +221 -0
- azure/ai/evaluation/_evaluators/_tool_selection/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_selection/_tool_selection.py +266 -0
- azure/ai/evaluation/_evaluators/_tool_selection/tool_selection.prompty +104 -0
- azure/ai/evaluation/_evaluators/_tool_success/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_tool_success/_tool_success.py +301 -0
- azure/ai/evaluation/_evaluators/_tool_success/tool_success.prompty +321 -0
- azure/ai/evaluation/_evaluators/_ungrounded_attributes/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_ungrounded_attributes/_ungrounded_attributes.py +102 -0
- azure/ai/evaluation/_evaluators/_xpia/xpia.py +20 -4
- azure/ai/evaluation/_exceptions.py +24 -1
- azure/ai/evaluation/_http_utils.py +7 -5
- azure/ai/evaluation/_legacy/__init__.py +3 -0
- azure/ai/evaluation/_legacy/_adapters/__init__.py +7 -0
- azure/ai/evaluation/_legacy/_adapters/_check.py +17 -0
- azure/ai/evaluation/_legacy/_adapters/_configuration.py +45 -0
- azure/ai/evaluation/_legacy/_adapters/_constants.py +10 -0
- azure/ai/evaluation/_legacy/_adapters/_errors.py +29 -0
- azure/ai/evaluation/_legacy/_adapters/_flows.py +28 -0
- azure/ai/evaluation/_legacy/_adapters/_service.py +16 -0
- azure/ai/evaluation/_legacy/_adapters/client.py +51 -0
- azure/ai/evaluation/_legacy/_adapters/entities.py +26 -0
- azure/ai/evaluation/_legacy/_adapters/tracing.py +28 -0
- azure/ai/evaluation/_legacy/_adapters/types.py +15 -0
- azure/ai/evaluation/_legacy/_adapters/utils.py +31 -0
- azure/ai/evaluation/_legacy/_batch_engine/__init__.py +9 -0
- azure/ai/evaluation/_legacy/_batch_engine/_config.py +48 -0
- azure/ai/evaluation/_legacy/_batch_engine/_engine.py +477 -0
- azure/ai/evaluation/_legacy/_batch_engine/_exceptions.py +88 -0
- azure/ai/evaluation/_legacy/_batch_engine/_openai_injector.py +132 -0
- azure/ai/evaluation/_legacy/_batch_engine/_result.py +107 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run.py +127 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run_storage.py +128 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run_submitter.py +262 -0
- azure/ai/evaluation/_legacy/_batch_engine/_status.py +25 -0
- azure/ai/evaluation/_legacy/_batch_engine/_trace.py +97 -0
- azure/ai/evaluation/_legacy/_batch_engine/_utils.py +97 -0
- azure/ai/evaluation/_legacy/_batch_engine/_utils_deprecated.py +131 -0
- azure/ai/evaluation/_legacy/_common/__init__.py +3 -0
- azure/ai/evaluation/_legacy/_common/_async_token_provider.py +117 -0
- azure/ai/evaluation/_legacy/_common/_logging.py +292 -0
- azure/ai/evaluation/_legacy/_common/_thread_pool_executor_with_context.py +17 -0
- azure/ai/evaluation/_legacy/prompty/__init__.py +36 -0
- azure/ai/evaluation/_legacy/prompty/_connection.py +119 -0
- azure/ai/evaluation/_legacy/prompty/_exceptions.py +139 -0
- azure/ai/evaluation/_legacy/prompty/_prompty.py +430 -0
- azure/ai/evaluation/_legacy/prompty/_utils.py +663 -0
- azure/ai/evaluation/_legacy/prompty/_yaml_utils.py +99 -0
- azure/ai/evaluation/_model_configurations.py +26 -0
- azure/ai/evaluation/_safety_evaluation/__init__.py +3 -0
- azure/ai/evaluation/_safety_evaluation/_generated_rai_client.py +0 -0
- azure/ai/evaluation/_safety_evaluation/_safety_evaluation.py +917 -0
- azure/ai/evaluation/_user_agent.py +32 -1
- azure/ai/evaluation/_vendor/rouge_score/rouge_scorer.py +0 -4
- azure/ai/evaluation/_vendor/rouge_score/scoring.py +0 -4
- azure/ai/evaluation/_vendor/rouge_score/tokenize.py +0 -4
- azure/ai/evaluation/_version.py +2 -1
- azure/ai/evaluation/red_team/__init__.py +22 -0
- azure/ai/evaluation/red_team/_agent/__init__.py +3 -0
- azure/ai/evaluation/red_team/_agent/_agent_functions.py +261 -0
- azure/ai/evaluation/red_team/_agent/_agent_tools.py +461 -0
- azure/ai/evaluation/red_team/_agent/_agent_utils.py +89 -0
- azure/ai/evaluation/red_team/_agent/_semantic_kernel_plugin.py +228 -0
- azure/ai/evaluation/red_team/_attack_objective_generator.py +268 -0
- azure/ai/evaluation/red_team/_attack_strategy.py +49 -0
- azure/ai/evaluation/red_team/_callback_chat_target.py +115 -0
- azure/ai/evaluation/red_team/_default_converter.py +21 -0
- azure/ai/evaluation/red_team/_evaluation_processor.py +505 -0
- azure/ai/evaluation/red_team/_mlflow_integration.py +430 -0
- azure/ai/evaluation/red_team/_orchestrator_manager.py +803 -0
- azure/ai/evaluation/red_team/_red_team.py +1717 -0
- azure/ai/evaluation/red_team/_red_team_result.py +661 -0
- azure/ai/evaluation/red_team/_result_processor.py +1708 -0
- azure/ai/evaluation/red_team/_utils/__init__.py +37 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_eval_chat_target.py +128 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_target.py +601 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_true_false_scorer.py +114 -0
- azure/ai/evaluation/red_team/_utils/constants.py +72 -0
- azure/ai/evaluation/red_team/_utils/exception_utils.py +345 -0
- azure/ai/evaluation/red_team/_utils/file_utils.py +266 -0
- azure/ai/evaluation/red_team/_utils/formatting_utils.py +365 -0
- azure/ai/evaluation/red_team/_utils/logging_utils.py +139 -0
- azure/ai/evaluation/red_team/_utils/metric_mapping.py +73 -0
- azure/ai/evaluation/red_team/_utils/objective_utils.py +46 -0
- azure/ai/evaluation/red_team/_utils/progress_utils.py +252 -0
- azure/ai/evaluation/red_team/_utils/retry_utils.py +218 -0
- azure/ai/evaluation/red_team/_utils/strategy_utils.py +218 -0
- azure/ai/evaluation/simulator/_adversarial_scenario.py +6 -0
- azure/ai/evaluation/simulator/_adversarial_simulator.py +187 -80
- azure/ai/evaluation/simulator/_constants.py +1 -0
- azure/ai/evaluation/simulator/_conversation/__init__.py +138 -11
- azure/ai/evaluation/simulator/_conversation/_conversation.py +6 -2
- azure/ai/evaluation/simulator/_conversation/constants.py +1 -1
- azure/ai/evaluation/simulator/_direct_attack_simulator.py +37 -24
- azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +1 -0
- azure/ai/evaluation/simulator/_indirect_attack_simulator.py +56 -28
- azure/ai/evaluation/simulator/_model_tools/__init__.py +2 -1
- azure/ai/evaluation/simulator/_model_tools/_generated_rai_client.py +225 -0
- azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +12 -10
- azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +100 -45
- azure/ai/evaluation/simulator/_model_tools/_rai_client.py +101 -3
- azure/ai/evaluation/simulator/_model_tools/_template_handler.py +31 -11
- azure/ai/evaluation/simulator/_model_tools/models.py +20 -17
- azure/ai/evaluation/simulator/_simulator.py +43 -19
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.3.dist-info}/METADATA +366 -27
- azure_ai_evaluation-1.13.3.dist-info/RECORD +305 -0
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.3.dist-info}/WHEEL +1 -1
- azure/ai/evaluation/_evaluators/_multimodal/__init__.py +0 -20
- azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal.py +0 -132
- azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal_base.py +0 -55
- azure/ai/evaluation/_evaluators/_multimodal/_hate_unfairness.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_protected_material.py +0 -124
- azure/ai/evaluation/_evaluators/_multimodal/_self_harm.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_sexual.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_violence.py +0 -100
- azure/ai/evaluation/simulator/_tracing.py +0 -89
- azure_ai_evaluation-1.0.1.dist-info/RECORD +0 -119
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.3.dist-info/licenses}/NOTICE.txt +0 -0
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.3.dist-info}/top_level.txt +0 -0
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
# noqa: E501
|
|
6
6
|
import logging
|
|
7
7
|
from random import randint
|
|
8
|
-
from typing import Callable, Optional, cast
|
|
8
|
+
from typing import Callable, Optional, cast, Union
|
|
9
9
|
|
|
10
|
+
from azure.ai.evaluation._constants import TokenScope
|
|
10
11
|
from azure.ai.evaluation._common._experimental import experimental
|
|
11
|
-
from azure.ai.evaluation._common.utils import validate_azure_ai_project
|
|
12
|
+
from azure.ai.evaluation._common.utils import validate_azure_ai_project, is_onedp_project
|
|
12
13
|
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
13
14
|
from azure.ai.evaluation.simulator import AdversarialScenario
|
|
14
15
|
from azure.ai.evaluation._model_configurations import AzureAIProject
|
|
16
|
+
from azure.ai.evaluation._common.onedp._client import ProjectsClient as AIProjectClient
|
|
15
17
|
from azure.core.credentials import TokenCredential
|
|
16
18
|
|
|
17
19
|
from ._adversarial_simulator import AdversarialSimulator
|
|
18
|
-
from ._model_tools import AdversarialTemplateHandler, ManagedIdentityAPITokenManager, RAIClient
|
|
20
|
+
from ._model_tools import AdversarialTemplateHandler, ManagedIdentityAPITokenManager, RAIClient
|
|
19
21
|
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
@@ -26,9 +28,9 @@ class DirectAttackSimulator:
|
|
|
26
28
|
Initialize a UPIA (user prompt injected attack) jailbreak adversarial simulator with a project scope.
|
|
27
29
|
This simulator converses with your AI system using prompts designed to interrupt normal functionality.
|
|
28
30
|
|
|
29
|
-
:param azure_ai_project: The
|
|
30
|
-
name.
|
|
31
|
-
:type azure_ai_project:
|
|
31
|
+
:param azure_ai_project: The Azure AI project, which can either be a string representing the project endpoint
|
|
32
|
+
or an instance of AzureAIProject. It contains subscription id, resource group, and project name.
|
|
33
|
+
:type azure_ai_project: Union[str, AzureAIProject]
|
|
32
34
|
:param credential: The credential for connecting to Azure AI project.
|
|
33
35
|
:type credential: ~azure.core.credentials.TokenCredential
|
|
34
36
|
|
|
@@ -42,26 +44,37 @@ class DirectAttackSimulator:
|
|
|
42
44
|
:caption: Run the DirectAttackSimulator to produce 2 results with 3 conversation turns each (6 messages in each result).
|
|
43
45
|
"""
|
|
44
46
|
|
|
45
|
-
def __init__(self, *, azure_ai_project: AzureAIProject, credential: TokenCredential):
|
|
47
|
+
def __init__(self, *, azure_ai_project: Union[str, AzureAIProject], credential: TokenCredential):
|
|
46
48
|
"""Constructor."""
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
self.azure_ai_project =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
if is_onedp_project(azure_ai_project):
|
|
51
|
+
self.azure_ai_project = azure_ai_project
|
|
52
|
+
self.credential = cast(TokenCredential, credential)
|
|
53
|
+
self.token_manager = ManagedIdentityAPITokenManager(
|
|
54
|
+
token_scope=TokenScope.COGNITIVE_SERVICES_MANAGEMENT,
|
|
55
|
+
logger=logging.getLogger("AdversarialSimulator"),
|
|
56
|
+
credential=self.credential,
|
|
57
|
+
)
|
|
58
|
+
self.rai_client = AIProjectClient(endpoint=azure_ai_project, credential=credential)
|
|
59
|
+
else:
|
|
60
|
+
try:
|
|
61
|
+
self.azure_ai_project = validate_azure_ai_project(azure_ai_project)
|
|
62
|
+
except EvaluationException as e:
|
|
63
|
+
raise EvaluationException(
|
|
64
|
+
message=e.message,
|
|
65
|
+
internal_message=e.internal_message,
|
|
66
|
+
target=ErrorTarget.DIRECT_ATTACK_SIMULATOR,
|
|
67
|
+
category=e.category,
|
|
68
|
+
blame=e.blame,
|
|
69
|
+
) from e
|
|
70
|
+
self.credential = cast(TokenCredential, credential)
|
|
71
|
+
self.token_manager = ManagedIdentityAPITokenManager(
|
|
72
|
+
token_scope=TokenScope.DEFAULT_AZURE_MANAGEMENT,
|
|
73
|
+
logger=logging.getLogger("AdversarialSimulator"),
|
|
74
|
+
credential=self.credential,
|
|
75
|
+
)
|
|
76
|
+
self.rai_client = RAIClient(azure_ai_project=self.azure_ai_project, token_manager=self.token_manager)
|
|
77
|
+
|
|
65
78
|
self.adversarial_template_handler = AdversarialTemplateHandler(
|
|
66
79
|
azure_ai_project=self.azure_ai_project, rai_client=self.rai_client
|
|
67
80
|
)
|
|
@@ -14,4 +14,5 @@ SUPPORTED_LANGUAGES_MAPPING = {
|
|
|
14
14
|
SupportedLanguages.SimplifiedChinese: BASE_SUFFIX.replace("__language__", "simplified chinese"),
|
|
15
15
|
SupportedLanguages.Portuguese: BASE_SUFFIX.replace("__language__", "portuguese"),
|
|
16
16
|
SupportedLanguages.Japanese: BASE_SUFFIX.replace("__language__", "japanese"),
|
|
17
|
+
SupportedLanguages.Korean: BASE_SUFFIX.replace("__language__", "korean"),
|
|
17
18
|
}
|
|
@@ -5,20 +5,23 @@
|
|
|
5
5
|
# noqa: E501
|
|
6
6
|
import asyncio
|
|
7
7
|
import logging
|
|
8
|
-
|
|
8
|
+
import random
|
|
9
|
+
from typing import Callable, cast, Union, Optional
|
|
9
10
|
|
|
10
11
|
from tqdm import tqdm
|
|
11
12
|
|
|
12
|
-
from azure.ai.evaluation._common.utils import validate_azure_ai_project
|
|
13
|
+
from azure.ai.evaluation._common.utils import validate_azure_ai_project, is_onedp_project
|
|
13
14
|
from azure.ai.evaluation._common._experimental import experimental
|
|
14
15
|
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
15
16
|
from azure.ai.evaluation.simulator import AdversarialScenarioJailbreak, SupportedLanguages
|
|
16
17
|
from azure.ai.evaluation._model_configurations import AzureAIProject
|
|
18
|
+
from azure.ai.evaluation._common.onedp._client import ProjectsClient as AIProjectClient
|
|
17
19
|
from azure.core.credentials import TokenCredential
|
|
20
|
+
from azure.ai.evaluation._constants import TokenScope
|
|
18
21
|
|
|
19
22
|
from ._adversarial_simulator import AdversarialSimulator, JsonLineList
|
|
20
23
|
|
|
21
|
-
from ._model_tools import AdversarialTemplateHandler, ManagedIdentityAPITokenManager, RAIClient
|
|
24
|
+
from ._model_tools import AdversarialTemplateHandler, ManagedIdentityAPITokenManager, RAIClient
|
|
22
25
|
|
|
23
26
|
logger = logging.getLogger(__name__)
|
|
24
27
|
|
|
@@ -28,9 +31,9 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
28
31
|
"""
|
|
29
32
|
Initializes the XPIA (cross domain prompt injected attack) jailbreak adversarial simulator with a project scope.
|
|
30
33
|
|
|
31
|
-
:param azure_ai_project: The
|
|
32
|
-
name.
|
|
33
|
-
:type azure_ai_project:
|
|
34
|
+
:param azure_ai_project: The Azure AI project, which can either be a string representing the project endpoint
|
|
35
|
+
or an instance of AzureAIProject. It contains subscription id, resource group, and project name.
|
|
36
|
+
:type azure_ai_project: Union[str, AzureAIProject]
|
|
34
37
|
:param credential: The credential for connecting to Azure AI project.
|
|
35
38
|
:type credential: ~azure.core.credentials.TokenCredential
|
|
36
39
|
|
|
@@ -44,30 +47,43 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
44
47
|
:caption: Run the IndirectAttackSimulator to produce 1 result with 1 conversation turn (2 messages in the result).
|
|
45
48
|
"""
|
|
46
49
|
|
|
47
|
-
def __init__(self, *, azure_ai_project: AzureAIProject, credential: TokenCredential):
|
|
50
|
+
def __init__(self, *, azure_ai_project: Union[str, AzureAIProject], credential: TokenCredential):
|
|
48
51
|
"""Constructor."""
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
self.azure_ai_project =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
53
|
+
if is_onedp_project(azure_ai_project):
|
|
54
|
+
self.azure_ai_project = azure_ai_project
|
|
55
|
+
self.credential = cast(TokenCredential, credential)
|
|
56
|
+
self.token_manager = ManagedIdentityAPITokenManager(
|
|
57
|
+
token_scope=TokenScope.COGNITIVE_SERVICES_MANAGEMENT,
|
|
58
|
+
logger=logging.getLogger("AdversarialSimulator"),
|
|
59
|
+
credential=self.credential,
|
|
60
|
+
)
|
|
61
|
+
self.rai_client = AIProjectClient(endpoint=azure_ai_project, credential=credential)
|
|
62
|
+
self.adversarial_template_handler = AdversarialTemplateHandler(
|
|
63
|
+
azure_ai_project=self.azure_ai_project, rai_client=self.rai_client
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
try:
|
|
67
|
+
self.azure_ai_project = validate_azure_ai_project(azure_ai_project)
|
|
68
|
+
except EvaluationException as e:
|
|
69
|
+
raise EvaluationException(
|
|
70
|
+
message=e.message,
|
|
71
|
+
internal_message=e.internal_message,
|
|
72
|
+
target=ErrorTarget.DIRECT_ATTACK_SIMULATOR,
|
|
73
|
+
category=e.category,
|
|
74
|
+
blame=e.blame,
|
|
75
|
+
) from e
|
|
76
|
+
|
|
77
|
+
self.credential = cast(TokenCredential, credential)
|
|
78
|
+
self.token_manager = ManagedIdentityAPITokenManager(
|
|
79
|
+
token_scope=TokenScope.DEFAULT_AZURE_MANAGEMENT,
|
|
80
|
+
logger=logging.getLogger("AdversarialSimulator"),
|
|
81
|
+
credential=self.credential,
|
|
82
|
+
)
|
|
83
|
+
self.rai_client = RAIClient(azure_ai_project=self.azure_ai_project, token_manager=self.token_manager)
|
|
84
|
+
self.adversarial_template_handler = AdversarialTemplateHandler(
|
|
85
|
+
azure_ai_project=self.azure_ai_project, rai_client=self.rai_client
|
|
86
|
+
)
|
|
71
87
|
super().__init__(azure_ai_project=azure_ai_project, credential=credential)
|
|
72
88
|
|
|
73
89
|
def _ensure_service_dependencies(self):
|
|
@@ -90,6 +106,7 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
90
106
|
api_call_retry_sleep_sec: int = 1,
|
|
91
107
|
api_call_delay_sec: int = 0,
|
|
92
108
|
concurrent_async_task: int = 3,
|
|
109
|
+
randomization_seed: Optional[int] = None,
|
|
93
110
|
**kwargs,
|
|
94
111
|
):
|
|
95
112
|
"""
|
|
@@ -115,6 +132,9 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
115
132
|
:keyword concurrent_async_task: The number of asynchronous tasks to run concurrently during the simulation.
|
|
116
133
|
Defaults to 3.
|
|
117
134
|
:paramtype concurrent_async_task: int
|
|
135
|
+
:keyword randomization_seed: The seed used to randomize prompt selection. If unset, the system's
|
|
136
|
+
default seed is used. Defaults to None.
|
|
137
|
+
:paramtype randomization_seed: Optional[int]
|
|
118
138
|
:return: A list of dictionaries, each representing a simulated conversation. Each dictionary contains:
|
|
119
139
|
|
|
120
140
|
- 'template_parameters': A dictionary with parameters used in the conversation template,
|
|
@@ -175,6 +195,13 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
175
195
|
ncols=100,
|
|
176
196
|
unit="simulations",
|
|
177
197
|
)
|
|
198
|
+
|
|
199
|
+
# Apply randomization to templates if seed is provided
|
|
200
|
+
if randomization_seed is not None:
|
|
201
|
+
# Create a local random instance to avoid polluting global state
|
|
202
|
+
local_random = random.Random(randomization_seed)
|
|
203
|
+
local_random.shuffle(templates)
|
|
204
|
+
|
|
178
205
|
for template in templates:
|
|
179
206
|
for parameter in template.template_parameters:
|
|
180
207
|
tasks.append(
|
|
@@ -189,6 +216,7 @@ class IndirectAttackSimulator(AdversarialSimulator):
|
|
|
189
216
|
api_call_delay_sec=api_call_delay_sec,
|
|
190
217
|
language=language,
|
|
191
218
|
semaphore=semaphore,
|
|
219
|
+
scenario=scenario,
|
|
192
220
|
)
|
|
193
221
|
)
|
|
194
222
|
)
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
"""Tooling for model evaluation"""
|
|
6
6
|
|
|
7
|
-
from ._identity_manager import ManagedIdentityAPITokenManager, PlainTokenManager
|
|
7
|
+
from ._identity_manager import ManagedIdentityAPITokenManager, PlainTokenManager
|
|
8
8
|
from ._proxy_completion_model import ProxyChatCompletionsModel
|
|
9
9
|
from ._rai_client import RAIClient
|
|
10
10
|
from ._template_handler import CONTENT_HARM_TEMPLATES_COLLECTION_KEY, AdversarialTemplateHandler
|
|
11
11
|
from .models import LLMBase, OpenAIChatCompletionsModel
|
|
12
|
+
from ..._constants import TokenScope
|
|
12
13
|
|
|
13
14
|
__all__ = [
|
|
14
15
|
"ManagedIdentityAPITokenManager",
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
from typing import Dict, List, Optional, Union
|
|
8
|
+
|
|
9
|
+
from azure.core.credentials import TokenCredential
|
|
10
|
+
from azure.core.pipeline.policies import UserAgentPolicy
|
|
11
|
+
from azure.ai.evaluation._model_configurations import AzureAIProject
|
|
12
|
+
from azure.ai.evaluation.simulator._model_tools import ManagedIdentityAPITokenManager
|
|
13
|
+
from azure.ai.evaluation._common.raiclient import MachineLearningServicesClient
|
|
14
|
+
from azure.ai.evaluation._constants import TokenScope
|
|
15
|
+
from azure.ai.evaluation._common.utils import is_onedp_project
|
|
16
|
+
from azure.ai.evaluation._common.onedp import ProjectsClient as AIProjectClient
|
|
17
|
+
from azure.ai.evaluation._common import EvaluationServiceOneDPClient
|
|
18
|
+
from azure.ai.evaluation._user_agent import UserAgentSingleton
|
|
19
|
+
import jwt
|
|
20
|
+
import time
|
|
21
|
+
import ast
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GeneratedRAIClient:
|
|
25
|
+
"""Client for the Responsible AI Service using the auto-generated MachineLearningServicesClient.
|
|
26
|
+
|
|
27
|
+
:param azure_ai_project: The Azure AI project, which can either be a string representing the project endpoint
|
|
28
|
+
or an instance of AzureAIProject. It contains subscription id, resource group, and project name.
|
|
29
|
+
:type azure_ai_project: Union[str, ~azure.ai.evaluation.AzureAIProject]
|
|
30
|
+
:param token_manager: The token manager
|
|
31
|
+
:type token_manager: ~azure.ai.evaluation.simulator._model_tools._identity_manager.APITokenManager
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
azure_ai_project: Union[AzureAIProject, str],
|
|
37
|
+
token_manager: ManagedIdentityAPITokenManager,
|
|
38
|
+
):
|
|
39
|
+
self.azure_ai_project = azure_ai_project
|
|
40
|
+
self.token_manager = token_manager
|
|
41
|
+
self.logger = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
user_agent_policy = UserAgentPolicy(base_user_agent=UserAgentSingleton().value)
|
|
44
|
+
|
|
45
|
+
if not is_onedp_project(azure_ai_project):
|
|
46
|
+
# Service URL construction
|
|
47
|
+
if "RAI_SVC_URL" in os.environ:
|
|
48
|
+
endpoint = os.environ["RAI_SVC_URL"].rstrip("/")
|
|
49
|
+
else:
|
|
50
|
+
endpoint = self._get_service_discovery_url()
|
|
51
|
+
|
|
52
|
+
# Create the autogenerated client
|
|
53
|
+
self._client = MachineLearningServicesClient(
|
|
54
|
+
endpoint=endpoint,
|
|
55
|
+
subscription_id=self.azure_ai_project["subscription_id"],
|
|
56
|
+
resource_group_name=self.azure_ai_project["resource_group_name"],
|
|
57
|
+
workspace_name=self.azure_ai_project["project_name"],
|
|
58
|
+
credential=self.token_manager,
|
|
59
|
+
).rai_svc
|
|
60
|
+
else:
|
|
61
|
+
self._client = AIProjectClient(
|
|
62
|
+
endpoint=azure_ai_project,
|
|
63
|
+
credential=token_manager,
|
|
64
|
+
user_agent_policy=user_agent_policy,
|
|
65
|
+
).red_teams
|
|
66
|
+
self._evaluation_onedp_client = EvaluationServiceOneDPClient(
|
|
67
|
+
endpoint=azure_ai_project,
|
|
68
|
+
credential=token_manager,
|
|
69
|
+
user_agent_policy=user_agent_policy,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def _get_service_discovery_url(self):
|
|
73
|
+
"""Get the service discovery URL.
|
|
74
|
+
|
|
75
|
+
:return: The service discovery URL
|
|
76
|
+
:rtype: str
|
|
77
|
+
"""
|
|
78
|
+
import requests
|
|
79
|
+
|
|
80
|
+
bearer_token = self._fetch_or_reuse_token(self.token_manager)
|
|
81
|
+
headers = {
|
|
82
|
+
"Authorization": f"Bearer {bearer_token}",
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
response = requests.get(
|
|
87
|
+
f"https://management.azure.com/subscriptions/{self.azure_ai_project['subscription_id']}/"
|
|
88
|
+
f"resourceGroups/{self.azure_ai_project['resource_group_name']}/"
|
|
89
|
+
f"providers/Microsoft.MachineLearningServices/workspaces/{self.azure_ai_project['project_name']}?"
|
|
90
|
+
f"api-version=2023-08-01-preview",
|
|
91
|
+
headers=headers,
|
|
92
|
+
timeout=5,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if response.status_code != 200:
|
|
96
|
+
msg = (
|
|
97
|
+
f"Failed to connect to your Azure AI project. Please check if the project scope is configured "
|
|
98
|
+
f"correctly, and make sure you have the necessary access permissions. "
|
|
99
|
+
f"Status code: {response.status_code}."
|
|
100
|
+
)
|
|
101
|
+
raise Exception(msg)
|
|
102
|
+
|
|
103
|
+
# Parse the discovery URL
|
|
104
|
+
from urllib.parse import urlparse
|
|
105
|
+
|
|
106
|
+
base_url = urlparse(response.json()["properties"]["discoveryUrl"])
|
|
107
|
+
return f"{base_url.scheme}://{base_url.netloc}"
|
|
108
|
+
|
|
109
|
+
async def get_attack_objectives(
|
|
110
|
+
self,
|
|
111
|
+
*,
|
|
112
|
+
risk_type: Optional[str] = None,
|
|
113
|
+
risk_category: Optional[str] = None,
|
|
114
|
+
application_scenario: str = None,
|
|
115
|
+
strategy: Optional[str] = None,
|
|
116
|
+
language: str = "en",
|
|
117
|
+
scan_session_id: Optional[str] = None,
|
|
118
|
+
target: Optional[str] = None,
|
|
119
|
+
client_id: Optional[str] = None,
|
|
120
|
+
) -> Dict:
|
|
121
|
+
"""Get attack objectives using the auto-generated operations.
|
|
122
|
+
|
|
123
|
+
:param risk_type: Optional risk type to filter the attack objectives
|
|
124
|
+
:type risk_type: Optional[str]
|
|
125
|
+
:param risk_category: Optional risk category to filter the attack objectives
|
|
126
|
+
:type risk_category: Optional[str]
|
|
127
|
+
:param application_scenario: Optional description of the application scenario for context
|
|
128
|
+
:type application_scenario: str
|
|
129
|
+
:param strategy: Optional strategy to filter the attack objectives
|
|
130
|
+
:type strategy: Optional[str]
|
|
131
|
+
:param language: Language code for the attack objectives (e.g., "en", "es", "fr")
|
|
132
|
+
:type language: str
|
|
133
|
+
:param scan_session_id: Optional unique session ID for the scan
|
|
134
|
+
:type scan_session_id: Optional[str]
|
|
135
|
+
:param target: Optional target type (model/agent)
|
|
136
|
+
:type target: Optional[str]
|
|
137
|
+
:param client_id: Optional client ID for ACA token authorization
|
|
138
|
+
:type client_id: Optional[str]
|
|
139
|
+
:return: The attack objectives
|
|
140
|
+
:rtype: Dict
|
|
141
|
+
"""
|
|
142
|
+
try:
|
|
143
|
+
# Build headers dictionary
|
|
144
|
+
headers = {}
|
|
145
|
+
if scan_session_id:
|
|
146
|
+
headers["x-ms-client-request-id"] = scan_session_id
|
|
147
|
+
if client_id:
|
|
148
|
+
from azure.identity import DefaultAzureCredential
|
|
149
|
+
|
|
150
|
+
self.logger.info(f"Using client_id: {client_id} to set token in aml-aca-token header ")
|
|
151
|
+
|
|
152
|
+
# Get token using the client_id for managed identity
|
|
153
|
+
managed_identity_credential = DefaultAzureCredential(
|
|
154
|
+
managed_identity_client_id=client_id, exclude_interactive_browser_credential=True
|
|
155
|
+
)
|
|
156
|
+
token = managed_identity_credential.get_token(TokenScope.DEFAULT_AZURE_MANAGEMENT).token
|
|
157
|
+
headers["aml-aca-token"] = token
|
|
158
|
+
|
|
159
|
+
# Send the request using the autogenerated client
|
|
160
|
+
response = self._client.get_attack_objectives(
|
|
161
|
+
risk_types=[risk_type],
|
|
162
|
+
risk_category=risk_category,
|
|
163
|
+
lang=language,
|
|
164
|
+
strategy=strategy,
|
|
165
|
+
target_type=target,
|
|
166
|
+
headers=headers,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
return response
|
|
170
|
+
|
|
171
|
+
except Exception as e:
|
|
172
|
+
# Log the exception for debugging purposes
|
|
173
|
+
import logging
|
|
174
|
+
|
|
175
|
+
logging.error(f"Error in get_attack_objectives: {str(e)}")
|
|
176
|
+
raise
|
|
177
|
+
|
|
178
|
+
async def get_jailbreak_prefixes(self, scan_session_id: Optional[str] = None) -> List[str]:
|
|
179
|
+
"""Get jailbreak prefixes using the auto-generated operations.
|
|
180
|
+
|
|
181
|
+
:param scan_session_id: Optional unique session ID for the scan
|
|
182
|
+
:type scan_session_id: Optional[str]
|
|
183
|
+
:return: The jailbreak prefixes
|
|
184
|
+
:rtype: List[str]
|
|
185
|
+
"""
|
|
186
|
+
try:
|
|
187
|
+
# Send the request using the autogenerated client
|
|
188
|
+
response = self._client.get_jail_break_dataset_with_type(
|
|
189
|
+
type="upia", headers={"x-ms-client-request-id": scan_session_id}
|
|
190
|
+
)
|
|
191
|
+
if isinstance(response, list):
|
|
192
|
+
return response
|
|
193
|
+
else:
|
|
194
|
+
self.logger.error("Unexpected response format from get_jail_break_dataset_with_type")
|
|
195
|
+
raise ValueError("Unexpected response format from get_jail_break_dataset_with_type")
|
|
196
|
+
|
|
197
|
+
except Exception as e:
|
|
198
|
+
return [""]
|
|
199
|
+
|
|
200
|
+
def _fetch_or_reuse_token(self, credential: TokenCredential, token: Optional[str] = None) -> str:
|
|
201
|
+
"""Get token. Fetch a new token if the current token is near expiry
|
|
202
|
+
|
|
203
|
+
:param credential: The Azure authentication credential.
|
|
204
|
+
:type credential:
|
|
205
|
+
~azure.core.credentials.TokenCredential
|
|
206
|
+
:param token: The Azure authentication token. Defaults to None. If none, a new token will be fetched.
|
|
207
|
+
:type token: str
|
|
208
|
+
:return: The Azure authentication token.
|
|
209
|
+
"""
|
|
210
|
+
if token:
|
|
211
|
+
# Decode the token to get its expiration time
|
|
212
|
+
try:
|
|
213
|
+
decoded_token = jwt.decode(token, options={"verify_signature": False})
|
|
214
|
+
except jwt.PyJWTError:
|
|
215
|
+
pass
|
|
216
|
+
else:
|
|
217
|
+
exp_time = decoded_token["exp"]
|
|
218
|
+
current_time = time.time()
|
|
219
|
+
|
|
220
|
+
# Return current token if not near expiry
|
|
221
|
+
if (exp_time - current_time) >= 300:
|
|
222
|
+
return token
|
|
223
|
+
|
|
224
|
+
# Get token
|
|
225
|
+
return credential.get_token(TokenScope.DEFAULT_AZURE_MANAGEMENT).token
|
|
@@ -8,9 +8,9 @@ import logging
|
|
|
8
8
|
import os
|
|
9
9
|
import time
|
|
10
10
|
from abc import ABC, abstractmethod
|
|
11
|
-
from
|
|
12
|
-
from typing import Optional, Union
|
|
11
|
+
from typing import Optional, Union, Any
|
|
13
12
|
|
|
13
|
+
from azure.ai.evaluation._constants import TokenScope
|
|
14
14
|
from azure.core.credentials import AccessToken, TokenCredential
|
|
15
15
|
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
|
|
16
16
|
|
|
@@ -19,12 +19,6 @@ AZURE_TOKEN_REFRESH_INTERVAL = int(
|
|
|
19
19
|
) # token refresh interval in seconds
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class TokenScope(Enum):
|
|
23
|
-
"""Token scopes for Azure endpoints"""
|
|
24
|
-
|
|
25
|
-
DEFAULT_AZURE_MANAGEMENT = "https://management.azure.com/.default"
|
|
26
|
-
|
|
27
|
-
|
|
28
22
|
class APITokenManager(ABC):
|
|
29
23
|
"""Base class for managing API tokens. Subclasses should implement the get_token method.
|
|
30
24
|
|
|
@@ -83,7 +77,14 @@ class APITokenManager(ABC):
|
|
|
83
77
|
return DefaultAzureCredential()
|
|
84
78
|
|
|
85
79
|
@abstractmethod
|
|
86
|
-
def get_token(
|
|
80
|
+
def get_token(
|
|
81
|
+
self,
|
|
82
|
+
scopes: Union[str, None] = None,
|
|
83
|
+
claims: Union[str, None] = None,
|
|
84
|
+
tenant_id: Union[str, None] = None,
|
|
85
|
+
enable_cae: bool = False,
|
|
86
|
+
**kwargs: Any,
|
|
87
|
+
) -> AccessToken:
|
|
87
88
|
"""Async method to get the API token. Subclasses should implement this method.
|
|
88
89
|
|
|
89
90
|
:return: API token
|
|
@@ -103,7 +104,7 @@ class ManagedIdentityAPITokenManager(APITokenManager):
|
|
|
103
104
|
"""API Token Manager for Azure Managed Identity
|
|
104
105
|
|
|
105
106
|
:param token_scope: Token scope for Azure endpoint
|
|
106
|
-
:type token_scope: ~azure.ai.evaluation.
|
|
107
|
+
:type token_scope: ~azure.ai.evaluation._constants.TokenScope
|
|
107
108
|
:param logger: Logger object
|
|
108
109
|
:type logger: logging.Logger
|
|
109
110
|
:keyword kwargs: Additional keyword arguments
|
|
@@ -151,6 +152,7 @@ class ManagedIdentityAPITokenManager(APITokenManager):
|
|
|
151
152
|
):
|
|
152
153
|
self.last_refresh_time = time.time()
|
|
153
154
|
get_token_method = self.credential.get_token(self.token_scope.value)
|
|
155
|
+
|
|
154
156
|
if inspect.isawaitable(get_token_method):
|
|
155
157
|
# If it's awaitable, await it
|
|
156
158
|
token_response: AccessToken = await get_token_method
|