Skip to content

Commit 48d331b

Browse files
committed
Fix Azure AI Inference connector model_extras duplication
1 parent f1aac84 commit 48d331b

8 files changed

Lines changed: 130 additions & 3 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright (c) Microsoft. All rights reserved.
2+
3+
import asyncio
4+
5+
from semantic_kernel.connectors.ai.azure_ai_inference import (
6+
AzureAIInferenceChatCompletion,
7+
AzureAIInferenceChatPromptExecutionSettings,
8+
)
9+
from semantic_kernel.contents import ChatHistory
10+
11+
"""
12+
This sample demonstrates an example of how to use reasoning models using the Azure AI Inference service.
13+
"""
14+
15+
chat_service = AzureAIInferenceChatCompletion(
16+
ai_model_id="gpt-5-mini",
17+
# You must specify the endpoint and api_key or configure them via environment variables:
18+
# AZURE_AI_INFERENCE_ENDPOINT
19+
# AZURE_AI_INFERENCE_API_KEY
20+
endpoint="...",
21+
api_key="...",
22+
)
23+
request_settings = AzureAIInferenceChatPromptExecutionSettings(
24+
extra_parameters={
25+
"reasoning_effort": "medium",
26+
"verbosity": "medium",
27+
},
28+
)
29+
30+
# Create a ChatHistory object
31+
chat_history = ChatHistory()
32+
33+
# This is the system message that gives the chatbot its personality.
34+
developer_message = """
35+
As an assistant supporting the user,
36+
you recognize all user input
37+
as questions or consultations and answer them.
38+
"""
39+
# The developer message was newly introduced for reasoning models such as OpenAI’s o1 and o1-mini.
40+
# `system message` cannot be used with reasoning models.
41+
chat_history.add_developer_message(developer_message)
42+
43+
44+
async def chat() -> bool:
45+
try:
46+
user_input = input("User:> ")
47+
except KeyboardInterrupt:
48+
print("\n\nExiting chat...")
49+
return False
50+
except EOFError:
51+
print("\n\nExiting chat...")
52+
return False
53+
54+
if user_input == "exit":
55+
print("\n\nExiting chat...")
56+
return False
57+
58+
chat_history.add_user_message(user_input)
59+
60+
# Get the chat message content from the chat completion service.
61+
response = await chat_service.get_chat_message_content(
62+
chat_history=chat_history,
63+
settings=request_settings,
64+
)
65+
if response:
66+
print(f"Reasoning model:> {response}")
67+
68+
# Add the chat message to the chat history to keep track of the conversation.
69+
chat_history.add_message(response)
70+
71+
return True
72+
73+
74+
async def main() -> None:
75+
# Start the chat loop. The chat loop will continue until the user types "exit".
76+
chatting = True
77+
while chatting:
78+
chatting = await chat()
79+
80+
# Sample output:
81+
# User:> Why is the sky blue in one sentence?
82+
# Mosscap:> The sky appears blue because air molecules in the atmosphere scatter shorter-wavelength (blue)
83+
# light more efficiently than longer-wavelength (red) light.
84+
85+
86+
if __name__ == "__main__":
87+
asyncio.run(main())

python/semantic_kernel/connectors/ai/azure_ai_inference/azure_ai_inference_settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from pydantic import SecretStr
66

7+
from semantic_kernel.connectors.ai.open_ai.const import DEFAULT_AZURE_API_VERSION
78
from semantic_kernel.kernel_pydantic import HttpsUrl, KernelBaseSettings
89
from semantic_kernel.utils.feature_stage_decorator import experimental
910

@@ -29,9 +30,12 @@ class AzureAIInferenceSettings(KernelBaseSettings):
2930
This value can be found in the Keys & Endpoint section when examining
3031
your resource from the Azure portal. You can use either KEY1 or KEY2.
3132
(Env var AZURE_AI_INFERENCE_API_KEY)
33+
- api_version: str | None - The API version to use. The default value is "2024-10-21".
34+
(Env var AZURE_AI_INFERENCE_API_VERSION)
3235
"""
3336

3437
env_prefix: ClassVar[str] = "AZURE_AI_INFERENCE_"
3538

3639
endpoint: HttpsUrl
3740
api_key: SecretStr | None = None
41+
api_version: str = DEFAULT_AZURE_API_VERSION

python/semantic_kernel/connectors/ai/azure_ai_inference/services/azure_ai_inference_base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def __init__(
4747
client_type: AzureAIInferenceClientType,
4848
api_key: str | None = None,
4949
endpoint: str | None = None,
50+
api_version: str | None = None,
5051
env_file_path: str | None = None,
5152
env_file_encoding: str | None = None,
5253
client: ChatCompletionsClient | EmbeddingsClient | None = None,
@@ -60,11 +61,13 @@ def __init__(
6061
The following environment variables are used:
6162
- AZURE_AI_INFERENCE_API_KEY
6263
- AZURE_AI_INFERENCE_ENDPOINT
64+
- AZURE_AI_INFERENCE_API_VERSION
6365
6466
Args:
6567
client_type (AzureAIInferenceClientType): The client type to use.
6668
api_key (str | None): The API key for the Azure AI Inference service deployment. (Optional)
6769
endpoint (str | None): The endpoint of the Azure AI Inference service deployment. (Optional)
70+
api_version (str | None): The API version to use. (Optional)
6871
env_file_path (str | None): The path to the environment file. (Optional)
6972
env_file_encoding (str | None): The encoding of the environment file. (Optional)
7073
client (ChatCompletionsClient | None): The Azure AI Inference client to use. (Optional)
@@ -81,6 +84,7 @@ def __init__(
8184
azure_ai_inference_settings = AzureAIInferenceSettings(
8285
api_key=api_key,
8386
endpoint=endpoint,
87+
api_version=api_version,
8488
env_file_path=env_file_path,
8589
env_file_encoding=env_file_encoding,
8690
)
@@ -93,6 +97,7 @@ def __init__(
9397
endpoint=endpoint,
9498
credential=AzureKeyCredential(azure_ai_inference_settings.api_key.get_secret_value()),
9599
user_agent=SEMANTIC_KERNEL_USER_AGENT,
100+
api_version=azure_ai_inference_settings.api_version,
96101
)
97102
else:
98103
if credential is None:
@@ -102,6 +107,7 @@ def __init__(
102107
endpoint=endpoint,
103108
credential=credential,
104109
user_agent=SEMANTIC_KERNEL_USER_AGENT,
110+
api_version=azure_ai_inference_settings.api_version,
105111
)
106112

107113
args: dict[str, Any] = {

python/semantic_kernel/connectors/ai/azure_ai_inference/services/azure_ai_inference_chat_completion.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def __init__(
6666
ai_model_id: str,
6767
api_key: str | None = None,
6868
endpoint: str | None = None,
69+
api_version: str | None = None,
6970
service_id: str | None = None,
7071
env_file_path: str | None = None,
7172
env_file_encoding: str | None = None,
@@ -78,11 +79,13 @@ def __init__(
7879
The following environment variables are used:
7980
- AZURE_AI_INFERENCE_API_KEY
8081
- AZURE_AI_INFERENCE_ENDPOINT
82+
- AZURE_AI_INFERENCE_API_VERSION
8183
8284
Args:
8385
ai_model_id: (str): A string that is used to identify the model such as the model name. (Required)
8486
api_key (str | None): The API key for the Azure AI Inference service deployment. (Optional)
8587
endpoint (str | None): The endpoint of the Azure AI Inference service deployment. (Optional)
88+
api_version (str | None): The API version to use. (Optional)
8689
service_id (str | None): Service ID for the chat completion service. (Optional)
8790
env_file_path (str | None): The path to the environment file. (Optional)
8891
env_file_encoding (str | None): The encoding of the environment file. (Optional)
@@ -99,6 +102,7 @@ def __init__(
99102
"client_type": AzureAIInferenceClientType.ChatCompletions,
100103
"client": client,
101104
"endpoint": endpoint,
105+
"api_version": api_version,
102106
"env_file_path": env_file_path,
103107
"env_file_encoding": env_file_encoding,
104108
}
@@ -139,6 +143,9 @@ async def _inner_get_chat_message_contents(
139143
assert isinstance(self.client, ChatCompletionsClient) # nosec
140144
with AzureAIInferenceTracing():
141145
settings_dict = settings.prepare_settings_dict()
146+
# Remove the extra parameters since it will be passed in via the `model_extras` param
147+
settings_dict.pop("extra_parameters", None)
148+
142149
self._handle_structured_output(settings, settings_dict)
143150
response: ChatCompletions = await self.client.complete(
144151
messages=self._prepare_chat_history_for_request(chat_history),
@@ -165,6 +172,9 @@ async def _inner_get_streaming_chat_message_contents(
165172
assert isinstance(self.client, ChatCompletionsClient) # nosec
166173
with AzureAIInferenceTracing():
167174
settings_dict = settings.prepare_settings_dict()
175+
# Remove the extra parameters since it will be passed in via the `model_extras` param
176+
settings_dict.pop("extra_parameters", None)
177+
168178
self._handle_structured_output(settings, settings_dict)
169179
response: AsyncStreamingChatCompletions = await self.client.complete(
170180
stream=True,

python/semantic_kernel/connectors/ai/azure_ai_inference/services/azure_ai_inference_text_embedding.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(
3535
ai_model_id: str,
3636
api_key: str | None = None,
3737
endpoint: str | None = None,
38+
api_version: str | None = None,
3839
service_id: str | None = None,
3940
env_file_path: str | None = None,
4041
env_file_encoding: str | None = None,
@@ -46,11 +47,13 @@ def __init__(
4647
The following environment variables are used:
4748
- AZURE_AI_INFERENCE_API_KEY
4849
- AZURE_AI_INFERENCE_ENDPOINT
50+
- AZURE_AI_INFERENCE_API_VERSION
4951
5052
Args:
5153
ai_model_id: (str): A string that is used to identify the model such as the model name. (Required)
5254
api_key (str | None): The API key for the Azure AI Inference service deployment. (Optional)
5355
endpoint (str | None): The endpoint of the Azure AI Inference service deployment. (Optional)
56+
api_version (str | None): The API version to use. (Optional)
5457
service_id (str | None): Service ID for the chat completion service. (Optional)
5558
env_file_path (str | None): The path to the environment file. (Optional)
5659
env_file_encoding (str | None): The encoding of the environment file. (Optional)
@@ -65,6 +68,7 @@ def __init__(
6568
client_type=AzureAIInferenceClientType.Embeddings,
6669
api_key=api_key,
6770
endpoint=endpoint,
71+
api_version=api_version,
6872
env_file_path=env_file_path,
6973
env_file_encoding=env_file_encoding,
7074
client=client,

python/semantic_kernel/connectors/ai/open_ai/settings/azure_open_ai_settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class AzureOpenAISettings(KernelBaseSettings):
8484
your resource from the Azure portal, the endpoint should end in openai.azure.com.
8585
If both base_url and endpoint are supplied, base_url will be used.
8686
(Env var AZURE_OPENAI_ENDPOINT)
87-
- api_version: str | None - The API version to use. The default value is "2024-02-01".
87+
- api_version: str | None - The API version to use. The default value is "2024-10-21".
8888
(Env var AZURE_OPENAI_API_VERSION)
8989
- token_endpoint: str - The token endpoint to use to retrieve the authentication token.
9090
The default value is "https://cognitiveservices.azure.com/.default".

python/tests/unit/connectors/ai/azure_ai_inference/services/test_azure_ai_inference_chat_completion.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ def test_azure_ai_inference_chat_completion_init_with_service_id(
6666
assert isinstance(azure_ai_inference.client, ChatCompletionsClient)
6767

6868

69+
def test_azure_ai_inference_chat_completion_init_with_api_version(azure_ai_inference_unit_test_env, model_id) -> None:
70+
"""Test initialization of AzureAIInferenceChatCompletion with api_version"""
71+
azure_ai_inference = AzureAIInferenceChatCompletion(model_id, api_version="2024-02-15-test")
72+
73+
assert azure_ai_inference.ai_model_id == model_id
74+
assert isinstance(azure_ai_inference.client, ChatCompletionsClient)
75+
assert azure_ai_inference.client._config.api_version == "2024-02-15-test"
76+
77+
6978
@pytest.mark.parametrize(
7079
"azure_ai_inference_client",
7180
[AzureAIInferenceChatCompletion.__name__],
@@ -210,7 +219,6 @@ async def test_azure_ai_inference_chat_completion_with_extra_parameters(
210219
messages=[UserMessage(content=user_message_content)],
211220
model=model_id,
212221
model_extras=settings.extra_parameters,
213-
**settings.prepare_settings_dict(),
214222
)
215223
assert len(responses) == 1
216224
assert responses[0].role == "assistant"
@@ -506,7 +514,6 @@ async def test_azure_ai_inference_streaming_chat_completion_with_extra_parameter
506514
messages=[UserMessage(content=user_message_content)],
507515
model=model_id,
508516
model_extras=settings.extra_parameters,
509-
**settings.prepare_settings_dict(),
510517
)
511518

512519

python/tests/unit/connectors/ai/azure_ai_inference/services/test_azure_ai_inference_text_embedding.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ def test_azure_ai_inference_text_embedding_init_with_service_id(
5252
assert isinstance(azure_ai_inference.client, EmbeddingsClient)
5353

5454

55+
def test_azure_ai_inference_text_embedding_init_with_api_version(azure_ai_inference_unit_test_env, model_id) -> None:
56+
"""Test initialization of AzureAIInferenceTextEmbedding with api_version"""
57+
azure_ai_inference = AzureAIInferenceTextEmbedding(model_id, api_version="2024-02-15-test")
58+
59+
assert azure_ai_inference.ai_model_id == model_id
60+
assert isinstance(azure_ai_inference.client, EmbeddingsClient)
61+
assert azure_ai_inference.client._config.api_version == "2024-02-15-test"
62+
63+
5564
@pytest.mark.parametrize(
5665
"azure_ai_inference_client",
5766
[AzureAIInferenceTextEmbedding.__name__],

0 commit comments

Comments
 (0)