diff --git a/ai-cli.sln b/ai-cli.sln
index da387f46..222f109e 100644
--- a/ai-cli.sln
+++ b/ai-cli.sln
@@ -39,6 +39,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telemetry", "Telemetry", "{
src\telemetry\NuGet.config = src\telemetry\NuGet.config
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "inference_extension", "src\extensions\inference_extension\inference_extension.csproj", "{7BF26AB6-8931-46CB-A330-D83DF55AB4E8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -181,6 +183,18 @@ Global
{306A3CD6-91C2-450B-9995-79701CE63FE2}.Release|x64.Build.0 = Release|Any CPU
{306A3CD6-91C2-450B-9995-79701CE63FE2}.Release|x86.ActiveCfg = Release|Any CPU
{306A3CD6-91C2-450B-9995-79701CE63FE2}.Release|x86.Build.0 = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|x64.Build.0 = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Debug|x86.Build.0 = Debug|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|x64.ActiveCfg = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|x64.Build.0 = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|x86.ActiveCfg = Release|Any CPU
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -195,6 +209,7 @@ Global
{9499C018-FA08-4133-93B3-FC0F3863A6CC} = {C8AFF891-D6AA-4B8F-BC21-10404DF4B355}
{CED7C805-0435-4BF7-A42F-9F3BBF14A18F} = {644B75F1-C768-4DB3-BAF2-C69A1F36DD28}
{306A3CD6-91C2-450B-9995-79701CE63FE2} = {975EBC5A-506D-49B5-AA7F-70D3119F009D}
+ {7BF26AB6-8931-46CB-A330-D83DF55AB4E8} = {644B75F1-C768-4DB3-BAF2-C69A1F36DD28}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {002655B1-E1E1-4F2A-8D53-C9CD55136AE2}
diff --git a/src/ai/.x/config/chat.default.config b/src/ai/.x/config/chat.default.config
index 6486aa83..6ef5af5a 100644
--- a/src/ai/.x/config/chat.default.config
+++ b/src/ai/.x/config/chat.default.config
@@ -2,6 +2,7 @@
@default.deployment
@default.search.connection
@default.assistant
+@default.model
@default.log
@default.path
@default.output
diff --git a/src/ai/.x/config/chat.default.model b/src/ai/.x/config/chat.default.model
new file mode 100644
index 00000000..bf2002d7
--- /dev/null
+++ b/src/ai/.x/config/chat.default.model
@@ -0,0 +1 @@
+chat.model.name=@chat.model
\ No newline at end of file
diff --git a/src/ai/.x/config/connection.from.endpoint b/src/ai/.x/config/connection.from.endpoint
index 957c7df2..99ee5622 100644
--- a/src/ai/.x/config/connection.from.endpoint
+++ b/src/ai/.x/config/connection.from.endpoint
@@ -1,3 +1,4 @@
service.config.region=@region
service.config.endpoint.uri=@endpoint
+service.config.endpoint.type=@endpoint.type
service.config.key=@key
\ No newline at end of file
diff --git a/src/ai/.x/config/endpoint.type b/src/ai/.x/config/endpoint.type
new file mode 100644
index 00000000..e69de29b
diff --git a/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreaming.csproj._ b/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreaming.csproj._
new file mode 100644
index 00000000..e19c066f
--- /dev/null
+++ b/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreaming.csproj._
@@ -0,0 +1,16 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+ Exe
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreamingClass.cs b/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreamingClass.cs
new file mode 100644
index 00000000..1a6fa820
--- /dev/null
+++ b/src/ai/.x/templates/aml-chat-streaming-cs/AzureAIInferencingChatCompletionsStreamingClass.cs
@@ -0,0 +1,66 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+using Azure;
+using Azure.Identity;
+using Azure.AI.Inference;
+using System;
+
+public class {ClassName}
+{
+ public {ClassName}(string aiChatEndpoint, string aiChatAPIKey, string? aiChatModel, string systemPrompt)
+ {
+ _systemPrompt = systemPrompt;
+ _aiChatModel = aiChatModel;
+
+ _client = string.IsNullOrEmpty(aiChatAPIKey)
+ ? new ChatCompletionsClient(new Uri(aiChatEndpoint), new DefaultAzureCredential())
+ : new ChatCompletionsClient(new Uri(aiChatEndpoint), new AzureKeyCredential(aiChatAPIKey));
+ _messages = new List();
+
+ ClearConversation();
+ }
+
+ public void ClearConversation()
+ {
+ _messages.Clear();
+ _messages.Add(new ChatRequestSystemMessage(_systemPrompt));
+ }
+
+ public async Task GetChatCompletionsStreamingAsync(string userPrompt, Action? callback = null)
+ {
+ _messages.Add(new ChatRequestUserMessage(userPrompt));
+ var options = new ChatCompletionsOptions(_messages);
+ if (!string.IsNullOrEmpty(_aiChatModel))
+ {
+ options.Model = _aiChatModel;
+ }
+
+ var responseContent = string.Empty;
+ var response = await _client.CompleteStreamingAsync(options);
+ await foreach (var update in response)
+ {
+ var content = update.ContentUpdate;
+
+ if (update.FinishReason == CompletionsFinishReason.ContentFiltered)
+ {
+ content = $"{content}\nWARNING: Content filtered!";
+ }
+
+ if (string.IsNullOrEmpty(content)) continue;
+
+ responseContent += content;
+ if (callback != null) callback(update);
+ }
+
+ _messages.Add(new ChatRequestAssistantMessage() { Content = responseContent });
+ return responseContent;
+ }
+
+ private string _systemPrompt;
+ private string? _aiChatModel;
+ private ChatCompletionsClient _client;
+ private List _messages;
+}
\ No newline at end of file
diff --git a/src/ai/.x/templates/aml-chat-streaming-cs/Program.cs b/src/ai/.x/templates/aml-chat-streaming-cs/Program.cs
new file mode 100644
index 00000000..2c9e4f9e
--- /dev/null
+++ b/src/ai/.x/templates/aml-chat-streaming-cs/Program.cs
@@ -0,0 +1,42 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+using System;
+
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ var aiChatAPIKey = Environment.GetEnvironmentVariable("AZURE_AI_CHAT_API_KEY") ?? "";
+ var aiChatEndpoint = Environment.GetEnvironmentVariable("AZURE_AI_CHAT_ENDPOINT") ?? "";
+ var aiChatModel = Environment.GetEnvironmentVariable("AZURE_AI_CHAT_MODEL"); // null is fine
+ var systemPrompt = Environment.GetEnvironmentVariable("SYSTEM_PROMPT") ?? "You are a helpful AI assistant.";
+
+ if (string.IsNullOrEmpty(aiChatAPIKey) || aiChatAPIKey.StartsWith(" {
+ var text = update.ContentUpdate;
+ Console.Write(text);
+ });
+ Console.WriteLine("\n");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ai/.x/templates/aml-chat-streaming-cs/_.json b/src/ai/.x/templates/aml-chat-streaming-cs/_.json
new file mode 100644
index 00000000..7cd818b5
--- /dev/null
+++ b/src/ai/.x/templates/aml-chat-streaming-cs/_.json
@@ -0,0 +1,6 @@
+{
+ "_LongName": "Azure AI Inference Chat Completions (Streaming)",
+ "_ShortName": "az-inference-chat-streaming",
+ "_Language": "C#",
+ "ClassName": "AzureAIInferenceChatCompletionsStreaming"
+}
\ No newline at end of file
diff --git a/src/ai/.x/templates/aml-chat-streaming-py/_.json b/src/ai/.x/templates/aml-chat-streaming-py/_.json
index d35d6a7c..d0b6c592 100644
--- a/src/ai/.x/templates/aml-chat-streaming-py/_.json
+++ b/src/ai/.x/templates/aml-chat-streaming-py/_.json
@@ -1,6 +1,6 @@
{
- "_LongName": "AzureML Chat Completions (Streaming)",
- "_ShortName": "aml-chat-streaming",
+ "_LongName": "Azure AI Inference Chat Completions (Streaming)",
+ "_ShortName": "az-inference-chat-streaming",
"_Language": "Python",
- "ClassName": "AzureMLChatCompletionsStreaming"
+ "ClassName": "AzureAIInferenceChatCompletionsStreaming"
}
\ No newline at end of file
diff --git a/src/ai/.x/templates/aml-chat-streaming-py/azureml_chat_completions_streaming.py b/src/ai/.x/templates/aml-chat-streaming-py/azureml_chat_completions_streaming.py
index 8bf30ade..daf323a5 100644
--- a/src/ai/.x/templates/aml-chat-streaming-py/azureml_chat_completions_streaming.py
+++ b/src/ai/.x/templates/aml-chat-streaming-py/azureml_chat_completions_streaming.py
@@ -3,8 +3,9 @@
from azure.core.credentials import AzureKeyCredential
class {ClassName}:
- def __init__(self, chat_endpoint, chat_api_key, chat_system_prompt):
+ def __init__(self, chat_endpoint, chat_api_key, chat_model, chat_system_prompt):
self.chat_system_prompt = chat_system_prompt
+ self.chat_model = chat_model
self.client = ChatCompletionsClient(endpoint=chat_endpoint, credential=AzureKeyCredential(chat_api_key))
self.clear_conversation()
@@ -19,11 +20,15 @@ def get_chat_completions(self, user_input, callback):
complete_content = ''
response = self.client.complete(
messages=self.messages,
+ model=self.chat_model,
stream=True,
)
for update in response:
+ if update.choices is None or len(update.choices) == 0:
+ continue
+
content = update.choices[0].delta.content or ""
if content is None: continue
diff --git a/src/ai/.x/templates/aml-chat-streaming-py/main.py b/src/ai/.x/templates/aml-chat-streaming-py/main.py
index 4a91a4e2..8bfa41c6 100644
--- a/src/ai/.x/templates/aml-chat-streaming-py/main.py
+++ b/src/ai/.x/templates/aml-chat-streaming-py/main.py
@@ -3,21 +3,23 @@
import sys
def main():
- chat_api_key = os.getenv("AZURE_AI_INFERENCE_CHAT_API_KEY", '')
- chat_endpoint = os.getenv("AZURE_AI_INFERENCE_CHAT_ENDPOINT", '')
- chat_system_prompt = os.getenv('AZURE_AI_INFERENCE_CHAT_SYSTEM_PROMPT', 'You are a helpful AI assistant.')
+ chat_api_key = os.getenv("AZURE_AI_CHAT_API_KEY", '')
+ chat_endpoint = os.getenv("AZURE_AI_CHAT_ENDPOINT", '')
+ chat_model = os.getenv('AZURE_AI_CHAT_MODEL', '')
+ chat_system_prompt = os.getenv('SYSTEM_PROMPT', 'You are a helpful AI assistant.')
ok = all([chat_api_key, chat_endpoint, chat_system_prompt]) and \
all([not s.startswith('
+
diff --git a/src/ai/commands/chat_command.cs b/src/ai/commands/chat_command.cs
index 33642b33..4b619caf 100644
--- a/src/ai/commands/chat_command.cs
+++ b/src/ai/commands/chat_command.cs
@@ -5,6 +5,7 @@
using Azure.AI.Details.Common.CLI.ConsoleGui;
using Azure.AI.Details.Common.CLI.Extensions.HelperFunctions;
+using Azure.AI.Details.Common.CLI.Extensions.Inference;
using Azure.AI.OpenAI;
using Azure.Core.Diagnostics;
using Microsoft.CognitiveServices.Speech;
@@ -204,12 +205,15 @@ private async Task> GetChatTextHandlerAsync(bool interactive)
var parameterFile = InputChatParameterFileToken.Data().GetOrDefault(_values);
if (!string.IsNullOrEmpty(parameterFile)) SetValuesFromParameterFile(parameterFile);
+ var endpointType = ConfigEndpointTypeToken.Data().GetOrDefault(_values);
+ var inferenceEndpointOk = endpointType == "inference";
+ if (inferenceEndpointOk) return GetInferenceChatTextHandler(interactive);
+
var assistantId = _values["chat.assistant.id"];
var assistantIdOk = !string.IsNullOrEmpty(assistantId);
+ if (assistantIdOk) return await GetAssistantsAPITextHandlerAsync(interactive, assistantId);
- return assistantIdOk
- ? await GetAssistantsAPITextHandlerAsync(interactive, assistantId)
- : GetChatCompletionsTextHandler(interactive);
+ return GetChatCompletionsTextHandler(interactive);
}
private async Task> GetAssistantsAPITextHandlerAsync(bool interactive, string assistantId)
@@ -219,7 +223,7 @@ private async Task> GetAssistantsAPITextHandlerAsync(bool int
var client = CreateAssistantClient();
var thread = await CreateOrGetAssistantThread(client, threadId);
- _ = CheckWriteChatHistoryOutputFileAsync(client, thread);
+ _ = CheckWriteChatHistoryOutputFileAsync(fileName => thread.SaveChatHistoryToFileAsync(client, fileName));
threadId = thread.Id;
_values.Reset("chat.thread.id", threadId);
@@ -239,13 +243,35 @@ private async Task> GetAssistantsAPITextHandlerAsync(bool int
};
}
+ private Func GetInferenceChatTextHandler(bool interactive)
+ {
+ var aiChatEndpoint = _values["service.config.endpoint.uri"];
+ var aiChatAPIKey = _values["service.config.key"];
+
+ var systemPrompt = _values.GetOrDefault("chat.message.system.prompt", DefaultSystemPrompt);
+ var chatHistoryJsonFile = InputChatHistoryJsonFileToken.Data().GetOrDefault(_values);
+ var aiChatModel = ChatModelNameToken.Data().GetOrDefault(_values);
+ var chat = new AzureAIInferenceChatCompletionsStreaming(aiChatEndpoint, aiChatAPIKey, aiChatModel, systemPrompt, chatHistoryJsonFile);
+
+ return async (string text) =>
+ {
+ if (interactive && text.ToLower() == "reset")
+ {
+ chat.ClearConversation();
+ return;
+ }
+
+ await GetInferenceChatTextHandlerAsync(chat, text);
+ };
+ }
+
private Func GetChatCompletionsTextHandler(bool interactive)
{
var client = CreateOpenAIClient(out var deployment);
var chatClient = client.GetChatClient(deployment);
var options = CreateChatCompletionOptions(out var messages);
- CheckWriteChatHistoryOutputFile(messages);
+ CheckWriteChatHistoryOutputFile(fileName => messages.SaveChatHistoryToFile(fileName));
var funcContext = CreateChatCompletionsFunctionFactoryAndCallContext(messages, options);
@@ -413,7 +439,7 @@ private void DisplayAssistantFunctionCall(string functionName, string functionAr
public async Task GetAssistantsAPIResponseAsync(AssistantClient assistantClient, string assistantId, AssistantThread thread, RunCreationOptions options, HelperFunctionFactory factory, string userInput)
{
await assistantClient.CreateMessageAsync(thread, [ userInput ]);
- _ = CheckWriteChatHistoryOutputFileAsync(assistantClient, thread);
+ _ = CheckWriteChatHistoryOutputFileAsync(fileName => thread.SaveChatHistoryToFileAsync(assistantClient, fileName));
DisplayAssistantPromptLabel();
@@ -461,14 +487,30 @@ public async Task GetAssistantsAPIResponseAsync(AssistantClient assistantClient,
}
while (run?.Status.IsTerminal == false);
- await CheckWriteChatHistoryOutputFileAsync(assistantClient, thread);
+ await CheckWriteChatHistoryOutputFileAsync(fileName => thread.SaveChatHistoryToFileAsync(assistantClient, fileName));
+ }
+
+ private async Task GetInferenceChatTextHandlerAsync(AzureAIInferenceChatCompletionsStreaming chat, string text)
+ {
+ CheckWriteChatHistoryOutputFile(fileName => chat.Messages.SaveChatHistoryToFile(fileName));
+ DisplayAssistantPromptLabel();
+
+ var response = await chat.GetChatCompletionsStreamingAsync(text, update =>
+ {
+ var content = update.ContentUpdate;
+ DisplayAssistantPromptTextStreaming(content);
+ });
+
+ DisplayAssistantPromptTextStreamingDone();
+ CheckWriteChatAnswerOutputFile(response);
+ CheckWriteChatHistoryOutputFile(fileName => chat.Messages.SaveChatHistoryToFile(fileName));
}
private async Task GetChatCompletionsAsync(ChatClient client, List messages, ChatCompletionOptions options, HelperFunctionCallContext functionCallContext, string text)
{
var requestMessage = new UserChatMessage(text);
messages.Add(requestMessage);
- CheckWriteChatHistoryOutputFile(messages);
+ CheckWriteChatHistoryOutputFile(fileName => messages.SaveChatHistoryToFile(fileName));
DisplayAssistantPromptLabel();
@@ -497,7 +539,7 @@ private async Task GetChatCompletionsAsync(ChatClient client, List DisplayAssistantFunctionCall(name, args, result)))
{
functionCallContext.Clear();
- CheckWriteChatHistoryOutputFile(messages);
+ CheckWriteChatHistoryOutputFile(fileName => messages.SaveChatHistoryToFile(fileName));
continue;
}
@@ -507,7 +549,7 @@ private async Task GetChatCompletionsAsync(ChatClient client, List messages.SaveChatHistoryToFile(fileName));
return contentComplete;
}
@@ -530,30 +572,30 @@ private void CheckWriteChatAnswerOutputFile(string completeResponse)
}
}
- private async Task CheckWriteChatHistoryOutputFileAsync(AssistantClient client, AssistantThread thread)
+ private async Task CheckWriteChatHistoryOutputFileAsync(Func saveChatHistoryToFile)
{
var outputHistoryFile = OutputChatHistoryFileToken.Data().GetOrDefault(_values);
if (!string.IsNullOrEmpty(outputHistoryFile))
{
var fileName = FileHelpers.GetOutputDataFileName(outputHistoryFile, _values);
- await thread.SaveChatHistoryToFileAsync(client, fileName);
+ await saveChatHistoryToFile(fileName);
}
}
- private void CheckWriteChatHistoryOutputFile(IList messages)
+ private void CheckWriteChatHistoryOutputFile(Action saveChatHistoryToFile)
{
var outputHistoryFile = OutputChatHistoryFileToken.Data().GetOrDefault(_values);
if (!string.IsNullOrEmpty(outputHistoryFile))
{
var fileName = FileHelpers.GetOutputDataFileName(outputHistoryFile, _values);
- messages.SaveChatHistoryToFile(fileName);
+ saveChatHistoryToFile(fileName);
}
}
private void ClearMessageHistory(List messages)
{
messages.RemoveRange(1, messages.Count - 1);
- CheckWriteChatHistoryOutputFile(messages);
+ CheckWriteChatHistoryOutputFile(fileName => messages.SaveChatHistoryToFile(fileName));
DisplayAssistantPromptLabel();
DisplayAssistantPromptTextStreaming("I've reset the conversation. How can I help you today?");
diff --git a/src/ai/commands/init_command.cs b/src/ai/commands/init_command.cs
index b59e7e53..68d8cd7d 100644
--- a/src/ai/commands/init_command.cs
+++ b/src/ai/commands/init_command.cs
@@ -74,6 +74,9 @@ private async Task DoCommand(string command)
case "init.aiservices": await DoInitRootCognitiveServicesAIServicesKind(interactive); break;
case "init.cognitiveservices": await DoInitRootCognitiveServicesCognitiveServicesKind(interactive); break;
+ case "init.inference": await DoInitRootAzureAiInference(interactive); break;
+ case "init.github": await DoInitRootGitHub(interactive); break;
+
case "init":
case "init.openai": await DoInitRootOpenAi(interactive, false, false, false, true, true, true); break;
case "init.openai.chat": await DoInitRootOpenAi(interactive, false, false, true, true, true, true); break;
@@ -596,6 +599,80 @@ private async Task DoInitCognitiveServicesAIServicesKind(bool interactive)
ResourceGroupNameToken.Data().Set(_values, resource.Group);
}
+ private async Task DoInitRootGitHub(bool interactive)
+ {
+ ConsoleHelpers.WriteLineWithHighlight($"`GITHUB MODELS`");
+
+ Console.WriteLine("You can use GitHub Models to find and experiment with AI models for free.");
+ Console.WriteLine("Once you are ready to bring your application to production, you can switch");
+ Console.WriteLine("to a token from a paid Azure account.\n");
+ Console.WriteLine("Create a token: https://github.com/settings/tokens");
+ Console.WriteLine("Review models: https://github.com/marketplace/models/");
+
+ ConsoleHelpers.WriteLineWithHighlight($"\n`GITHUB CONFIGURATION`");
+ Console.Write("Token: ");
+ var color = Console.ForegroundColor;
+ Console.ForegroundColor = Console.BackgroundColor;
+ var token = Console.ReadLine();
+ Console.ForegroundColor = color;
+
+ if (string.IsNullOrEmpty(token))
+ {
+ throw new ApplicationException($"CANCELED: No token provided");
+ }
+ else if (token.Length < 4)
+ {
+ throw new ApplicationException($"CANCELED: Token is too short");
+ }
+
+ Console.Write("Model: ");
+ var model = Console.ReadLine();
+ if (string.IsNullOrEmpty(model))
+ {
+ throw new ApplicationException($"CANCELED: No model provided");
+ }
+
+ var endpoint = "https://models.inference.ai.azure.com";
+ ConfigSetHelpers.ConfigGitHub(endpoint, model, token);
+
+ await Task.CompletedTask;
+ }
+
+ private async Task DoInitRootAzureAiInference(bool interactive)
+ {
+ await DoInitAzureAiInference(interactive);
+ }
+
+ private async Task DoInitAzureAiInference(bool interactive)
+ {
+ ConsoleHelpers.WriteLineWithHighlight($"`AZURE AI INFERENCE`");
+
+ Console.Write("Endpoint: ");
+ var endpoint = Console.ReadLine();
+ if (string.IsNullOrEmpty(endpoint))
+ {
+ throw new ApplicationException($"CANCELED: No endpoint provided");
+ }
+
+ Console.Write("Key: ");
+ var color = Console.ForegroundColor;
+ Console.ForegroundColor = Console.BackgroundColor;
+ var key = Console.ReadLine();
+ Console.ForegroundColor = color;
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ApplicationException($"CANCELED: No key provided");
+ }
+ else if (key.Length < 4)
+ {
+ throw new ApplicationException($"CANCELED: Key is too short");
+ }
+
+ ConfigSetHelpers.ConfigAzureAiInference(endpoint, key);
+
+ await Task.CompletedTask;
+ }
+
private async Task DoInitRootCognitiveServicesCognitiveServicesKind(bool interactive)
{
if (!interactive) ThrowInteractiveNotSupportedApplicationException(); // POST-IGNITE: TODO: Add back non-interactive mode support
diff --git a/src/ai/commands/parsers/chat_command_parser.cs b/src/ai/commands/parsers/chat_command_parser.cs
index f250c811..10781086 100644
--- a/src/ai/commands/parsers/chat_command_parser.cs
+++ b/src/ai/commands/parsers/chat_command_parser.cs
@@ -101,6 +101,7 @@ public CommonChatNamedValueTokenParsers() : base(
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser(),
@@ -159,6 +160,8 @@ public CommonChatNamedValueTokenParsers() : base(
new OutputFileNameNamedValueTokenParser(null, "chat.output.thread.id", "0111", "chat.assistant.thread.output.id"),
new OutputFileNameNamedValueTokenParser(null, "chat.output.add.thread.id", "01111", "chat.assistant.thread.output.add.id"),
+
+ ChatModelNameToken.Parser(),
};
private static INamedValueTokenParser[] _chatAssistantCreateCommandParsers = {
diff --git a/src/ai/commands/parsers/eval_command_parser.cs b/src/ai/commands/parsers/eval_command_parser.cs
index 34a4682e..2ce87bc0 100644
--- a/src/ai/commands/parsers/eval_command_parser.cs
+++ b/src/ai/commands/parsers/eval_command_parser.cs
@@ -34,6 +34,7 @@ public static bool ParseCommandValues(INamedValueTokens tokens, ICommandValues v
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser(),
diff --git a/src/ai/commands/parsers/init_command_parser.cs b/src/ai/commands/parsers/init_command_parser.cs
index b9ebc174..277337c0 100644
--- a/src/ai/commands/parsers/init_command_parser.cs
+++ b/src/ai/commands/parsers/init_command_parser.cs
@@ -23,6 +23,8 @@ public static bool ParseCommandValues(INamedValueTokens tokens, ICommandValues v
private static readonly (string name, bool valuesRequired)[] _commands = {
("init.aiservices", false),
("init.cognitiveservices", false),
+ ("init.inference", false),
+ ("init.github", false),
("init.openai.chat", false),
("init.openai.embeddings", false),
("init.openai.evaluations", false),
@@ -52,6 +54,8 @@ private static INamedValueTokenParser[] GetCommandParsers(ICommandValues values)
{
case "init.aiservices":
case "init.cognitiveservices":
+ case "init.inference":
+ case "init.github":
case "init.openai":
case "init.openai.chat":
case "init.openai.embeddings":
diff --git a/src/ai/commands/parsers/scenario_wizard_command_parser.cs b/src/ai/commands/parsers/scenario_wizard_command_parser.cs
index 1a887346..f656dd89 100644
--- a/src/ai/commands/parsers/scenario_wizard_command_parser.cs
+++ b/src/ai/commands/parsers/scenario_wizard_command_parser.cs
@@ -55,6 +55,7 @@ public CommonScenarioNamedValueTokenParsers() : base(
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser(),
diff --git a/src/ai/commands/parsers/search_command_parser.cs b/src/ai/commands/parsers/search_command_parser.cs
index 2df7354c..299f9ad8 100644
--- a/src/ai/commands/parsers/search_command_parser.cs
+++ b/src/ai/commands/parsers/search_command_parser.cs
@@ -79,6 +79,7 @@ public CommonSearchNamedValueTokenParsers() : base(
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser()
diff --git a/src/ai/commands/parsers/service_command_parser.cs b/src/ai/commands/parsers/service_command_parser.cs
index ef83f8a4..04a167ec 100644
--- a/src/ai/commands/parsers/service_command_parser.cs
+++ b/src/ai/commands/parsers/service_command_parser.cs
@@ -120,6 +120,7 @@ public CommonServiceNamedValueTokenParsers() : base(
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser(),
SubscriptionToken.Parser()
diff --git a/src/ai/commands/parsers/tool_command_parser.cs b/src/ai/commands/parsers/tool_command_parser.cs
index c0d59e84..b75df66c 100644
--- a/src/ai/commands/parsers/tool_command_parser.cs
+++ b/src/ai/commands/parsers/tool_command_parser.cs
@@ -58,6 +58,7 @@ public CommonToolNamedValueTokenParsers() : base(
new ExpandFileNameNamedValueTokenParser(),
+ ConfigEndpointTypeToken.Parser(),
ConfigEndpointUriToken.Parser(),
ConfigDeploymentToken.Parser()
diff --git a/src/ai/commands/parsers/vision_command_parser.cs b/src/ai/commands/parsers/vision_command_parser.cs
index 48455a2b..6aff23d1 100644
--- a/src/ai/commands/parsers/vision_command_parser.cs
+++ b/src/ai/commands/parsers/vision_command_parser.cs
@@ -83,6 +83,7 @@ public CommonVisionNamedValueTokenParsers() : base(
new CommonNamedValueTokenParsers(),
new IniFileNamedValueTokenParser(),
new ExpandFileNameNamedValueTokenParser(),
+ new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.type", "0011"),
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.uri", "0011"),
new Any1PinnedNamedValueTokenParser("--url", "vision.input.url", "001", "url", "vision.input.type"),
new Any1PinnedNamedValueTokenParser("--file", "vision.input.file", "001", "file", "vision.input.type"),
diff --git a/src/ai/helpers/config_environment_helpers.cs b/src/ai/helpers/config_environment_helpers.cs
index 11b9159b..9d045a0f 100644
--- a/src/ai/helpers/config_environment_helpers.cs
+++ b/src/ai/helpers/config_environment_helpers.cs
@@ -25,18 +25,30 @@ public static Dictionary GetEnvironment(INamedValues values)
env.Add("AZURE_AI_RESOURCE_NAME", ReadConfig(values, "resource"));
#endif
- env.Add("AZURE_OPENAI_KEY", ReadConfig(values, "chat.key"));
- env.Add("AZURE_OPENAI_API_KEY", ReadConfig(values, "chat.key"));
- env.Add("AZURE_OPENAI_API_VERSION", ChatCommand.GetOpenAIClientVersionNumber());
- env.Add("AZURE_OPENAI_ENDPOINT", ReadConfig(values, "chat.endpoint"));
-
- env.Add("AZURE_OPENAI_CHAT_DEPLOYMENT", ReadConfig(values, "chat.deployment"));
- env.Add("AZURE_OPENAI_EVALUATION_DEPLOYMENT", ReadConfig(values, "chat.evaluation.model.deployment.name") ?? ReadConfig(values, "chat.deployment"));
- env.Add("AZURE_OPENAI_EMBEDDING_DEPLOYMENT", ReadConfig(values, "search.embedding.model.deployment.name"));
-
- env.Add("AZURE_OPENAI_CHAT_MODEL", ReadConfig(values, "chat.model"));
- env.Add("AZURE_OPENAI_EVALUATION_MODEL", ReadConfig(values, "chat.evaluation.model.name") ?? ReadConfig(values, "chat.model"));
- env.Add("AZURE_OPENAI_EMBEDDING_MODEL", ReadConfig(values, "search.embedding.model.name"));
+ var endpointType = ReadConfig(values, "chat.endpoint.type");
+ var endpointTypeIsInference = endpointType == "inference";
+
+ if (endpointTypeIsInference)
+ {
+ env.Add("AZURE_AI_CHAT_API_KEY", ReadConfig(values, "chat.key"));
+ env.Add("AZURE_AI_CHAT_ENDPOINT", ReadConfig(values, "chat.endpoint"));
+ env.Add("AZURE_AI_CHAT_MODEL", ReadConfig(values, "chat.model"));
+ }
+ else
+ {
+ env.Add("AZURE_OPENAI_KEY", ReadConfig(values, "chat.key"));
+ env.Add("AZURE_OPENAI_API_KEY", ReadConfig(values, "chat.key"));
+ env.Add("AZURE_OPENAI_API_VERSION", ChatCommand.GetOpenAIClientVersionNumber());
+ env.Add("AZURE_OPENAI_ENDPOINT", ReadConfig(values, "chat.endpoint"));
+
+ env.Add("AZURE_OPENAI_CHAT_DEPLOYMENT", ReadConfig(values, "chat.deployment"));
+ env.Add("AZURE_OPENAI_EVALUATION_DEPLOYMENT", ReadConfig(values, "chat.evaluation.model.deployment.name") ?? ReadConfig(values, "chat.deployment"));
+ env.Add("AZURE_OPENAI_EMBEDDING_DEPLOYMENT", ReadConfig(values, "search.embedding.model.deployment.name"));
+
+ env.Add("AZURE_OPENAI_CHAT_MODEL", ReadConfig(values, "chat.model"));
+ env.Add("AZURE_OPENAI_EVALUATION_MODEL", ReadConfig(values, "chat.evaluation.model.name") ?? ReadConfig(values, "chat.model"));
+ env.Add("AZURE_OPENAI_EMBEDDING_MODEL", ReadConfig(values, "search.embedding.model.name"));
+ }
env.Add("AZURE_AI_SEARCH_ENDPOINT", ReadConfig(values, "search.endpoint"));
env.Add("AZURE_AI_SEARCH_INDEX_NAME", ReadConfig(values, "search.index.name"));
diff --git a/src/clis/vz/commands/parsers/common_vision_token_parsers.cs b/src/clis/vz/commands/parsers/common_vision_token_parsers.cs
index 4265ae36..6eaff4b4 100644
--- a/src/clis/vz/commands/parsers/common_vision_token_parsers.cs
+++ b/src/clis/vz/commands/parsers/common_vision_token_parsers.cs
@@ -18,6 +18,7 @@ public VisionServiceOptionsTokenParser() : base(
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.query.string", "00011"),
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.http.header", "00011"),
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.traffic.type", "00011"),
+ new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.type", "0011"),
new Any1ValueNamedValueTokenParser("--uri", "service.config.endpoint.uri", "0010;0001"),
new Any1ValueNamedValueTokenParser("--token.value", "service.config.token.value", "0010"),
diff --git a/src/common/details/helpers/config_set_helpers.cs b/src/common/details/helpers/config_set_helpers.cs
index f6dabdeb..29b60dd9 100644
--- a/src/common/details/helpers/config_set_helpers.cs
+++ b/src/common/details/helpers/config_set_helpers.cs
@@ -40,6 +40,8 @@ public static void ConfigCognitiveServicesAIServicesKindResource(string subscrip
actions.Add(ConfigSetLambda("@chat.key", key, "Key (chat)", key.Substring(0, 4) + "****************************", ref maxLabelWidth));
actions.Add(ConfigSetLambda("@chat.region", region, "Region (chat)", region, ref maxLabelWidth));
actions.Add(ConfigSetLambda("@chat.endpoint", endpoint, "Endpoint (chat)", endpoint, ref maxLabelWidth));
+ ConfigSet("@chat.endpoint.type", "ais");
+
if (chatDeployment != null)
{
actions.Add(ConfigSetLambda("@chat.deployment", chatDeployment.Value.Name, "Deployment (chat)", chatDeployment.Value.Name, ref maxLabelWidth));
@@ -101,6 +103,7 @@ public static void ConfigOpenAiResource(string subscriptionId, string region, st
actions.Add(ConfigSetLambda("@chat.key", key, "Key (chat)", key.Substring(0, 4) + "****************************", ref maxLabelWidth));
actions.Add(ConfigSetLambda("@chat.endpoint", endpoint, "Endpoint (chat)", endpoint, ref maxLabelWidth));
+ ConfigSet("@chat.endpoint.type", "aoai");
if (chatDeployment != null)
{
actions.Add(ConfigSetLambda("@chat.deployment", chatDeployment.Value.Name, "Deployment (chat)", chatDeployment.Value.Name, ref maxLabelWidth));
@@ -206,5 +209,33 @@ public static string ConfigSet(string atFile, string setValue, bool print = fals
return fileName;
}
+
+ public static void ConfigAzureAiInference(string endpoint, string key)
+ {
+ ConsoleHelpers.WriteLineWithHighlight($"\n`CONFIG AZURE AI INFERENCE`");
+ Console.WriteLine();
+
+ int maxLabelWidth = 0;
+ var actions = new List>(new Action[] {
+ ConfigSetLambda("@chat.endpoint", endpoint, "Endpoint", endpoint, ref maxLabelWidth),
+ ConfigSetLambda("@chat.key", key, "Key", key.Substring(0, 4) + "****************************", ref maxLabelWidth),
+ });
+ ConfigSet("@chat.endpoint.type", "inference");
+ actions.ForEach(x => x?.Invoke(maxLabelWidth));
+ }
+
+ public static void ConfigGitHub(string endpoint, string model, string token)
+ {
+ ConsoleHelpers.WriteLineWithHighlight($"\n`CONFIG AZURE AI INFERENCE/GITHUB MODELS`");
+ Console.WriteLine();
+
+ int maxLabelWidth = 0;
+ var actions = new List>(new Action[] {
+ ConfigSetLambda("@chat.endpoint", endpoint, "Endpoint", endpoint, ref maxLabelWidth),
+ ConfigSetLambda("@chat.key", token, "Token", token.Substring(0, 4) + "****************************", ref maxLabelWidth),
+ ConfigSetLambda("@chat.model", model, "Model", model, ref maxLabelWidth),
+ });
+ actions.ForEach(x => x?.Invoke(maxLabelWidth));
+ }
}
}
diff --git a/src/common/details/named_values/tokens/chat_model_name_token.cs b/src/common/details/named_values/tokens/chat_model_name_token.cs
new file mode 100644
index 00000000..ea9e2df2
--- /dev/null
+++ b/src/common/details/named_values/tokens/chat_model_name_token.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace Azure.AI.Details.Common.CLI
+{
+ public class ChatModelNameToken
+ {
+ public static NamedValueTokenData Data() => new NamedValueTokenData(_optionName, _fullName, _optionExample, _requiredDisplayName);
+ public static INamedValueTokenParser Parser(bool requireChatPart = false) => new Any1ValueNamedValueTokenParser(_optionName, _fullName, requireChatPart ? "110" : "010");
+
+ private const string _requiredDisplayName = "model name";
+ private const string _optionName = "--model";
+ private const string _optionExample = "NAME";
+ private const string _fullName = "chat.model.name";
+ }
+}
diff --git a/src/common/details/named_values/tokens/config_endpoint_type_token.cs b/src/common/details/named_values/tokens/config_endpoint_type_token.cs
new file mode 100644
index 00000000..c723dc03
--- /dev/null
+++ b/src/common/details/named_values/tokens/config_endpoint_type_token.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+namespace Azure.AI.Details.Common.CLI
+{
+ public class ConfigEndpointTypeToken
+ {
+ public static NamedValueTokenData Data() => new NamedValueTokenData(_optionName, _fullName, _optionExample, _requiredDisplayName);
+ public static INamedValueTokenParser Parser() => new Any1ValueNamedValueTokenParser(_optionName, _fullName, "0011");
+
+ private const string _requiredDisplayName = "endpoint type";
+ private const string _optionName = "--endpoint-type";
+ private const string _optionExample = "TYPE";
+ private const string _fullName = "service.config.endpoint.type";
+ }
+}
diff --git a/src/extensions/inference_extension/AzureAIInferenceChatCompletionsStreaming.cs b/src/extensions/inference_extension/AzureAIInferenceChatCompletionsStreaming.cs
new file mode 100644
index 00000000..5aa19530
--- /dev/null
+++ b/src/extensions/inference_extension/AzureAIInferenceChatCompletionsStreaming.cs
@@ -0,0 +1,76 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+using Azure;
+using Azure.Identity;
+using Azure.AI.Inference;
+
+namespace Azure.AI.Details.Common.CLI.Extensions.Inference;
+
+public class AzureAIInferenceChatCompletionsStreaming
+{
+ public AzureAIInferenceChatCompletionsStreaming(string aiChatEndpoint, string aiChatAPIKey, string? aiChatModel, string systemPrompt, string? chatHistoryJsonFile = null)
+ {
+ _systemPrompt = systemPrompt;
+ _aiChatModel = aiChatModel;
+
+ _client = string.IsNullOrEmpty(aiChatAPIKey)
+ ? new ChatCompletionsClient(new Uri(aiChatEndpoint), new DefaultAzureCredential())
+ : new ChatCompletionsClient(new Uri(aiChatEndpoint), new AzureKeyCredential(aiChatAPIKey));
+
+ _messages = new List();
+ if (!string.IsNullOrEmpty(chatHistoryJsonFile))
+ {
+ _messages.ReadChatHistoryFromFile(chatHistoryJsonFile);
+ }
+ else
+ {
+ ClearConversation();
+ }
+ }
+
+ public void ClearConversation()
+ {
+ _messages.Clear();
+ _messages.Add(new ChatRequestSystemMessage(_systemPrompt));
+ }
+
+ public List Messages { get => _messages; }
+
+ public async Task GetChatCompletionsStreamingAsync(string userPrompt, Action? callback = null)
+ {
+ _messages.Add(new ChatRequestUserMessage(userPrompt));
+ var options = new ChatCompletionsOptions(_messages);
+ if (!string.IsNullOrEmpty(_aiChatModel))
+ {
+ options.Model = _aiChatModel;
+ }
+
+ var responseContent = string.Empty;
+ var response = await _client.CompleteStreamingAsync(options);
+ await foreach (var update in response)
+ {
+ var content = update.ContentUpdate;
+
+ if (update.FinishReason == CompletionsFinishReason.ContentFiltered)
+ {
+ content = $"{content}\nWARNING: Content filtered!";
+ }
+
+ if (string.IsNullOrEmpty(content)) continue;
+
+ responseContent += content;
+ if (callback != null) callback(update);
+ }
+
+ _messages.Add(new ChatRequestAssistantMessage() { Content = responseContent });
+ return responseContent;
+ }
+
+ private string _systemPrompt;
+ private string? _aiChatModel;
+ private ChatCompletionsClient _client;
+ private List _messages;
+}
\ No newline at end of file
diff --git a/src/extensions/inference_extension/AzureInferenceHelpers.cs b/src/extensions/inference_extension/AzureInferenceHelpers.cs
new file mode 100644
index 00000000..ad4a5a88
--- /dev/null
+++ b/src/extensions/inference_extension/AzureInferenceHelpers.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+
+using Azure.AI.Inference;
+using System.Text;
+using System.ClientModel.Primitives;
+using System.Text.Json;
+
+namespace Azure.AI.Details.Common.CLI.Extensions.Inference;
+
+public static class AzureInferenceHelpers
+{
+ public static void ReadChatHistoryFromFile(this List messages, string fileName)
+ {
+ var historyFile = FileHelpers.ReadAllText(fileName, Encoding.UTF8);
+
+ var historyFileLines = historyFile.Split(Environment.NewLine);
+ var clearIfSystem = () =>
+ {
+ messages.Clear();
+ return typeof(ChatRequestSystemMessage);
+ };
+
+ foreach (var line in historyFileLines)
+ {
+ var jsonObject = JsonDocument.Parse(line);
+ JsonElement roleObj;
+
+ if (!jsonObject.RootElement.TryGetProperty("role", out roleObj))
+ {
+ continue;
+ }
+
+ var role = roleObj.GetString();
+
+ var type = role?.ToLowerInvariant() switch
+ {
+ "user" => typeof(ChatRequestUserMessage),
+ "assistant" => typeof(ChatRequestAssistantMessage),
+ "system" => clearIfSystem(),
+ "tool" => typeof(ChatRequestToolMessage),
+ _ => throw new Exception($"Unknown chat role {role}")
+ };
+
+ var message = ModelReaderWriter.Read(BinaryData.FromString(line), type, ModelReaderWriterOptions.Json) as ChatRequestMessage;
+ messages.Add(message!);
+ }
+ }
+
+ public static void SaveChatHistoryToFile(this IList messages, string fileName)
+ {
+ var history = new StringBuilder();
+
+ foreach (var message in messages)
+ {
+ var messageText = message switch
+ {
+ ChatRequestUserMessage userMessage => ModelReaderWriter.Write(userMessage, ModelReaderWriterOptions.Json).ToString(),
+ ChatRequestAssistantMessage assistantMessage => ModelReaderWriter.Write(assistantMessage, ModelReaderWriterOptions.Json).ToString(),
+ ChatRequestSystemMessage systemMessage => ModelReaderWriter.Write(systemMessage, ModelReaderWriterOptions.Json).ToString(),
+ ChatRequestToolMessage toolMessage => ModelReaderWriter.Write(toolMessage, ModelReaderWriterOptions.Json).ToString(),
+ _ => null
+ };
+
+ if (!string.IsNullOrEmpty(messageText))
+ {
+ history.AppendLine(messageText);
+ }
+ }
+
+ FileHelpers.WriteAllText(fileName, history.ToString(), Encoding.UTF8);
+ }
+}
diff --git a/src/extensions/inference_extension/BuildCommon.targets b/src/extensions/inference_extension/BuildCommon.targets
new file mode 100644
index 00000000..9813b863
--- /dev/null
+++ b/src/extensions/inference_extension/BuildCommon.targets
@@ -0,0 +1,24 @@
+
+
+
+
+ 1.0.0
+ false
+
+
+
+ $([System.DateTime]::Now.ToString('yyyyMMdd'))
+ $([System.Environment]::UserName)
+
+
+
+ $(CLIAssemblyVersion)-DEV-$(UserName)-$(CurrentDate)
+
+
+
+ $(CLIAssemblyVersion)
+ $(CLIAssemblyVersion)
+ $(CLIAssemblyInformationalVersion)
+
+
+
diff --git a/src/extensions/inference_extension/inference_extension.csproj b/src/extensions/inference_extension/inference_extension.csproj
new file mode 100644
index 00000000..8af3c252
--- /dev/null
+++ b/src/extensions/inference_extension/inference_extension.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Azure.AI.CLI.Extensions.Inference
+ net8.0
+ Azure.AI.Details.Common.CLI.Extensions.Inference
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/extensions/speech_extension/commands/parsers/common_speech_token_parsers.cs b/src/extensions/speech_extension/commands/parsers/common_speech_token_parsers.cs
index ee980284..67e80ba2 100644
--- a/src/extensions/speech_extension/commands/parsers/common_speech_token_parsers.cs
+++ b/src/extensions/speech_extension/commands/parsers/common_speech_token_parsers.cs
@@ -18,6 +18,7 @@ public SpeechConfigServiceConnectionTokenParser() : base(
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.query.string", "00011"),
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.http.header", "00011"),
new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.traffic.type", "00011"),
+ new Any1ValueNamedValueTokenParser(null, "service.config.endpoint.type", "0011"),
new Any1ValueNamedValueTokenParser("--uri", "service.config.endpoint.uri", "0010;0001"),
new Any1ValueNamedValueTokenParser("--token.value", "service.config.token.value", "0010"),
diff --git a/tests/test.yaml b/tests/test.yaml
index c69fb172..84d01203 100644
--- a/tests/test.yaml
+++ b/tests/test.yaml
@@ -86,7 +86,7 @@
^Name +Short +Name +Language +\r?$\n
^-+ +-+ +-+\r?$\n
^Environment +Variables +\.env *\r?$\n
- ^AzureML Chat Completions \(Streaming\) +aml-chat-streaming +Python *\r?$\n
+ ^Azure AI Inference Chat Completions \(Streaming\) +az-inference-chat-streaming +C#, +Python *\r?$\n
^Helper +Function +Class +Library +helper-functions +C# *\r?$\n
^OpenAI +Assistants +openai-asst +C#, +JavaScript, +Python *\r?$\n
^OpenAI +Assistants +\(Streaming\) +openai-asst-streaming +C#, +JavaScript, +Python *\r?$\n
diff --git a/tests/test3.yaml b/tests/test3.yaml
index 8a1aa9ad..68750d95 100644
--- a/tests/test3.yaml
+++ b/tests/test3.yaml
@@ -1566,16 +1566,32 @@
exit
tag: skip
-- area: ai dev new aml-chat-streaming (key)
+- area: ai dev new az-inference-chat-streaming (key)
tests:
- - class: dev new aml-chat-streaming (python)
+ - class: dev new az-inference-chat-streaming (c#)
steps:
- name: generate template
- command: ai dev new aml-chat-streaming --python
+ command: ai dev new az-inference-chat-streaming --cs
+ - name: build template
+ bash: |
+ cd az-inference-chat-streaming-cs
+ dotnet build
+ - name: run template
+ command: ai dev shell --bash "cd az-inference-chat-streaming-cs;./bin/Debug/net8.0/AzureAIInferencingChatCompletionsStreaming"
+ input: |-
+ Tell me a joke
+ Tell me another joke
+ exit
+ tag: skip
+
+ - class: dev new az-inference-chat-streaming (python)
+ steps:
+ - name: generate template
+ command: ai dev new az-inference-chat-streaming --python
- name: install requirements
bash: |
- cd aml-chat-streaming-py
+ cd az-inference-chat-streaming-py
if [ -f /etc/os-release ]; then
python3 -m venv env
source env/bin/activate
@@ -1588,7 +1604,7 @@
command: ai dev shell
arguments:
bash: |
- cd aml-chat-streaming-py
+ cd az-inference-chat-streaming-py
if [ -f /etc/os-release ]; then
source env/bin/activate
python main.py