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.

Files changed (123) hide show
  1. azure/ai/evaluation/__init__.py +9 -0
  2. azure/ai/evaluation/_aoai/__init__.py +10 -0
  3. azure/ai/evaluation/_aoai/aoai_grader.py +89 -0
  4. azure/ai/evaluation/_aoai/label_grader.py +66 -0
  5. azure/ai/evaluation/_aoai/string_check_grader.py +65 -0
  6. azure/ai/evaluation/_aoai/text_similarity_grader.py +88 -0
  7. azure/ai/evaluation/_azure/_clients.py +4 -4
  8. azure/ai/evaluation/_azure/_envs.py +208 -0
  9. azure/ai/evaluation/_azure/_token_manager.py +12 -7
  10. azure/ai/evaluation/_common/__init__.py +5 -0
  11. azure/ai/evaluation/_common/evaluation_onedp_client.py +118 -0
  12. azure/ai/evaluation/_common/onedp/__init__.py +32 -0
  13. azure/ai/evaluation/_common/onedp/_client.py +139 -0
  14. azure/ai/evaluation/_common/onedp/_configuration.py +73 -0
  15. azure/ai/evaluation/_common/onedp/_model_base.py +1232 -0
  16. azure/ai/evaluation/_common/onedp/_patch.py +21 -0
  17. azure/ai/evaluation/_common/onedp/_serialization.py +2032 -0
  18. azure/ai/evaluation/_common/onedp/_types.py +21 -0
  19. azure/ai/evaluation/_common/onedp/_validation.py +50 -0
  20. azure/ai/evaluation/_common/onedp/_vendor.py +50 -0
  21. azure/ai/evaluation/_common/onedp/_version.py +9 -0
  22. azure/ai/evaluation/_common/onedp/aio/__init__.py +29 -0
  23. azure/ai/evaluation/_common/onedp/aio/_client.py +143 -0
  24. azure/ai/evaluation/_common/onedp/aio/_configuration.py +75 -0
  25. azure/ai/evaluation/_common/onedp/aio/_patch.py +21 -0
  26. azure/ai/evaluation/_common/onedp/aio/_vendor.py +40 -0
  27. azure/ai/evaluation/_common/onedp/aio/operations/__init__.py +39 -0
  28. azure/ai/evaluation/_common/onedp/aio/operations/_operations.py +4494 -0
  29. azure/ai/evaluation/_common/onedp/aio/operations/_patch.py +21 -0
  30. azure/ai/evaluation/_common/onedp/models/__init__.py +142 -0
  31. azure/ai/evaluation/_common/onedp/models/_enums.py +162 -0
  32. azure/ai/evaluation/_common/onedp/models/_models.py +2228 -0
  33. azure/ai/evaluation/_common/onedp/models/_patch.py +21 -0
  34. azure/ai/evaluation/_common/onedp/operations/__init__.py +39 -0
  35. azure/ai/evaluation/_common/onedp/operations/_operations.py +5655 -0
  36. azure/ai/evaluation/_common/onedp/operations/_patch.py +21 -0
  37. azure/ai/evaluation/_common/onedp/py.typed +1 -0
  38. azure/ai/evaluation/_common/onedp/servicepatterns/__init__.py +1 -0
  39. azure/ai/evaluation/_common/onedp/servicepatterns/aio/__init__.py +1 -0
  40. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/__init__.py +25 -0
  41. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_operations.py +34 -0
  42. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_patch.py +20 -0
  43. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/__init__.py +1 -0
  44. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/__init__.py +1 -0
  45. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/__init__.py +22 -0
  46. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_operations.py +29 -0
  47. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_patch.py +20 -0
  48. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/__init__.py +22 -0
  49. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_operations.py +29 -0
  50. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_patch.py +20 -0
  51. azure/ai/evaluation/_common/onedp/servicepatterns/operations/__init__.py +25 -0
  52. azure/ai/evaluation/_common/onedp/servicepatterns/operations/_operations.py +34 -0
  53. azure/ai/evaluation/_common/onedp/servicepatterns/operations/_patch.py +20 -0
  54. azure/ai/evaluation/_common/rai_service.py +158 -28
  55. azure/ai/evaluation/_common/raiclient/_version.py +1 -1
  56. azure/ai/evaluation/_common/utils.py +79 -1
  57. azure/ai/evaluation/_constants.py +16 -0
  58. azure/ai/evaluation/_eval_mapping.py +71 -0
  59. azure/ai/evaluation/_evaluate/_batch_run/_run_submitter_client.py +30 -16
  60. azure/ai/evaluation/_evaluate/_batch_run/eval_run_context.py +8 -0
  61. azure/ai/evaluation/_evaluate/_batch_run/proxy_client.py +5 -0
  62. azure/ai/evaluation/_evaluate/_batch_run/target_run_context.py +17 -1
  63. azure/ai/evaluation/_evaluate/_eval_run.py +1 -1
  64. azure/ai/evaluation/_evaluate/_evaluate.py +325 -74
  65. azure/ai/evaluation/_evaluate/_evaluate_aoai.py +534 -0
  66. azure/ai/evaluation/_evaluate/_utils.py +117 -4
  67. azure/ai/evaluation/_evaluators/_common/_base_eval.py +8 -3
  68. azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +12 -3
  69. azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +2 -2
  70. azure/ai/evaluation/_evaluators/_document_retrieval/__init__.py +11 -0
  71. azure/ai/evaluation/_evaluators/_document_retrieval/_document_retrieval.py +467 -0
  72. azure/ai/evaluation/_evaluators/_fluency/_fluency.py +1 -1
  73. azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +1 -1
  74. azure/ai/evaluation/_evaluators/_intent_resolution/_intent_resolution.py +6 -2
  75. azure/ai/evaluation/_evaluators/_relevance/_relevance.py +1 -1
  76. azure/ai/evaluation/_evaluators/_response_completeness/_response_completeness.py +7 -2
  77. azure/ai/evaluation/_evaluators/_response_completeness/response_completeness.prompty +31 -46
  78. azure/ai/evaluation/_evaluators/_similarity/_similarity.py +1 -1
  79. azure/ai/evaluation/_evaluators/_task_adherence/_task_adherence.py +5 -2
  80. azure/ai/evaluation/_evaluators/_tool_call_accuracy/_tool_call_accuracy.py +6 -2
  81. azure/ai/evaluation/_exceptions.py +2 -0
  82. azure/ai/evaluation/_legacy/_adapters/__init__.py +0 -14
  83. azure/ai/evaluation/_legacy/_adapters/_check.py +17 -0
  84. azure/ai/evaluation/_legacy/_adapters/_flows.py +1 -1
  85. azure/ai/evaluation/_legacy/_batch_engine/_engine.py +51 -32
  86. azure/ai/evaluation/_legacy/_batch_engine/_openai_injector.py +114 -8
  87. azure/ai/evaluation/_legacy/_batch_engine/_result.py +6 -0
  88. azure/ai/evaluation/_legacy/_batch_engine/_run.py +6 -0
  89. azure/ai/evaluation/_legacy/_batch_engine/_run_submitter.py +69 -29
  90. azure/ai/evaluation/_legacy/_batch_engine/_trace.py +54 -62
  91. azure/ai/evaluation/_legacy/_batch_engine/_utils.py +19 -1
  92. azure/ai/evaluation/_legacy/_common/__init__.py +3 -0
  93. azure/ai/evaluation/_legacy/_common/_async_token_provider.py +124 -0
  94. azure/ai/evaluation/_legacy/_common/_thread_pool_executor_with_context.py +15 -0
  95. azure/ai/evaluation/_legacy/prompty/_connection.py +11 -74
  96. azure/ai/evaluation/_legacy/prompty/_exceptions.py +80 -0
  97. azure/ai/evaluation/_legacy/prompty/_prompty.py +119 -9
  98. azure/ai/evaluation/_legacy/prompty/_utils.py +72 -2
  99. azure/ai/evaluation/_safety_evaluation/_safety_evaluation.py +90 -17
  100. azure/ai/evaluation/_version.py +1 -1
  101. azure/ai/evaluation/red_team/_attack_strategy.py +1 -1
  102. azure/ai/evaluation/red_team/_red_team.py +825 -450
  103. azure/ai/evaluation/red_team/_utils/metric_mapping.py +23 -0
  104. azure/ai/evaluation/red_team/_utils/strategy_utils.py +1 -1
  105. azure/ai/evaluation/simulator/_adversarial_simulator.py +63 -39
  106. azure/ai/evaluation/simulator/_constants.py +1 -0
  107. azure/ai/evaluation/simulator/_conversation/__init__.py +13 -6
  108. azure/ai/evaluation/simulator/_conversation/_conversation.py +2 -1
  109. azure/ai/evaluation/simulator/_direct_attack_simulator.py +35 -22
  110. azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +1 -0
  111. azure/ai/evaluation/simulator/_indirect_attack_simulator.py +40 -25
  112. azure/ai/evaluation/simulator/_model_tools/__init__.py +2 -1
  113. azure/ai/evaluation/simulator/_model_tools/_generated_rai_client.py +24 -18
  114. azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +5 -10
  115. azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +65 -41
  116. azure/ai/evaluation/simulator/_model_tools/_template_handler.py +9 -5
  117. azure/ai/evaluation/simulator/_model_tools/models.py +20 -17
  118. {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/METADATA +25 -2
  119. {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/RECORD +123 -65
  120. /azure/ai/evaluation/_legacy/{_batch_engine → _common}/_logging.py +0 -0
  121. {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/NOTICE.txt +0 -0
  122. {azure_ai_evaluation-1.5.0.dist-info → azure_ai_evaluation-1.6.0.dist-info}/WHEEL +0 -0
  123. {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()
@@ -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("https://management.azure.com/.default").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
- # Get RAI service URL from discovery service and check service availability
560
- token = await fetch_or_reuse_token(credential)
561
- rai_svc_url = await get_rai_svc_url(project_scope, token)
562
- await ensure_service_availability(rai_svc_url, token, annotation_task)
563
-
564
- # Submit annotation request and fetch result
565
- operation_id = await submit_request(data, metric_name, rai_svc_url, token, annotation_task, evaluator_name)
566
- annotation_response = cast(List[Dict], await fetch_result(operation_id, rai_svc_url, credential, token))
567
- result = parse_response(annotation_response, metric_name, metric_display_name)
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
- return result
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
- # Get RAI service URL from discovery service and check service availability
668
- token = await fetch_or_reuse_token(credential)
669
- rai_svc_url = await get_rai_svc_url(project_scope, token)
670
- await ensure_service_availability(rai_svc_url, token, Tasks.CONTENT_HARM)
671
- # Submit annotation request and fetch result
672
- operation_id = await submit_multimodal_request(messages, metric_name, rai_svc_url, token)
673
- annotation_response = cast(List[Dict], await fetch_result(operation_id, rai_svc_url, credential, token))
674
- result = parse_response(annotation_response, metric_name)
675
- return result
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
@@ -6,4 +6,4 @@
6
6
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
7
7
  # --------------------------------------------------------------------------
8
8
 
9
- VERSION = "1.0.0b1"
9
+ VERSION = "1.6.0"