azure-ai-evaluation 1.5.0__py3-none-any.whl → 1.6.0__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 +9 -0
- azure/ai/evaluation/_aoai/__init__.py +10 -0
- azure/ai/evaluation/_aoai/aoai_grader.py +89 -0
- azure/ai/evaluation/_aoai/label_grader.py +66 -0
- azure/ai/evaluation/_aoai/string_check_grader.py +65 -0
- azure/ai/evaluation/_aoai/text_similarity_grader.py +88 -0
- azure/ai/evaluation/_azure/_clients.py +4 -4
- azure/ai/evaluation/_azure/_envs.py +208 -0
- azure/ai/evaluation/_azure/_token_manager.py +12 -7
- azure/ai/evaluation/_common/__init__.py +5 -0
- azure/ai/evaluation/_common/evaluation_onedp_client.py +118 -0
- azure/ai/evaluation/_common/onedp/__init__.py +32 -0
- azure/ai/evaluation/_common/onedp/_client.py +139 -0
- azure/ai/evaluation/_common/onedp/_configuration.py +73 -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/_validation.py +50 -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 +143 -0
- azure/ai/evaluation/_common/onedp/aio/_configuration.py +75 -0
- azure/ai/evaluation/_common/onedp/aio/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/aio/_vendor.py +40 -0
- azure/ai/evaluation/_common/onedp/aio/operations/__init__.py +39 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_operations.py +4494 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/models/__init__.py +142 -0
- azure/ai/evaluation/_common/onedp/models/_enums.py +162 -0
- azure/ai/evaluation/_common/onedp/models/_models.py +2228 -0
- azure/ai/evaluation/_common/onedp/models/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/operations/__init__.py +39 -0
- azure/ai/evaluation/_common/onedp/operations/_operations.py +5655 -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 +158 -28
- azure/ai/evaluation/_common/raiclient/_version.py +1 -1
- azure/ai/evaluation/_common/utils.py +79 -1
- azure/ai/evaluation/_constants.py +16 -0
- azure/ai/evaluation/_eval_mapping.py +71 -0
- azure/ai/evaluation/_evaluate/_batch_run/_run_submitter_client.py +30 -16
- azure/ai/evaluation/_evaluate/_batch_run/eval_run_context.py +8 -0
- azure/ai/evaluation/_evaluate/_batch_run/proxy_client.py +5 -0
- azure/ai/evaluation/_evaluate/_batch_run/target_run_context.py +17 -1
- azure/ai/evaluation/_evaluate/_eval_run.py +1 -1
- azure/ai/evaluation/_evaluate/_evaluate.py +325 -74
- azure/ai/evaluation/_evaluate/_evaluate_aoai.py +534 -0
- azure/ai/evaluation/_evaluate/_utils.py +117 -4
- azure/ai/evaluation/_evaluators/_common/_base_eval.py +8 -3
- azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +12 -3
- azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +2 -2
- azure/ai/evaluation/_evaluators/_document_retrieval/__init__.py +11 -0
- azure/ai/evaluation/_evaluators/_document_retrieval/_document_retrieval.py +467 -0
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +1 -1
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +1 -1
- azure/ai/evaluation/_evaluators/_intent_resolution/_intent_resolution.py +6 -2
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +1 -1
- azure/ai/evaluation/_evaluators/_response_completeness/_response_completeness.py +7 -2
- azure/ai/evaluation/_evaluators/_response_completeness/response_completeness.prompty +31 -46
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +1 -1
- azure/ai/evaluation/_evaluators/_task_adherence/_task_adherence.py +5 -2
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/_tool_call_accuracy.py +6 -2
- azure/ai/evaluation/_exceptions.py +2 -0
- azure/ai/evaluation/_legacy/_adapters/__init__.py +0 -14
- azure/ai/evaluation/_legacy/_adapters/_check.py +17 -0
- azure/ai/evaluation/_legacy/_adapters/_flows.py +1 -1
- azure/ai/evaluation/_legacy/_batch_engine/_engine.py +51 -32
- azure/ai/evaluation/_legacy/_batch_engine/_openai_injector.py +114 -8
- azure/ai/evaluation/_legacy/_batch_engine/_result.py +6 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run.py +6 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run_submitter.py +69 -29
- azure/ai/evaluation/_legacy/_batch_engine/_trace.py +54 -62
- azure/ai/evaluation/_legacy/_batch_engine/_utils.py +19 -1
- azure/ai/evaluation/_legacy/_common/__init__.py +3 -0
- azure/ai/evaluation/_legacy/_common/_async_token_provider.py +124 -0
- azure/ai/evaluation/_legacy/_common/_thread_pool_executor_with_context.py +15 -0
- azure/ai/evaluation/_legacy/prompty/_connection.py +11 -74
- azure/ai/evaluation/_legacy/prompty/_exceptions.py +80 -0
- azure/ai/evaluation/_legacy/prompty/_prompty.py +119 -9
- azure/ai/evaluation/_legacy/prompty/_utils.py +72 -2
- azure/ai/evaluation/_safety_evaluation/_safety_evaluation.py +90 -17
- azure/ai/evaluation/_version.py +1 -1
- azure/ai/evaluation/red_team/_attack_strategy.py +1 -1
- azure/ai/evaluation/red_team/_red_team.py +825 -450
- azure/ai/evaluation/red_team/_utils/metric_mapping.py +23 -0
- azure/ai/evaluation/red_team/_utils/strategy_utils.py +1 -1
- azure/ai/evaluation/simulator/_adversarial_simulator.py +63 -39
- azure/ai/evaluation/simulator/_constants.py +1 -0
- azure/ai/evaluation/simulator/_conversation/__init__.py +13 -6
- azure/ai/evaluation/simulator/_conversation/_conversation.py +2 -1
- azure/ai/evaluation/simulator/_direct_attack_simulator.py +35 -22
- azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +1 -0
- azure/ai/evaluation/simulator/_indirect_attack_simulator.py +40 -25
- azure/ai/evaluation/simulator/_model_tools/__init__.py +2 -1
- azure/ai/evaluation/simulator/_model_tools/_generated_rai_client.py +24 -18
- azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +5 -10
- azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +65 -41
- azure/ai/evaluation/simulator/_model_tools/_template_handler.py +9 -5
- azure/ai/evaluation/simulator/_model_tools/models.py +20 -17
- {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/METADATA +25 -2
- {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/RECORD +123 -65
- /azure/ai/evaluation/_legacy/{_batch_engine → _common}/_logging.py +0 -0
- {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/NOTICE.txt +0 -0
- {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/WHEEL +0 -0
- {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
"""Customize generated code here.
|
|
7
|
+
|
|
8
|
+
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
9
|
+
"""
|
|
10
|
+
from typing import List
|
|
11
|
+
|
|
12
|
+
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def patch_sdk():
|
|
16
|
+
"""Do not remove from this file.
|
|
17
|
+
|
|
18
|
+
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
19
|
+
you can't accomplish using the techniques described in
|
|
20
|
+
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
21
|
+
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
# pylint: disable=wrong-import-position
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ._patch import * # pylint: disable=unused-wildcard-import
|
|
14
|
+
|
|
15
|
+
from ._operations import ServicePatternsOperations # type: ignore
|
|
16
|
+
|
|
17
|
+
from ._patch import __all__ as _patch_all
|
|
18
|
+
from ._patch import *
|
|
19
|
+
from ._patch import patch_sdk as _patch_sdk
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ServicePatternsOperations",
|
|
23
|
+
]
|
|
24
|
+
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
|
|
25
|
+
_patch_sdk()
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
from azure.core import AsyncPipelineClient
|
|
9
|
+
|
|
10
|
+
from ...._serialization import Deserializer, Serializer
|
|
11
|
+
from ....aio._configuration import AIProjectClientConfiguration
|
|
12
|
+
from ...buildingblocks.aio.operations._operations import ServicePatternsBuildingBlocksOperations
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ServicePatternsOperations:
|
|
16
|
+
"""
|
|
17
|
+
.. warning::
|
|
18
|
+
**DO NOT** instantiate this class directly.
|
|
19
|
+
|
|
20
|
+
Instead, you should access the following operations through
|
|
21
|
+
:class:`~azure.ai.projects.aio.AIProjectClient`'s
|
|
22
|
+
:attr:`service_patterns` attribute.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
26
|
+
input_args = list(args)
|
|
27
|
+
self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client")
|
|
28
|
+
self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config")
|
|
29
|
+
self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer")
|
|
30
|
+
self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer")
|
|
31
|
+
|
|
32
|
+
self.building_blocks = ServicePatternsBuildingBlocksOperations(
|
|
33
|
+
self._client, self._config, self._serialize, self._deserialize
|
|
34
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
"""Customize generated code here.
|
|
6
|
+
|
|
7
|
+
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
8
|
+
"""
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def patch_sdk():
|
|
15
|
+
"""Do not remove from this file.
|
|
16
|
+
|
|
17
|
+
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
18
|
+
you can't accomplish using the techniques described in
|
|
19
|
+
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
20
|
+
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
# pylint: disable=wrong-import-position
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ._patch import * # pylint: disable=unused-wildcard-import
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from ._patch import __all__ as _patch_all
|
|
17
|
+
from ._patch import *
|
|
18
|
+
from ._patch import patch_sdk as _patch_sdk
|
|
19
|
+
|
|
20
|
+
__all__ = []
|
|
21
|
+
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
|
|
22
|
+
_patch_sdk()
|
azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_operations.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
from azure.core import AsyncPipelineClient
|
|
9
|
+
|
|
10
|
+
from ....._serialization import Deserializer, Serializer
|
|
11
|
+
from .....aio._configuration import AIProjectClientConfiguration
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ServicePatternsBuildingBlocksOperations:
|
|
15
|
+
"""
|
|
16
|
+
.. warning::
|
|
17
|
+
**DO NOT** instantiate this class directly.
|
|
18
|
+
|
|
19
|
+
Instead, you should access the following operations through
|
|
20
|
+
:class:`~azure.ai.projects.aio.AIProjectClient`'s
|
|
21
|
+
:attr:`building_blocks` attribute.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
25
|
+
input_args = list(args)
|
|
26
|
+
self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client")
|
|
27
|
+
self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config")
|
|
28
|
+
self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer")
|
|
29
|
+
self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
"""Customize generated code here.
|
|
6
|
+
|
|
7
|
+
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
8
|
+
"""
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def patch_sdk():
|
|
15
|
+
"""Do not remove from this file.
|
|
16
|
+
|
|
17
|
+
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
18
|
+
you can't accomplish using the techniques described in
|
|
19
|
+
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
20
|
+
"""
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
# pylint: disable=wrong-import-position
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ._patch import * # pylint: disable=unused-wildcard-import
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from ._patch import __all__ as _patch_all
|
|
17
|
+
from ._patch import *
|
|
18
|
+
from ._patch import patch_sdk as _patch_sdk
|
|
19
|
+
|
|
20
|
+
__all__ = []
|
|
21
|
+
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
|
|
22
|
+
_patch_sdk()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
from azure.core import PipelineClient
|
|
9
|
+
|
|
10
|
+
from ...._configuration import AIProjectClientConfiguration
|
|
11
|
+
from ...._serialization import Deserializer, Serializer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ServicePatternsBuildingBlocksOperations:
|
|
15
|
+
"""
|
|
16
|
+
.. warning::
|
|
17
|
+
**DO NOT** instantiate this class directly.
|
|
18
|
+
|
|
19
|
+
Instead, you should access the following operations through
|
|
20
|
+
:class:`~azure.ai.projects.AIProjectClient`'s
|
|
21
|
+
:attr:`building_blocks` attribute.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, *args, **kwargs):
|
|
25
|
+
input_args = list(args)
|
|
26
|
+
self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client")
|
|
27
|
+
self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config")
|
|
28
|
+
self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer")
|
|
29
|
+
self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
"""Customize generated code here.
|
|
6
|
+
|
|
7
|
+
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
8
|
+
"""
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def patch_sdk():
|
|
15
|
+
"""Do not remove from this file.
|
|
16
|
+
|
|
17
|
+
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
18
|
+
you can't accomplish using the techniques described in
|
|
19
|
+
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
20
|
+
"""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
# pylint: disable=wrong-import-position
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ._patch import * # pylint: disable=unused-wildcard-import
|
|
14
|
+
|
|
15
|
+
from ._operations import ServicePatternsOperations # type: ignore
|
|
16
|
+
|
|
17
|
+
from ._patch import __all__ as _patch_all
|
|
18
|
+
from ._patch import *
|
|
19
|
+
from ._patch import patch_sdk as _patch_sdk
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ServicePatternsOperations",
|
|
23
|
+
]
|
|
24
|
+
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
|
|
25
|
+
_patch_sdk()
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
# --------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
5
|
+
# Code generated by Microsoft (R) Python Code Generator.
|
|
6
|
+
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
from azure.core import PipelineClient
|
|
9
|
+
|
|
10
|
+
from ..._configuration import AIProjectClientConfiguration
|
|
11
|
+
from ..._serialization import Deserializer, Serializer
|
|
12
|
+
from ..buildingblocks.operations._operations import ServicePatternsBuildingBlocksOperations
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ServicePatternsOperations:
|
|
16
|
+
"""
|
|
17
|
+
.. warning::
|
|
18
|
+
**DO NOT** instantiate this class directly.
|
|
19
|
+
|
|
20
|
+
Instead, you should access the following operations through
|
|
21
|
+
:class:`~azure.ai.projects.AIProjectClient`'s
|
|
22
|
+
:attr:`service_patterns` attribute.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, **kwargs):
|
|
26
|
+
input_args = list(args)
|
|
27
|
+
self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client")
|
|
28
|
+
self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config")
|
|
29
|
+
self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer")
|
|
30
|
+
self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer")
|
|
31
|
+
|
|
32
|
+
self.building_blocks = ServicePatternsBuildingBlocksOperations(
|
|
33
|
+
self._client, self._config, self._serialize, self._deserialize
|
|
34
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
"""Customize generated code here.
|
|
6
|
+
|
|
7
|
+
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
8
|
+
"""
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def patch_sdk():
|
|
15
|
+
"""Do not remove from this file.
|
|
16
|
+
|
|
17
|
+
`patch_sdk` is a last resort escape hatch that allows you to do customizations
|
|
18
|
+
you can't accomplish using the techniques described in
|
|
19
|
+
https://aka.ms/azsdk/python/dpcodegen/python/customize
|
|
20
|
+
"""
|
|
@@ -12,6 +12,8 @@ from ast import literal_eval
|
|
|
12
12
|
from typing import Dict, List, Optional, Union, cast
|
|
13
13
|
from urllib.parse import urlparse
|
|
14
14
|
from string import Template
|
|
15
|
+
from azure.ai.evaluation._common.onedp._client import AIProjectClient
|
|
16
|
+
from azure.core.exceptions import HttpResponseError
|
|
15
17
|
|
|
16
18
|
import jwt
|
|
17
19
|
|
|
@@ -19,6 +21,7 @@ from azure.ai.evaluation._legacy._adapters._errors import MissingRequiredPackage
|
|
|
19
21
|
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
20
22
|
from azure.ai.evaluation._http_utils import AsyncHttpPipeline, get_async_http_client
|
|
21
23
|
from azure.ai.evaluation._model_configurations import AzureAIProject
|
|
24
|
+
from azure.ai.evaluation._common.utils import is_onedp_project
|
|
22
25
|
from azure.core.credentials import TokenCredential
|
|
23
26
|
from azure.core.exceptions import HttpResponseError
|
|
24
27
|
from azure.core.pipeline.policies import AsyncRetryPolicy
|
|
@@ -41,6 +44,8 @@ USER_AGENT = "{}/{}".format("azure-ai-evaluation", version)
|
|
|
41
44
|
USER_TEXT_TEMPLATE_DICT: Dict[str, Template] = {
|
|
42
45
|
"DEFAULT": Template("<Human>{$query}</><System>{$response}</>"),
|
|
43
46
|
}
|
|
47
|
+
ML_WORKSPACE = "https://management.azure.com/.default"
|
|
48
|
+
COG_SRV_WORKSPACE = "https://ai.azure.com/.default"
|
|
44
49
|
|
|
45
50
|
INFERENCE_OF_SENSITIVE_ATTRIBUTES = "inference_sensitive_attributes"
|
|
46
51
|
|
|
@@ -99,11 +104,7 @@ def get_common_headers(token: str, evaluator_name: Optional[str] = None) -> Dict
|
|
|
99
104
|
user_agent = f"{USER_AGENT} (type=evaluator; subtype={evaluator_name})" if evaluator_name else USER_AGENT
|
|
100
105
|
return {
|
|
101
106
|
"Authorization": f"Bearer {token}",
|
|
102
|
-
"Content-Type": "application/json",
|
|
103
107
|
"User-Agent": user_agent,
|
|
104
|
-
# Handle "RuntimeError: Event loop is closed" from httpx AsyncClient
|
|
105
|
-
# https://github.com/encode/httpx/discussions/2959
|
|
106
|
-
"Connection": "close",
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
|
|
@@ -112,7 +113,31 @@ def get_async_http_client_with_timeout() -> AsyncHttpPipeline:
|
|
|
112
113
|
retry_policy=AsyncRetryPolicy(timeout=CommonConstants.DEFAULT_HTTP_TIMEOUT)
|
|
113
114
|
)
|
|
114
115
|
|
|
116
|
+
async def ensure_service_availability_onedp(client: AIProjectClient, token: str, capability: Optional[str] = None) -> None:
|
|
117
|
+
"""Check if the Responsible AI service is available in the region and has the required capability, if relevant.
|
|
115
118
|
|
|
119
|
+
:param client: The AI project client.
|
|
120
|
+
:type client: AIProjectClient
|
|
121
|
+
:param token: The Azure authentication token.
|
|
122
|
+
:type token: str
|
|
123
|
+
:param capability: The capability to check. Default is None.
|
|
124
|
+
:type capability: str
|
|
125
|
+
:raises Exception: If the service is not available in the region or the capability is not available.
|
|
126
|
+
"""
|
|
127
|
+
headers = get_common_headers(token)
|
|
128
|
+
capabilities = client.evaluations.check_annotation(headers=headers)
|
|
129
|
+
|
|
130
|
+
if capability and capability not in capabilities:
|
|
131
|
+
msg = f"The needed capability '{capability}' is not supported by the RAI service in this region."
|
|
132
|
+
raise EvaluationException(
|
|
133
|
+
message=msg,
|
|
134
|
+
internal_message=msg,
|
|
135
|
+
target=ErrorTarget.RAI_CLIENT,
|
|
136
|
+
category=ErrorCategory.SERVICE_UNAVAILABLE,
|
|
137
|
+
blame=ErrorBlame.USER_ERROR,
|
|
138
|
+
tsg_link="https://aka.ms/azsdk/python/evaluation/safetyevaluator/troubleshoot",
|
|
139
|
+
)
|
|
140
|
+
|
|
116
141
|
async def ensure_service_availability(rai_svc_url: str, token: str, capability: Optional[str] = None) -> None:
|
|
117
142
|
"""Check if the Responsible AI service is available in the region and has the required capability, if relevant.
|
|
118
143
|
|
|
@@ -231,6 +256,40 @@ async def submit_request(
|
|
|
231
256
|
return operation_id
|
|
232
257
|
|
|
233
258
|
|
|
259
|
+
async def submit_request_onedp(
|
|
260
|
+
client: AIProjectClient,
|
|
261
|
+
data: dict,
|
|
262
|
+
metric: str,
|
|
263
|
+
token: str,
|
|
264
|
+
annotation_task: str,
|
|
265
|
+
evaluator_name: str
|
|
266
|
+
) -> str:
|
|
267
|
+
"""Submit request to Responsible AI service for evaluation and return operation ID
|
|
268
|
+
|
|
269
|
+
:param client: The AI project client.
|
|
270
|
+
:type client: AIProjectClient
|
|
271
|
+
:param data: The data to evaluate.
|
|
272
|
+
:type data: dict
|
|
273
|
+
:param metric: The evaluation metric to use.
|
|
274
|
+
:type metric: str
|
|
275
|
+
:param token: The Azure authentication token.
|
|
276
|
+
:type token: str
|
|
277
|
+
:param annotation_task: The annotation task to use.
|
|
278
|
+
:type annotation_task: str
|
|
279
|
+
:param evaluator_name: The evaluator name.
|
|
280
|
+
:type evaluator_name: str
|
|
281
|
+
:return: The operation ID.
|
|
282
|
+
:rtype: str
|
|
283
|
+
"""
|
|
284
|
+
normalized_user_text = get_formatted_template(data, annotation_task)
|
|
285
|
+
payload = generate_payload(normalized_user_text, metric, annotation_task=annotation_task)
|
|
286
|
+
headers = get_common_headers(token, evaluator_name)
|
|
287
|
+
response = client.evaluations.submit_annotation(payload, headers=headers)
|
|
288
|
+
result = json.loads(response)
|
|
289
|
+
operation_id = result["location"].split("/")[-1]
|
|
290
|
+
return operation_id
|
|
291
|
+
|
|
292
|
+
|
|
234
293
|
async def fetch_result(operation_id: str, rai_svc_url: str, credential: TokenCredential, token: str) -> Dict:
|
|
235
294
|
"""Fetch the annotation result from Responsible AI service
|
|
236
295
|
|
|
@@ -267,6 +326,34 @@ async def fetch_result(operation_id: str, rai_svc_url: str, credential: TokenCre
|
|
|
267
326
|
sleep_time = RAIService.SLEEP_TIME**request_count
|
|
268
327
|
await asyncio.sleep(sleep_time)
|
|
269
328
|
|
|
329
|
+
async def fetch_result_onedp(client: AIProjectClient, operation_id: str, token: str) -> Dict:
|
|
330
|
+
"""Fetch the annotation result from Responsible AI service
|
|
331
|
+
|
|
332
|
+
:param client: The AI project client.
|
|
333
|
+
:type client: AIProjectClient
|
|
334
|
+
:param operation_id: The operation ID.
|
|
335
|
+
:type operation_id: str
|
|
336
|
+
:param token: The Azure authentication token.
|
|
337
|
+
:type token: str
|
|
338
|
+
:return: The annotation result.
|
|
339
|
+
:rtype: Dict
|
|
340
|
+
"""
|
|
341
|
+
start = time.time()
|
|
342
|
+
request_count = 0
|
|
343
|
+
|
|
344
|
+
while True:
|
|
345
|
+
headers = get_common_headers(token)
|
|
346
|
+
try:
|
|
347
|
+
return client.evaluations.operation_results(operation_id, headers=headers)
|
|
348
|
+
except HttpResponseError:
|
|
349
|
+
request_count += 1
|
|
350
|
+
time_elapsed = time.time() - start
|
|
351
|
+
if time_elapsed > RAIService.TIMEOUT:
|
|
352
|
+
raise TimeoutError(f"Fetching annotation result {request_count} times out after {time_elapsed:.2f} seconds")
|
|
353
|
+
|
|
354
|
+
sleep_time = RAIService.SLEEP_TIME**request_count
|
|
355
|
+
await asyncio.sleep(sleep_time)
|
|
356
|
+
|
|
270
357
|
def parse_response( # pylint: disable=too-many-branches,too-many-statements
|
|
271
358
|
batch_response: List[Dict], metric_name: str, metric_display_name: Optional[str] = None
|
|
272
359
|
) -> Dict[str, Union[str, float]]:
|
|
@@ -500,7 +587,7 @@ async def get_rai_svc_url(project_scope: AzureAIProject, token: str) -> str:
|
|
|
500
587
|
return rai_url
|
|
501
588
|
|
|
502
589
|
|
|
503
|
-
async def fetch_or_reuse_token(credential: TokenCredential, token: Optional[str] = None) -> str:
|
|
590
|
+
async def fetch_or_reuse_token(credential: TokenCredential, token: Optional[str] = None, workspace: Optional[str] = ML_WORKSPACE) -> str:
|
|
504
591
|
"""Get token. Fetch a new token if the current token is near expiry
|
|
505
592
|
|
|
506
593
|
:param credential: The Azure authentication credential.
|
|
@@ -524,13 +611,13 @@ async def fetch_or_reuse_token(credential: TokenCredential, token: Optional[str]
|
|
|
524
611
|
if (exp_time - current_time) >= 300:
|
|
525
612
|
return token
|
|
526
613
|
|
|
527
|
-
return credential.get_token(
|
|
614
|
+
return credential.get_token(workspace).token
|
|
528
615
|
|
|
529
616
|
|
|
530
617
|
async def evaluate_with_rai_service(
|
|
531
618
|
data: dict,
|
|
532
619
|
metric_name: str,
|
|
533
|
-
project_scope: AzureAIProject,
|
|
620
|
+
project_scope: Union[str, AzureAIProject],
|
|
534
621
|
credential: TokenCredential,
|
|
535
622
|
annotation_task: str = Tasks.CONTENT_HARM,
|
|
536
623
|
metric_display_name=None,
|
|
@@ -556,18 +643,26 @@ async def evaluate_with_rai_service(
|
|
|
556
643
|
:rtype: Dict[str, Union[str, float]]
|
|
557
644
|
"""
|
|
558
645
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
646
|
+
if is_onedp_project(project_scope):
|
|
647
|
+
client = AIProjectClient(endpoint=project_scope, credential=credential)
|
|
648
|
+
token = await fetch_or_reuse_token(credential=credential, workspace=COG_SRV_WORKSPACE)
|
|
649
|
+
await ensure_service_availability_onedp(client, token, annotation_task)
|
|
650
|
+
operation_id = await submit_request_onedp(client, data, metric_name, token, annotation_task, evaluator_name)
|
|
651
|
+
annotation_response = cast(List[Dict], await fetch_result_onedp(client, operation_id, token))
|
|
652
|
+
result = parse_response(annotation_response, metric_name, metric_display_name)
|
|
653
|
+
return result
|
|
654
|
+
else:
|
|
655
|
+
# Get RAI service URL from discovery service and check service availability
|
|
656
|
+
token = await fetch_or_reuse_token(credential)
|
|
657
|
+
rai_svc_url = await get_rai_svc_url(project_scope, token)
|
|
658
|
+
await ensure_service_availability(rai_svc_url, token, annotation_task)
|
|
568
659
|
|
|
569
|
-
|
|
660
|
+
# Submit annotation request and fetch result
|
|
661
|
+
operation_id = await submit_request(data, metric_name, rai_svc_url, token, annotation_task, evaluator_name)
|
|
662
|
+
annotation_response = cast(List[Dict], await fetch_result(operation_id, rai_svc_url, credential, token))
|
|
663
|
+
result = parse_response(annotation_response, metric_name, metric_display_name)
|
|
570
664
|
|
|
665
|
+
return result
|
|
571
666
|
|
|
572
667
|
def generate_payload_multimodal(content_type: str, messages, metric: str) -> Dict:
|
|
573
668
|
"""Generate the payload for the annotation request
|
|
@@ -600,7 +695,6 @@ def generate_payload_multimodal(content_type: str, messages, metric: str) -> Dic
|
|
|
600
695
|
"AnnotationTask": task,
|
|
601
696
|
}
|
|
602
697
|
|
|
603
|
-
|
|
604
698
|
async def submit_multimodal_request(messages, metric: str, rai_svc_url: str, token: str) -> str:
|
|
605
699
|
"""Submit request to Responsible AI service for evaluation and return operation ID
|
|
606
700
|
:param messages: The normalized list of messages to be entered as the "Contents" in the payload.
|
|
@@ -646,9 +740,37 @@ async def submit_multimodal_request(messages, metric: str, rai_svc_url: str, tok
|
|
|
646
740
|
operation_id = result["location"].split("/")[-1]
|
|
647
741
|
return operation_id
|
|
648
742
|
|
|
743
|
+
async def submit_multimodal_request_onedp(client: AIProjectClient, messages, metric: str, token: str) -> str:
|
|
744
|
+
|
|
745
|
+
# handle inference sdk strongly type messages
|
|
746
|
+
if len(messages) > 0 and not isinstance(messages[0], dict):
|
|
747
|
+
try:
|
|
748
|
+
from azure.ai.inference.models import ChatRequestMessage
|
|
749
|
+
except ImportError as ex:
|
|
750
|
+
error_message = (
|
|
751
|
+
"Please install 'azure-ai-inference' package to use SystemMessage, UserMessage, AssistantMessage"
|
|
752
|
+
)
|
|
753
|
+
raise MissingRequiredPackage(message=error_message) from ex
|
|
754
|
+
if len(messages) > 0 and isinstance(messages[0], ChatRequestMessage):
|
|
755
|
+
messages = [message.as_dict() for message in messages]
|
|
756
|
+
|
|
757
|
+
## fetch system and assistant messages from the list of messages
|
|
758
|
+
filtered_messages = [message for message in messages if message["role"] != "system"]
|
|
759
|
+
assistant_messages = [message for message in messages if message["role"] == "assistant"]
|
|
760
|
+
|
|
761
|
+
## prepare for request
|
|
762
|
+
content_type = retrieve_content_type(assistant_messages, metric)
|
|
763
|
+
payload = generate_payload_multimodal(content_type, filtered_messages, metric)
|
|
764
|
+
headers = get_common_headers(token)
|
|
765
|
+
|
|
766
|
+
response = client.evaluations.submit_annotation(payload, headers=headers)
|
|
767
|
+
|
|
768
|
+
result = json.loads(response)
|
|
769
|
+
operation_id = result["location"].split("/")[-1]
|
|
770
|
+
return operation_id
|
|
649
771
|
|
|
650
772
|
async def evaluate_with_rai_service_multimodal(
|
|
651
|
-
messages, metric_name: str, project_scope: AzureAIProject, credential: TokenCredential
|
|
773
|
+
messages, metric_name: str, project_scope: Union[str, AzureAIProject], credential: TokenCredential
|
|
652
774
|
):
|
|
653
775
|
""" "Evaluate the content safety of the response using Responsible AI service
|
|
654
776
|
:param messages: The normalized list of messages.
|
|
@@ -664,12 +786,20 @@ async def evaluate_with_rai_service_multimodal(
|
|
|
664
786
|
:rtype: List[List[Dict]]
|
|
665
787
|
"""
|
|
666
788
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
789
|
+
if is_onedp_project(project_scope):
|
|
790
|
+
client = AIProjectClient(endpoint=project_scope, credential=credential)
|
|
791
|
+
token = await fetch_or_reuse_token(credential=credential, workspace=COG_SRV_WORKSPACE)
|
|
792
|
+
await ensure_service_availability_onedp(client, token, Tasks.CONTENT_HARM)
|
|
793
|
+
operation_id = await submit_multimodal_request_onedp(client, messages, metric_name, token)
|
|
794
|
+
annotation_response = cast(List[Dict], await fetch_result_onedp(client, operation_id, token))
|
|
795
|
+
result = parse_response(annotation_response, metric_name)
|
|
796
|
+
return result
|
|
797
|
+
else:
|
|
798
|
+
token = await fetch_or_reuse_token(credential)
|
|
799
|
+
rai_svc_url = await get_rai_svc_url(project_scope, token)
|
|
800
|
+
await ensure_service_availability(rai_svc_url, token, Tasks.CONTENT_HARM)
|
|
801
|
+
# Submit annotation request and fetch result
|
|
802
|
+
operation_id = await submit_multimodal_request(messages, metric_name, rai_svc_url, token)
|
|
803
|
+
annotation_response = cast(List[Dict], await fetch_result(operation_id, rai_svc_url, credential, token))
|
|
804
|
+
result = parse_response(annotation_response, metric_name)
|
|
805
|
+
return result
|