azure-ai-evaluation 1.0.1__py3-none-any.whl → 1.13.5__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 (277) hide show
  1. azure/ai/evaluation/__init__.py +85 -14
  2. azure/ai/evaluation/_aoai/__init__.py +10 -0
  3. azure/ai/evaluation/_aoai/aoai_grader.py +140 -0
  4. azure/ai/evaluation/_aoai/label_grader.py +68 -0
  5. azure/ai/evaluation/_aoai/python_grader.py +86 -0
  6. azure/ai/evaluation/_aoai/score_model_grader.py +94 -0
  7. azure/ai/evaluation/_aoai/string_check_grader.py +66 -0
  8. azure/ai/evaluation/_aoai/text_similarity_grader.py +80 -0
  9. azure/ai/evaluation/_azure/__init__.py +3 -0
  10. azure/ai/evaluation/_azure/_clients.py +204 -0
  11. azure/ai/evaluation/_azure/_envs.py +207 -0
  12. azure/ai/evaluation/_azure/_models.py +227 -0
  13. azure/ai/evaluation/_azure/_token_manager.py +129 -0
  14. azure/ai/evaluation/_common/__init__.py +9 -1
  15. azure/ai/evaluation/_common/constants.py +124 -2
  16. azure/ai/evaluation/_common/evaluation_onedp_client.py +169 -0
  17. azure/ai/evaluation/_common/onedp/__init__.py +32 -0
  18. azure/ai/evaluation/_common/onedp/_client.py +166 -0
  19. azure/ai/evaluation/_common/onedp/_configuration.py +72 -0
  20. azure/ai/evaluation/_common/onedp/_model_base.py +1232 -0
  21. azure/ai/evaluation/_common/onedp/_patch.py +21 -0
  22. azure/ai/evaluation/_common/onedp/_serialization.py +2032 -0
  23. azure/ai/evaluation/_common/onedp/_types.py +21 -0
  24. azure/ai/evaluation/_common/onedp/_utils/__init__.py +6 -0
  25. azure/ai/evaluation/_common/onedp/_utils/model_base.py +1232 -0
  26. azure/ai/evaluation/_common/onedp/_utils/serialization.py +2032 -0
  27. azure/ai/evaluation/_common/onedp/_validation.py +66 -0
  28. azure/ai/evaluation/_common/onedp/_vendor.py +50 -0
  29. azure/ai/evaluation/_common/onedp/_version.py +9 -0
  30. azure/ai/evaluation/_common/onedp/aio/__init__.py +29 -0
  31. azure/ai/evaluation/_common/onedp/aio/_client.py +168 -0
  32. azure/ai/evaluation/_common/onedp/aio/_configuration.py +72 -0
  33. azure/ai/evaluation/_common/onedp/aio/_patch.py +21 -0
  34. azure/ai/evaluation/_common/onedp/aio/operations/__init__.py +49 -0
  35. azure/ai/evaluation/_common/onedp/aio/operations/_operations.py +7143 -0
  36. azure/ai/evaluation/_common/onedp/aio/operations/_patch.py +21 -0
  37. azure/ai/evaluation/_common/onedp/models/__init__.py +358 -0
  38. azure/ai/evaluation/_common/onedp/models/_enums.py +447 -0
  39. azure/ai/evaluation/_common/onedp/models/_models.py +5963 -0
  40. azure/ai/evaluation/_common/onedp/models/_patch.py +21 -0
  41. azure/ai/evaluation/_common/onedp/operations/__init__.py +49 -0
  42. azure/ai/evaluation/_common/onedp/operations/_operations.py +8951 -0
  43. azure/ai/evaluation/_common/onedp/operations/_patch.py +21 -0
  44. azure/ai/evaluation/_common/onedp/py.typed +1 -0
  45. azure/ai/evaluation/_common/onedp/servicepatterns/__init__.py +1 -0
  46. azure/ai/evaluation/_common/onedp/servicepatterns/aio/__init__.py +1 -0
  47. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/__init__.py +25 -0
  48. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_operations.py +34 -0
  49. azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_patch.py +20 -0
  50. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/__init__.py +1 -0
  51. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/__init__.py +1 -0
  52. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/__init__.py +22 -0
  53. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_operations.py +29 -0
  54. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_patch.py +20 -0
  55. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/__init__.py +22 -0
  56. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_operations.py +29 -0
  57. azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_patch.py +20 -0
  58. azure/ai/evaluation/_common/onedp/servicepatterns/operations/__init__.py +25 -0
  59. azure/ai/evaluation/_common/onedp/servicepatterns/operations/_operations.py +34 -0
  60. azure/ai/evaluation/_common/onedp/servicepatterns/operations/_patch.py +20 -0
  61. azure/ai/evaluation/_common/rai_service.py +578 -69
  62. azure/ai/evaluation/_common/raiclient/__init__.py +34 -0
  63. azure/ai/evaluation/_common/raiclient/_client.py +128 -0
  64. azure/ai/evaluation/_common/raiclient/_configuration.py +87 -0
  65. azure/ai/evaluation/_common/raiclient/_model_base.py +1235 -0
  66. azure/ai/evaluation/_common/raiclient/_patch.py +20 -0
  67. azure/ai/evaluation/_common/raiclient/_serialization.py +2050 -0
  68. azure/ai/evaluation/_common/raiclient/_version.py +9 -0
  69. azure/ai/evaluation/_common/raiclient/aio/__init__.py +29 -0
  70. azure/ai/evaluation/_common/raiclient/aio/_client.py +130 -0
  71. azure/ai/evaluation/_common/raiclient/aio/_configuration.py +87 -0
  72. azure/ai/evaluation/_common/raiclient/aio/_patch.py +20 -0
  73. azure/ai/evaluation/_common/raiclient/aio/operations/__init__.py +25 -0
  74. azure/ai/evaluation/_common/raiclient/aio/operations/_operations.py +981 -0
  75. azure/ai/evaluation/_common/raiclient/aio/operations/_patch.py +20 -0
  76. azure/ai/evaluation/_common/raiclient/models/__init__.py +60 -0
  77. azure/ai/evaluation/_common/raiclient/models/_enums.py +18 -0
  78. azure/ai/evaluation/_common/raiclient/models/_models.py +651 -0
  79. azure/ai/evaluation/_common/raiclient/models/_patch.py +20 -0
  80. azure/ai/evaluation/_common/raiclient/operations/__init__.py +25 -0
  81. azure/ai/evaluation/_common/raiclient/operations/_operations.py +1238 -0
  82. azure/ai/evaluation/_common/raiclient/operations/_patch.py +20 -0
  83. azure/ai/evaluation/_common/raiclient/py.typed +1 -0
  84. azure/ai/evaluation/_common/utils.py +505 -27
  85. azure/ai/evaluation/_constants.py +147 -0
  86. azure/ai/evaluation/_converters/__init__.py +3 -0
  87. azure/ai/evaluation/_converters/_ai_services.py +899 -0
  88. azure/ai/evaluation/_converters/_models.py +467 -0
  89. azure/ai/evaluation/_converters/_sk_services.py +495 -0
  90. azure/ai/evaluation/_eval_mapping.py +87 -0
  91. azure/ai/evaluation/_evaluate/_batch_run/__init__.py +10 -2
  92. azure/ai/evaluation/_evaluate/_batch_run/_run_submitter_client.py +176 -0
  93. azure/ai/evaluation/_evaluate/_batch_run/batch_clients.py +82 -0
  94. azure/ai/evaluation/_evaluate/_batch_run/code_client.py +18 -12
  95. azure/ai/evaluation/_evaluate/_batch_run/eval_run_context.py +19 -6
  96. azure/ai/evaluation/_evaluate/_batch_run/proxy_client.py +47 -22
  97. azure/ai/evaluation/_evaluate/_batch_run/target_run_context.py +18 -2
  98. azure/ai/evaluation/_evaluate/_eval_run.py +32 -46
  99. azure/ai/evaluation/_evaluate/_evaluate.py +1809 -142
  100. azure/ai/evaluation/_evaluate/_evaluate_aoai.py +992 -0
  101. azure/ai/evaluation/_evaluate/_telemetry/__init__.py +5 -90
  102. azure/ai/evaluation/_evaluate/_utils.py +237 -42
  103. azure/ai/evaluation/_evaluator_definition.py +76 -0
  104. azure/ai/evaluation/_evaluators/_bleu/_bleu.py +80 -28
  105. azure/ai/evaluation/_evaluators/_code_vulnerability/__init__.py +5 -0
  106. azure/ai/evaluation/_evaluators/_code_vulnerability/_code_vulnerability.py +119 -0
  107. azure/ai/evaluation/_evaluators/_coherence/_coherence.py +40 -4
  108. azure/ai/evaluation/_evaluators/_common/__init__.py +2 -0
  109. azure/ai/evaluation/_evaluators/_common/_base_eval.py +430 -29
  110. azure/ai/evaluation/_evaluators/_common/_base_multi_eval.py +63 -0
  111. azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +269 -12
  112. azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +74 -9
  113. azure/ai/evaluation/_evaluators/_common/_conversation_aggregators.py +49 -0
  114. azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +73 -53
  115. azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +35 -5
  116. azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +26 -5
  117. azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +35 -5
  118. azure/ai/evaluation/_evaluators/_content_safety/_violence.py +34 -4
  119. azure/ai/evaluation/_evaluators/_document_retrieval/__init__.py +7 -0
  120. azure/ai/evaluation/_evaluators/_document_retrieval/_document_retrieval.py +442 -0
  121. azure/ai/evaluation/_evaluators/_eci/_eci.py +6 -3
  122. azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +97 -70
  123. azure/ai/evaluation/_evaluators/_fluency/_fluency.py +39 -3
  124. azure/ai/evaluation/_evaluators/_gleu/_gleu.py +80 -25
  125. azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +230 -20
  126. azure/ai/evaluation/_evaluators/_groundedness/groundedness_with_query.prompty +30 -29
  127. azure/ai/evaluation/_evaluators/_groundedness/groundedness_without_query.prompty +19 -14
  128. azure/ai/evaluation/_evaluators/_intent_resolution/__init__.py +7 -0
  129. azure/ai/evaluation/_evaluators/_intent_resolution/_intent_resolution.py +196 -0
  130. azure/ai/evaluation/_evaluators/_intent_resolution/intent_resolution.prompty +275 -0
  131. azure/ai/evaluation/_evaluators/_meteor/_meteor.py +89 -36
  132. azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +22 -4
  133. azure/ai/evaluation/_evaluators/_qa/_qa.py +94 -35
  134. azure/ai/evaluation/_evaluators/_relevance/_relevance.py +100 -4
  135. azure/ai/evaluation/_evaluators/_relevance/relevance.prompty +154 -56
  136. azure/ai/evaluation/_evaluators/_response_completeness/__init__.py +7 -0
  137. azure/ai/evaluation/_evaluators/_response_completeness/_response_completeness.py +202 -0
  138. azure/ai/evaluation/_evaluators/_response_completeness/response_completeness.prompty +84 -0
  139. azure/ai/evaluation/_evaluators/_retrieval/_retrieval.py +39 -3
  140. azure/ai/evaluation/_evaluators/_rouge/_rouge.py +166 -26
  141. azure/ai/evaluation/_evaluators/_service_groundedness/_service_groundedness.py +38 -7
  142. azure/ai/evaluation/_evaluators/_similarity/_similarity.py +81 -85
  143. azure/ai/evaluation/_evaluators/_task_adherence/__init__.py +7 -0
  144. azure/ai/evaluation/_evaluators/_task_adherence/_task_adherence.py +226 -0
  145. azure/ai/evaluation/_evaluators/_task_adherence/task_adherence.prompty +101 -0
  146. azure/ai/evaluation/_evaluators/_task_completion/__init__.py +7 -0
  147. azure/ai/evaluation/_evaluators/_task_completion/_task_completion.py +177 -0
  148. azure/ai/evaluation/_evaluators/_task_completion/task_completion.prompty +220 -0
  149. azure/ai/evaluation/_evaluators/_task_navigation_efficiency/__init__.py +7 -0
  150. azure/ai/evaluation/_evaluators/_task_navigation_efficiency/_task_navigation_efficiency.py +384 -0
  151. azure/ai/evaluation/_evaluators/_tool_call_accuracy/__init__.py +9 -0
  152. azure/ai/evaluation/_evaluators/_tool_call_accuracy/_tool_call_accuracy.py +298 -0
  153. azure/ai/evaluation/_evaluators/_tool_call_accuracy/tool_call_accuracy.prompty +166 -0
  154. azure/ai/evaluation/_evaluators/_tool_call_success/__init__.py +7 -0
  155. azure/ai/evaluation/_evaluators/_tool_call_success/_tool_call_success.py +306 -0
  156. azure/ai/evaluation/_evaluators/_tool_call_success/tool_call_success.prompty +321 -0
  157. azure/ai/evaluation/_evaluators/_tool_input_accuracy/__init__.py +9 -0
  158. azure/ai/evaluation/_evaluators/_tool_input_accuracy/_tool_input_accuracy.py +263 -0
  159. azure/ai/evaluation/_evaluators/_tool_input_accuracy/tool_input_accuracy.prompty +76 -0
  160. azure/ai/evaluation/_evaluators/_tool_output_utilization/__init__.py +7 -0
  161. azure/ai/evaluation/_evaluators/_tool_output_utilization/_tool_output_utilization.py +225 -0
  162. azure/ai/evaluation/_evaluators/_tool_output_utilization/tool_output_utilization.prompty +221 -0
  163. azure/ai/evaluation/_evaluators/_tool_selection/__init__.py +9 -0
  164. azure/ai/evaluation/_evaluators/_tool_selection/_tool_selection.py +266 -0
  165. azure/ai/evaluation/_evaluators/_tool_selection/tool_selection.prompty +104 -0
  166. azure/ai/evaluation/_evaluators/_ungrounded_attributes/__init__.py +5 -0
  167. azure/ai/evaluation/_evaluators/_ungrounded_attributes/_ungrounded_attributes.py +102 -0
  168. azure/ai/evaluation/_evaluators/_xpia/xpia.py +20 -4
  169. azure/ai/evaluation/_exceptions.py +24 -1
  170. azure/ai/evaluation/_http_utils.py +7 -5
  171. azure/ai/evaluation/_legacy/__init__.py +3 -0
  172. azure/ai/evaluation/_legacy/_adapters/__init__.py +7 -0
  173. azure/ai/evaluation/_legacy/_adapters/_check.py +17 -0
  174. azure/ai/evaluation/_legacy/_adapters/_configuration.py +45 -0
  175. azure/ai/evaluation/_legacy/_adapters/_constants.py +10 -0
  176. azure/ai/evaluation/_legacy/_adapters/_errors.py +29 -0
  177. azure/ai/evaluation/_legacy/_adapters/_flows.py +28 -0
  178. azure/ai/evaluation/_legacy/_adapters/_service.py +16 -0
  179. azure/ai/evaluation/_legacy/_adapters/client.py +51 -0
  180. azure/ai/evaluation/_legacy/_adapters/entities.py +26 -0
  181. azure/ai/evaluation/_legacy/_adapters/tracing.py +28 -0
  182. azure/ai/evaluation/_legacy/_adapters/types.py +15 -0
  183. azure/ai/evaluation/_legacy/_adapters/utils.py +31 -0
  184. azure/ai/evaluation/_legacy/_batch_engine/__init__.py +9 -0
  185. azure/ai/evaluation/_legacy/_batch_engine/_config.py +48 -0
  186. azure/ai/evaluation/_legacy/_batch_engine/_engine.py +477 -0
  187. azure/ai/evaluation/_legacy/_batch_engine/_exceptions.py +88 -0
  188. azure/ai/evaluation/_legacy/_batch_engine/_openai_injector.py +132 -0
  189. azure/ai/evaluation/_legacy/_batch_engine/_result.py +107 -0
  190. azure/ai/evaluation/_legacy/_batch_engine/_run.py +127 -0
  191. azure/ai/evaluation/_legacy/_batch_engine/_run_storage.py +128 -0
  192. azure/ai/evaluation/_legacy/_batch_engine/_run_submitter.py +262 -0
  193. azure/ai/evaluation/_legacy/_batch_engine/_status.py +25 -0
  194. azure/ai/evaluation/_legacy/_batch_engine/_trace.py +97 -0
  195. azure/ai/evaluation/_legacy/_batch_engine/_utils.py +97 -0
  196. azure/ai/evaluation/_legacy/_batch_engine/_utils_deprecated.py +131 -0
  197. azure/ai/evaluation/_legacy/_common/__init__.py +3 -0
  198. azure/ai/evaluation/_legacy/_common/_async_token_provider.py +117 -0
  199. azure/ai/evaluation/_legacy/_common/_logging.py +292 -0
  200. azure/ai/evaluation/_legacy/_common/_thread_pool_executor_with_context.py +17 -0
  201. azure/ai/evaluation/_legacy/prompty/__init__.py +36 -0
  202. azure/ai/evaluation/_legacy/prompty/_connection.py +119 -0
  203. azure/ai/evaluation/_legacy/prompty/_exceptions.py +139 -0
  204. azure/ai/evaluation/_legacy/prompty/_prompty.py +430 -0
  205. azure/ai/evaluation/_legacy/prompty/_utils.py +663 -0
  206. azure/ai/evaluation/_legacy/prompty/_yaml_utils.py +99 -0
  207. azure/ai/evaluation/_model_configurations.py +26 -0
  208. azure/ai/evaluation/_safety_evaluation/__init__.py +3 -0
  209. azure/ai/evaluation/_safety_evaluation/_generated_rai_client.py +0 -0
  210. azure/ai/evaluation/_safety_evaluation/_safety_evaluation.py +917 -0
  211. azure/ai/evaluation/_user_agent.py +32 -1
  212. azure/ai/evaluation/_vendor/rouge_score/rouge_scorer.py +0 -4
  213. azure/ai/evaluation/_vendor/rouge_score/scoring.py +0 -4
  214. azure/ai/evaluation/_vendor/rouge_score/tokenize.py +0 -4
  215. azure/ai/evaluation/_version.py +2 -1
  216. azure/ai/evaluation/red_team/__init__.py +22 -0
  217. azure/ai/evaluation/red_team/_agent/__init__.py +3 -0
  218. azure/ai/evaluation/red_team/_agent/_agent_functions.py +261 -0
  219. azure/ai/evaluation/red_team/_agent/_agent_tools.py +461 -0
  220. azure/ai/evaluation/red_team/_agent/_agent_utils.py +89 -0
  221. azure/ai/evaluation/red_team/_agent/_semantic_kernel_plugin.py +228 -0
  222. azure/ai/evaluation/red_team/_attack_objective_generator.py +268 -0
  223. azure/ai/evaluation/red_team/_attack_strategy.py +49 -0
  224. azure/ai/evaluation/red_team/_callback_chat_target.py +115 -0
  225. azure/ai/evaluation/red_team/_default_converter.py +21 -0
  226. azure/ai/evaluation/red_team/_evaluation_processor.py +505 -0
  227. azure/ai/evaluation/red_team/_mlflow_integration.py +430 -0
  228. azure/ai/evaluation/red_team/_orchestrator_manager.py +803 -0
  229. azure/ai/evaluation/red_team/_red_team.py +1717 -0
  230. azure/ai/evaluation/red_team/_red_team_result.py +661 -0
  231. azure/ai/evaluation/red_team/_result_processor.py +1708 -0
  232. azure/ai/evaluation/red_team/_utils/__init__.py +37 -0
  233. azure/ai/evaluation/red_team/_utils/_rai_service_eval_chat_target.py +128 -0
  234. azure/ai/evaluation/red_team/_utils/_rai_service_target.py +601 -0
  235. azure/ai/evaluation/red_team/_utils/_rai_service_true_false_scorer.py +114 -0
  236. azure/ai/evaluation/red_team/_utils/constants.py +72 -0
  237. azure/ai/evaluation/red_team/_utils/exception_utils.py +345 -0
  238. azure/ai/evaluation/red_team/_utils/file_utils.py +266 -0
  239. azure/ai/evaluation/red_team/_utils/formatting_utils.py +365 -0
  240. azure/ai/evaluation/red_team/_utils/logging_utils.py +139 -0
  241. azure/ai/evaluation/red_team/_utils/metric_mapping.py +73 -0
  242. azure/ai/evaluation/red_team/_utils/objective_utils.py +46 -0
  243. azure/ai/evaluation/red_team/_utils/progress_utils.py +252 -0
  244. azure/ai/evaluation/red_team/_utils/retry_utils.py +218 -0
  245. azure/ai/evaluation/red_team/_utils/strategy_utils.py +218 -0
  246. azure/ai/evaluation/simulator/_adversarial_scenario.py +6 -0
  247. azure/ai/evaluation/simulator/_adversarial_simulator.py +187 -80
  248. azure/ai/evaluation/simulator/_constants.py +1 -0
  249. azure/ai/evaluation/simulator/_conversation/__init__.py +138 -11
  250. azure/ai/evaluation/simulator/_conversation/_conversation.py +6 -2
  251. azure/ai/evaluation/simulator/_conversation/constants.py +1 -1
  252. azure/ai/evaluation/simulator/_direct_attack_simulator.py +37 -24
  253. azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +1 -0
  254. azure/ai/evaluation/simulator/_indirect_attack_simulator.py +56 -28
  255. azure/ai/evaluation/simulator/_model_tools/__init__.py +2 -1
  256. azure/ai/evaluation/simulator/_model_tools/_generated_rai_client.py +225 -0
  257. azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +12 -10
  258. azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +100 -45
  259. azure/ai/evaluation/simulator/_model_tools/_rai_client.py +101 -3
  260. azure/ai/evaluation/simulator/_model_tools/_template_handler.py +31 -11
  261. azure/ai/evaluation/simulator/_model_tools/models.py +20 -17
  262. azure/ai/evaluation/simulator/_simulator.py +43 -19
  263. {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/METADATA +378 -27
  264. azure_ai_evaluation-1.13.5.dist-info/RECORD +305 -0
  265. {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/WHEEL +1 -1
  266. azure/ai/evaluation/_evaluators/_multimodal/__init__.py +0 -20
  267. azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal.py +0 -132
  268. azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal_base.py +0 -55
  269. azure/ai/evaluation/_evaluators/_multimodal/_hate_unfairness.py +0 -100
  270. azure/ai/evaluation/_evaluators/_multimodal/_protected_material.py +0 -124
  271. azure/ai/evaluation/_evaluators/_multimodal/_self_harm.py +0 -100
  272. azure/ai/evaluation/_evaluators/_multimodal/_sexual.py +0 -100
  273. azure/ai/evaluation/_evaluators/_multimodal/_violence.py +0 -100
  274. azure/ai/evaluation/simulator/_tracing.py +0 -89
  275. azure_ai_evaluation-1.0.1.dist-info/RECORD +0 -119
  276. {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info/licenses}/NOTICE.txt +0 -0
  277. {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,292 @@
1
+ # ---------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # ---------------------------------------------------------
4
+
5
+ # Original source:
6
+ # - promptflow-core/promptflow/_core/log_manager.py
7
+ # - promptflow-core/promptflow/_utils/logger_utils.py
8
+
9
+ import os
10
+ import logging
11
+ import re
12
+ import sys
13
+ from re import Pattern
14
+ from contextvars import ContextVar
15
+ from datetime import datetime, timezone
16
+ from dataclasses import dataclass
17
+ from io import StringIO, TextIOBase
18
+ from typing import Any, Dict, Final, Mapping, Optional, Set, TextIO, Tuple, Union
19
+
20
+
21
+ valid_logging_level: Final[Set[str]] = {"CRITICAL", "FATAL", "ERROR", "WARN", "WARNING", "INFO", "DEBUG", "NOTSET"}
22
+
23
+
24
+ def get_pf_logging_level(default=logging.INFO):
25
+ logging_level = os.environ.get("PF_LOGGING_LEVEL", None)
26
+ if logging_level not in valid_logging_level:
27
+ # Fall back to info if user input is invalid.
28
+ logging_level = default
29
+ return logging_level
30
+
31
+
32
+ def _get_format_for_logger(
33
+ default_log_format: Optional[str] = None, default_date_format: Optional[str] = None
34
+ ) -> Tuple[str, str]:
35
+ """
36
+ Get the logging format and date format for logger.
37
+
38
+ This function attempts to find the handler of the root logger with a configured formatter.
39
+ If such a handler is found, it returns the format and date format used by this handler.
40
+ This can be configured through logging.basicConfig. If no configured formatter is found,
41
+ it defaults to LOG_FORMAT and DATETIME_FORMAT.
42
+ """
43
+ log_format = (
44
+ os.environ.get("PF_LOG_FORMAT")
45
+ or default_log_format
46
+ or "%(asctime)s %(thread)7d %(name)-18s %(levelname)-8s %(message)s"
47
+ )
48
+ datetime_format = os.environ.get("PF_LOG_DATETIME_FORMAT") or default_date_format or "%Y-%m-%d %H:%M:%S %z"
49
+ return log_format, datetime_format
50
+
51
+
52
+ def get_logger(name: str) -> logging.Logger:
53
+ """Get logger used during execution."""
54
+ logger = logging.Logger(name)
55
+ logger.setLevel(get_pf_logging_level())
56
+ # logger.addHandler(FileHandlerConcurrentWrapper())
57
+ stdout_handler = logging.StreamHandler(sys.stdout)
58
+ fmt, datefmt = _get_format_for_logger()
59
+ # TODO ralphe: Do we need a credentials scrubber here like the old code had? We are not logging
60
+ # logging anything that sensitive here.
61
+ stdout_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt=datefmt))
62
+ logger.addHandler(stdout_handler)
63
+ return logger
64
+
65
+
66
+ def scrub_credentials(s: str):
67
+ """Scrub credentials in string s.
68
+
69
+ For example, for input string: "print accountkey=accountKey", the output will be:
70
+ "print accountkey=**data_scrubbed**"
71
+ """
72
+ # for h in logger.handlers:
73
+ # if isinstance(h, FileHandlerConcurrentWrapper):
74
+ # if h.handler and h.handler._formatter:
75
+ # credential_scrubber = h.handler._formatter.credential_scrubber
76
+ # if credential_scrubber:
77
+ # return credential_scrubber.scrub(s)
78
+ return CredentialScrubber.scrub(s)
79
+
80
+
81
+ class CredentialScrubber:
82
+ """Scrub sensitive information in string."""
83
+
84
+ PLACE_HOLDER = "**data_scrubbed**"
85
+ LENGTH_THRESHOLD = 2
86
+ DEFAULT_REGEX_SET: Final[Set[Pattern[str]]] = {
87
+ re.compile(r"(?<=sig=)[^\s;&]+", flags=re.IGNORECASE), # Replace signature.
88
+ re.compile(r"(?<=key=)[^\s;&]+", flags=re.IGNORECASE), # Replace key.
89
+ }
90
+
91
+ @staticmethod
92
+ def scrub(input: str) -> str:
93
+ """Replace sensitive information in input string with PLACE_HOLDER.
94
+
95
+ For example, for input string: "print accountkey=accountKey", the output will be:
96
+ "print accountkey=**data_scrubbed**"
97
+ """
98
+ output = input
99
+ for regex in CredentialScrubber.DEFAULT_REGEX_SET:
100
+ output = regex.sub(CredentialScrubber.PLACE_HOLDER, output)
101
+ return output
102
+
103
+
104
+ # Logs by flow_logger will only be shown in flow mode.
105
+ # These logs should contain all detailed logs from executor and runtime.
106
+ flow_logger = get_logger("execution.flow")
107
+
108
+ # Logs by bulk_logger will only be shown in bulktest and eval modes.
109
+ # These logs should contain overall progress logs and error logs.
110
+ bulk_logger = get_logger("execution.bulk")
111
+
112
+ # Logs by logger will be shown in all the modes above,
113
+ # such as error logs.
114
+ logger = get_logger("execution")
115
+
116
+
117
+ def log_progress(
118
+ run_start_time: datetime,
119
+ total_count: int,
120
+ current_count: int,
121
+ logger: logging.Logger = bulk_logger,
122
+ formatter="Finished {count} / {total_count} lines.",
123
+ ) -> None:
124
+ if current_count > 0:
125
+ delta = datetime.now(timezone.utc).timestamp() - run_start_time.timestamp()
126
+ average_execution_time = round(delta / current_count, 2)
127
+ estimated_execution_time = round(average_execution_time * (total_count - current_count), 2)
128
+ logger.info(formatter.format(count=current_count, total_count=total_count))
129
+ logger.info(
130
+ f"Average execution time for completed lines: {average_execution_time} seconds. "
131
+ f"Estimated time for incomplete lines: {estimated_execution_time} seconds."
132
+ )
133
+
134
+
135
+ def incremental_print(log: str, printed: int, fileout: Union[TextIO, Any]) -> int:
136
+ count = 0
137
+ for line in log.splitlines():
138
+ if count >= printed:
139
+ fileout.write(line + "\n")
140
+ printed += 1
141
+ count += 1
142
+ return printed
143
+
144
+
145
+ def print_red_error(message):
146
+ try:
147
+ from colorama import Fore, init
148
+
149
+ init(autoreset=True)
150
+ print(Fore.RED + message)
151
+ except ImportError:
152
+ print(message)
153
+
154
+
155
+ @dataclass
156
+ class NodeInfo:
157
+ run_id: str
158
+ node_name: str
159
+ line_number: int
160
+
161
+
162
+ class NodeLogManager:
163
+ """Replace sys.stdout and sys.stderr with NodeLogWriter.
164
+
165
+ This class intercepts and saves logs to stdout/stderr when executing a node. For example:
166
+ with NodeLogManager() as log_manager:
167
+ print('test stdout')
168
+ print('test stderr', file=sys.stderr)
169
+
170
+ log_manager.get_logs() will return: {'stdout': 'test stdout\n', 'stderr': 'test stderr\n'}
171
+ """
172
+
173
+ def __init__(self, record_datetime: bool = True):
174
+ self.stdout_logger = NodeLogWriter(sys.stdout, record_datetime)
175
+ self.stderr_logger = NodeLogWriter(sys.stderr, record_datetime, is_stderr=True)
176
+
177
+ def __enter__(self) -> "NodeLogManager":
178
+ """Replace sys.stdout and sys.stderr with NodeLogWriter."""
179
+ self._prev_stdout = sys.stdout
180
+ self._prev_stderr = sys.stderr
181
+ sys.stdout = self.stdout_logger
182
+ sys.stderr = self.stderr_logger
183
+ return self
184
+
185
+ def __exit__(self, *args) -> None:
186
+ """Restore sys.stdout and sys.stderr."""
187
+ sys.stdout = self._prev_stdout
188
+ sys.stderr = self._prev_stderr
189
+
190
+ def set_node_context(self, run_id: str, node_name: str, line_number: int) -> None:
191
+ """Set node context."""
192
+ self.stdout_logger.set_node_info(run_id, node_name, line_number)
193
+ self.stderr_logger.set_node_info(run_id, node_name, line_number)
194
+
195
+ def clear_node_context(self, run_id: str) -> None:
196
+ """Clear node context."""
197
+ self.stdout_logger.clear_node_info(run_id)
198
+ self.stderr_logger.clear_node_info(run_id)
199
+
200
+ def get_logs(self, run_id: str) -> Mapping[str, str]:
201
+ return {
202
+ "stdout": self.stdout_logger.get_log(run_id),
203
+ "stderr": self.stderr_logger.get_log(run_id),
204
+ }
205
+
206
+
207
+ class NodeLogWriter(TextIOBase):
208
+ """Record node run logs."""
209
+
210
+ DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
211
+
212
+ def __init__(self, prev_stdout: Union[TextIOBase, Any], record_datetime: bool = True, is_stderr: bool = False):
213
+ self.run_id_to_stdout: Dict[str, StringIO] = {}
214
+ self._context: ContextVar[Optional[NodeInfo]] = ContextVar("run_log_info", default=None)
215
+ self._prev_out: Union[TextIOBase, Any] = prev_stdout
216
+ self._record_datetime: bool = record_datetime
217
+ self._is_stderr: bool = is_stderr
218
+
219
+ def set_node_info(self, run_id: str, node_name: str, line_number: int) -> None:
220
+ """Set node info to a context variable.
221
+
222
+ After set node info, write method will write to string IO associated with this node.
223
+ """
224
+ run_log_info = NodeInfo(run_id, node_name, line_number)
225
+ self._context.set(run_log_info)
226
+ self.run_id_to_stdout.update({run_id: StringIO()})
227
+
228
+ def clear_node_info(self, run_id: str):
229
+ """Clear context variable associated with run id."""
230
+ log_info: Optional[NodeInfo] = self._context.get()
231
+ if log_info and log_info.run_id == run_id:
232
+ self._context.set(None)
233
+
234
+ if run_id in self.run_id_to_stdout:
235
+ self.run_id_to_stdout.pop(run_id)
236
+
237
+ def get_log(self, run_id: str) -> str:
238
+ """Get log associated with run id."""
239
+ string_io: Optional[StringIO] = self.run_id_to_stdout.get(run_id)
240
+ if string_io is None:
241
+ return ""
242
+
243
+ return string_io.getvalue()
244
+
245
+ def write(self, s: str) -> int:
246
+ """Override TextIO's write method and writes input string into a string IO
247
+
248
+ The written string is compliant without any credentials.
249
+ The string is also recorded to flow/bulk logger.
250
+ If node info is not set, write to previous stdout.
251
+ """
252
+ log_info: Optional[NodeInfo] = self._context.get()
253
+ s = scrub_credentials(s) # Remove credential from string.
254
+ if log_info is None:
255
+ return self._prev_out.write(s)
256
+ else:
257
+ self._write_to_flow_log(log_info, s)
258
+ stdout: Optional[StringIO] = self.run_id_to_stdout.get(log_info.run_id)
259
+ # When the line execution timeout is reached, all running nodes will be cancelled and node info will
260
+ # be cleared. This will remove StringIO from self.run_id_to_stdout. For sync tools running in a worker
261
+ # thread, they can't be stopped and self._context won't change in the worker
262
+ # thread because it's a thread-local variable. Therefore, we need to check if StringIO is None here.
263
+ if stdout is None:
264
+ return 0
265
+ if self._record_datetime and s != "\n": # For line breaker, do not add datetime prefix.
266
+ s = f"[{datetime.now(timezone.utc).strftime(self.DATETIME_FORMAT)}] {s}"
267
+ return stdout.write(s)
268
+
269
+ def flush(self):
270
+ """Override TextIO's flush method."""
271
+ node_info: Optional[NodeInfo] = self._context.get()
272
+ if node_info is None:
273
+ self._prev_out.flush()
274
+ else:
275
+ string_io = self.run_id_to_stdout.get(node_info.run_id)
276
+ if string_io is not None:
277
+ string_io.flush()
278
+
279
+ def _write_to_flow_log(self, log_info: NodeInfo, s: str):
280
+ """Save stdout log to flow_logger and stderr log to logger."""
281
+ # If user uses "print('log message.')" to log, then
282
+ # "write" method will be called twice and the second time input is only '\n'.
283
+ # For this case, should not log '\n' in flow_logger.
284
+ if s != "\n":
285
+ if self._is_stderr:
286
+ flow_log = f"[{str(log_info)}] stderr> " + s.rstrip("\n")
287
+ # Log stderr in all scenarios so we can diagnose problems.
288
+ logger.warning(flow_log)
289
+ else:
290
+ flow_log = f"[{str(log_info)}] stdout> " + s.rstrip("\n")
291
+ # Log stdout only in flow mode.
292
+ flow_logger.info(flow_log)
@@ -0,0 +1,17 @@
1
+ # ---------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # ---------------------------------------------------------
4
+
5
+ import contextvars
6
+ from concurrent.futures import ThreadPoolExecutor
7
+ from functools import partial
8
+ from typing_extensions import override
9
+
10
+
11
+ class ThreadPoolExecutorWithContext(ThreadPoolExecutor):
12
+ """ThreadPoolExecutor that preserves context variables across threads."""
13
+
14
+ @override
15
+ def submit(self, fn, *args, **kwargs):
16
+ context = contextvars.copy_context()
17
+ return super().submit(context.run, partial(fn, *args, **kwargs))
@@ -0,0 +1,36 @@
1
+ # ---------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # ---------------------------------------------------------
4
+
5
+ from azure.ai.evaluation._legacy.prompty._prompty import AsyncPrompty
6
+ from azure.ai.evaluation._legacy.prompty._connection import Connection, OpenAIConnection, AzureOpenAIConnection
7
+ from azure.ai.evaluation._legacy.prompty._exceptions import (
8
+ PromptyException,
9
+ MissingRequiredInputError,
10
+ InvalidInputError,
11
+ JinjaTemplateError,
12
+ NotSupportedError,
13
+ )
14
+
15
+ # =========================================================================================================
16
+ # NOTE: All of the code here is largely copy of code from Promptflow. Generally speaking, the following
17
+ # changes were made:
18
+ # - Added type annotations
19
+ # - Legacy or deprecated functionality has been removed (e.g. no more support for completions API)
20
+ # - Reworked the way images are handled to 1) Reduce the amount of code brought over, 2) remove
21
+ # the need to do two passes over the template to insert images, 3) remove the completely unnecessary
22
+ # loading of image data from the internet when it is not actually needed
23
+ # - Minor obvious tweaks to improve code readability, and removal of unused code paths
24
+ # =========================================================================================================
25
+
26
+ __all__ = [
27
+ "AsyncPrompty",
28
+ "Connection",
29
+ "AzureOpenAIConnection",
30
+ "OpenAIConnection",
31
+ "PromptyException",
32
+ "MissingRequiredInputError",
33
+ "InvalidInputError",
34
+ "JinjaTemplateError",
35
+ "NotSupportedError",
36
+ ]
@@ -0,0 +1,119 @@
1
+ # ---------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # ---------------------------------------------------------
4
+
5
+ import os
6
+ from abc import ABC, abstractmethod
7
+ from dataclasses import dataclass
8
+ from typing import Any, ClassVar, Mapping, Optional
9
+
10
+ from azure.ai.evaluation._legacy.prompty._exceptions import MissingRequiredInputError
11
+ from azure.ai.evaluation._legacy.prompty._utils import dataclass_from_dict
12
+
13
+
14
+ def _is_empty_connection_config(connection_dict: Mapping[str, Any]) -> bool:
15
+ return any(key not in {"azure_deployment", "model", "type"} for key in connection_dict.keys())
16
+
17
+
18
+ @dataclass
19
+ class Connection(ABC):
20
+ """Base class for all connection classes."""
21
+
22
+ @property
23
+ @abstractmethod
24
+ def type(self) -> str:
25
+ """Gets the type of the connection.
26
+
27
+ :return: The type of the connection.
28
+ :rtype: str"""
29
+ ...
30
+
31
+ @staticmethod
32
+ def parse_from_config(model_configuration: Mapping[str, Any]) -> "Connection":
33
+ """Parse a connection from a model configuration.
34
+
35
+ :param model_configuration: The model configuration.
36
+ :type model_configuration: Mapping[str, Any]
37
+ :return: The connection.
38
+ :rtype: Connection
39
+ """
40
+ connection_dict = {**model_configuration}
41
+ connection_type = connection_dict.pop("type", "")
42
+
43
+ connection: Connection
44
+ if connection_type in [AzureOpenAIConnection.TYPE, "azure_openai"]:
45
+ if not _is_empty_connection_config(connection_dict):
46
+ connection = AzureOpenAIConnection.from_env()
47
+ else:
48
+ connection = dataclass_from_dict(AzureOpenAIConnection, connection_dict)
49
+
50
+ elif connection_type in [OpenAIConnection.TYPE, "openai"]:
51
+ if not _is_empty_connection_config(connection_dict):
52
+ connection = OpenAIConnection.from_env()
53
+ else:
54
+ connection = dataclass_from_dict(OpenAIConnection, connection_dict)
55
+
56
+ else:
57
+ error_message = (
58
+ f"'{connection_type}' is not a supported connection type. Valid values are "
59
+ f"[{AzureOpenAIConnection.TYPE}, {OpenAIConnection.TYPE}]"
60
+ )
61
+ raise MissingRequiredInputError(error_message)
62
+
63
+ return connection
64
+
65
+
66
+ @dataclass
67
+ class OpenAIConnection(Connection):
68
+ """Connection class for OpenAI endpoints."""
69
+
70
+ base_url: str
71
+ model: str
72
+ api_key: Optional[str] = None
73
+ organization: Optional[str] = None
74
+
75
+ TYPE: ClassVar[str] = "openai"
76
+
77
+ @property
78
+ def type(self) -> str:
79
+ return OpenAIConnection.TYPE
80
+
81
+ @classmethod
82
+ def from_env(cls) -> "OpenAIConnection":
83
+ return cls(
84
+ base_url=os.environ.get("OPENAI_BASE_URL", ""),
85
+ model=os.environ.get("OPENAI_MODEL", ""),
86
+ api_key=os.environ.get("OPENAI_API_KEY"),
87
+ organization=os.environ.get("OPENAI_ORG_ID"),
88
+ )
89
+
90
+
91
+ @dataclass
92
+ class AzureOpenAIConnection(Connection):
93
+ """Connection class for Azure OpenAI endpoints."""
94
+
95
+ azure_endpoint: str
96
+ azure_deployment: str
97
+ api_key: Optional[str] = None
98
+ api_version: Optional[str] = None
99
+ resource_id: Optional[str] = None
100
+
101
+ TYPE: ClassVar[str] = "azure_openai"
102
+
103
+ @property
104
+ def type(self) -> str:
105
+ return AzureOpenAIConnection.TYPE
106
+
107
+ @classmethod
108
+ def from_env(cls) -> "AzureOpenAIConnection":
109
+ return cls(
110
+ azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT", ""),
111
+ azure_deployment=os.environ.get("AZURE_OPENAI_DEPLOYMENT", ""),
112
+ api_key=os.environ.get("AZURE_OPENAI_API_KEY"),
113
+ api_version=os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-01"),
114
+ )
115
+
116
+ def __post_init__(self):
117
+ # set default API version
118
+ if not self.api_version:
119
+ self.api_version = "2024-02-01"
@@ -0,0 +1,139 @@
1
+ # ---------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # ---------------------------------------------------------
4
+
5
+ from typing import Optional
6
+ from openai import OpenAIError
7
+ from azure.ai.evaluation._exceptions import ErrorCategory, ErrorBlame, ErrorTarget, EvaluationException
8
+
9
+
10
+ class PromptyException(EvaluationException):
11
+ """Exception class for Prompty related errors.
12
+
13
+ This exception is used to indicate that the error was caused by Prompty execution.
14
+
15
+ :param message: The error message.
16
+ :type message: str
17
+ """
18
+
19
+ def __init__(self, message: str, **kwargs):
20
+ kwargs.setdefault("category", ErrorCategory.INVALID_VALUE)
21
+ kwargs.setdefault("target", ErrorTarget.UNKNOWN)
22
+ kwargs.setdefault("blame", ErrorBlame.USER_ERROR)
23
+
24
+ super().__init__(message, **kwargs)
25
+
26
+
27
+ class MissingRequiredInputError(PromptyException):
28
+ """Exception raised when missing required input"""
29
+
30
+ def __init__(self, message: str, **kwargs):
31
+ kwargs.setdefault("category", ErrorCategory.MISSING_FIELD)
32
+ kwargs.setdefault("target", ErrorTarget.EVAL_RUN)
33
+ super().__init__(message, **kwargs)
34
+
35
+
36
+ class InvalidInputError(PromptyException):
37
+ """Exception raised when an input is invalid, could not be loaded, or is not the expected format."""
38
+
39
+ def __init__(self, message: str, **kwargs):
40
+ kwargs.setdefault("category", ErrorCategory.INVALID_VALUE)
41
+ kwargs.setdefault("target", ErrorTarget.EVAL_RUN)
42
+ super().__init__(message, **kwargs)
43
+
44
+
45
+ class JinjaTemplateError(PromptyException):
46
+ """Exception raised when the Jinja template is invalid or could not be rendered."""
47
+
48
+ def __init__(self, message: str, **kwargs):
49
+ kwargs.setdefault("category", ErrorCategory.INVALID_VALUE)
50
+ kwargs.setdefault("target", ErrorTarget.EVAL_RUN)
51
+ super().__init__(message, **kwargs)
52
+
53
+
54
+ class NotSupportedError(PromptyException):
55
+ """Exception raised when the operation is not supported."""
56
+
57
+ def __init__(self, message: str, **kwargs):
58
+ kwargs.setdefault("category", ErrorCategory.INVALID_VALUE)
59
+ kwargs.setdefault("target", ErrorTarget.UNKNOWN)
60
+ kwargs.setdefault("blame", ErrorBlame.SYSTEM_ERROR)
61
+ super().__init__(message, **kwargs)
62
+
63
+
64
+ class WrappedOpenAIError(PromptyException):
65
+ """Exception raised when an OpenAI error is encountered."""
66
+
67
+ def __init__(self, *, message: Optional[str] = None, error: Optional[OpenAIError] = None, **kwargs):
68
+ kwargs.setdefault("category", ErrorCategory.FAILED_EXECUTION)
69
+ kwargs.setdefault("target", ErrorTarget.EVAL_RUN)
70
+ kwargs.setdefault("blame", ErrorBlame.USER_ERROR)
71
+
72
+ message = (
73
+ message or self.to_openai_error_message(error)
74
+ if error
75
+ else "An error occurred while executing the OpenAI API."
76
+ )
77
+ super().__init__(message, **kwargs)
78
+
79
+ @staticmethod
80
+ def to_openai_error_message(e: OpenAIError) -> str:
81
+ # TODO ralphe: Error handling that relies on string matching is fragile and should be replaced
82
+ # with a more robust solution that examines the actual error type since that provies
83
+ # more than enough information to handle errors.
84
+ ex_type = type(e).__name__
85
+ error_message = str(e)
86
+ # https://learn.microsoft.com/en-gb/azure/ai-services/openai/reference
87
+ if error_message == "<empty message>":
88
+ msg = "The api key is invalid or revoked. " "You can correct or regenerate the api key of your connection."
89
+ return f"OpenAI API hits {ex_type}: {msg}"
90
+ # for models that do not support the `functions` parameter.
91
+ elif "Unrecognized request argument supplied: functions" in error_message:
92
+ msg = (
93
+ "Current model does not support the `functions` parameter. If you are using openai connection, then "
94
+ "please use gpt-3.5-turbo, gpt-4, gpt-4-32k, gpt-3.5-turbo-0613 or gpt-4-0613. You can refer to "
95
+ "https://platform.openai.com/docs/guides/gpt/function-calling. If you are using azure openai "
96
+ "connection, then please first go to your Azure OpenAI resource, deploy model 'gpt-35-turbo' or "
97
+ "'gpt-4' with version 0613. You can refer to "
98
+ "https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/function-calling."
99
+ )
100
+ return f"OpenAI API hits {ex_type}: {msg}"
101
+ elif "Invalid content type. image_url is only supported by certain models" in error_message:
102
+ msg = (
103
+ "Current model does not support the image input. If you are using openai connection, then please use "
104
+ "gpt-4-vision-preview. You can refer to https://platform.openai.com/docs/guides/vision."
105
+ "If you are using azure openai connection, then please first go to your Azure OpenAI resource, "
106
+ 'create a GPT-4 Turbo with Vision deployment by selecting model name: "gpt-4" and '
107
+ 'model version "vision-preview". You can refer to '
108
+ "https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/gpt-with-vision"
109
+ )
110
+ return f"OpenAI API hits {ex_type}: {msg}"
111
+ elif (
112
+ "'response_format' of type" in error_message and "is not supported with this model." in error_message
113
+ ) or (
114
+ "Additional properties are not allowed" in error_message
115
+ and "unexpected) - 'response_format'" in error_message
116
+ ):
117
+ msg = (
118
+ 'The response_format parameter needs to be a dictionary such as {"type": "text"}. '
119
+ "The value associated with the type key should be either 'text' or 'json_object' "
120
+ 'If you are using openai connection, you can only set response_format to { "type": "json_object" } '
121
+ "when calling gpt-3.5-turbo-1106 or gpt-4-1106-preview to enable JSON mode. You can refer to "
122
+ "https://platform.openai.com/docs/guides/text-generation/json-mode. If you are using azure openai "
123
+ "connection, then please first go to your Azure OpenAI resource, compatible with GPT-4 Turbo and "
124
+ "all GPT-3.5 Turbo models newer than gpt-35-turbo-1106. You can refer to "
125
+ "https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/json-mode?tabs=python."
126
+ )
127
+ return f"OpenAI API hits {ex_type}: {msg}"
128
+ elif "Principal does not have access to API/Operation" in error_message:
129
+ msg = (
130
+ "Principal does not have access to API/Operation. If you are using azure openai connection, "
131
+ "please make sure you have proper role assignment on your azure openai resource. You can refer to "
132
+ "https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/role-based-access-control"
133
+ )
134
+ return f"OpenAI API hits {ex_type}: {msg}"
135
+ else:
136
+ return (
137
+ f"OpenAI API hits {ex_type}: {error_message} [Error reference: "
138
+ "https://platform.openai.com/docs/guides/error-codes/api-errors]"
139
+ )