Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ChartGeneratorAISample/ChartGenerator.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35506.116 d17.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChartGenerator", "ChartGenerator\ChartGenerator.csproj", "{EC5A9A69-964B-4546-B344-41C7A240CD6D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
238 changes: 238 additions & 0 deletions ChartGeneratorAISample/ChartGenerator/AIService/ChartsAIService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

namespace ChartGenerator
{
internal class ChartAIService
{
#region Fields

/// <summary>
/// The EndPoint
/// </summary>
internal const string endpoint = "https://mobilemaui.openai.azure.com/";

/// <summary>
/// The Deployment name
/// </summary>
internal const string deploymentName = "deployment name";

/// <summary>
/// The Image Deployment name
/// </summary>
internal const string imageDeploymentName = "IMAGE_MODEL_NAME";

/// <summary>
/// The API key
/// </summary>
internal const string key = "API key";

/// <summary>
/// The chat completion service
/// </summary>
private IChatCompletionService? chatCompletions;

/// <summary>
/// The kernal
/// </summary>
private Kernel? kernel;

/// <summary>
/// The chat histroy
/// </summary>
private ChatHistory? chatHistory;

/// <summary>
/// The credential valid field
/// </summary>
private static bool isCredentialValid;

/// <summary>
/// The already credential validated field
/// </summary>
private static bool isAlreadyValidated;

/// <summary>
/// The uri result field
/// </summary>
private Uri? uriResult;

#endregion

public ChartAIService()
{
ValidateCredential();
}

#region Properties

/// <summary>
/// Gets or Set a value indicating whether an credentials are valid or not.
/// Returns <c>true</c> if the credentials are valid; otherwise, <c>false</c>.
/// </summary>
public static bool IsCredentialValid
{
get
{
return isCredentialValid;
}
set
{
isCredentialValid = value;
}
}

/// <summary>
/// Gets or sets a value indicating the chat history object
/// </summary>
public ChatHistory? ChatHistory
{
get
{
return chatHistory;
}
set
{
chatHistory = value;
}
}

/// <summary>
/// Gets or sets a value indicating the chat completions object
/// </summary>
public IChatCompletionService? ChatCompletions
{
get
{
return chatCompletions;
}
set
{
chatCompletions = value;
}
}

/// <summary>
/// Gets or sets a value indicating the kernal object
/// </summary>
public Kernel? Kernel
{
get
{
return kernel;
}
set
{
kernel = value;
}
}

#endregion

#region Private Methods

/// <summary>
/// Validate Azure Credentials
/// </summary>
private async void ValidateCredential()
{
#region Azure OpenAI
// Use below method for Azure Open AI
this.GetAzureOpenAIKernal();
#endregion

if (isAlreadyValidated)
{
return;
}
bool isValidUri = Uri.TryCreate(endpoint, UriKind.Absolute, out uriResult)
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

if (!isValidUri || !endpoint.Contains("http") || string.IsNullOrEmpty(key) || key.Contains("API key") || string.IsNullOrEmpty(deploymentName) || deploymentName.Contains("deployment name") || string.IsNullOrEmpty(imageDeploymentName))
{
ShowAlertAsync();
return;
}
try
{
if (ChatHistory != null && chatCompletions != null)
{
// test the semantic kernal with message.
ChatHistory.AddSystemMessage("Hello, Test Check");
await chatCompletions.GetChatMessageContentAsync(chatHistory: ChatHistory, kernel: kernel);
}
}
catch (Exception)
{
// Handle any exceptions that indicate the credentials or endpoint are invalid.
ShowAlertAsync();
return;
}
IsCredentialValid = true;
isAlreadyValidated = true;
}

#region Azure OpenAI
/// <summary>
/// To get the Azure open ai kernal method
/// </summary>
private void GetAzureOpenAIKernal()
{
// Create the chat history
chatHistory = new ChatHistory();
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, key);

// Get the kernal from build
kernel = builder.Build();

//Get the chat completions from kernal
chatCompletions = kernel.GetRequiredService<IChatCompletionService>();
}
#endregion

/// <summary>
/// Retrieves an answer from the deployment name model using the provided user prompt.
/// </summary>
/// <param name="userPrompt">The user prompt.</param>
/// <returns>The AI response.</returns>
internal async Task<string> GetAnswerFromGPT(string userPrompt)
{
if (IsCredentialValid && ChatCompletions != null && ChatHistory != null)
{
ChatHistory.Clear();

// Add the user's prompt as a user message to the conversation.
ChatHistory.AddUserMessage(userPrompt);
try
{
//// Send the chat completion request to the OpenAI API and await the response.
var response = await ChatCompletions.GetChatMessageContentAsync(chatHistory: ChatHistory, kernel: Kernel);
return response.ToString();
}
catch
{
// If an exception occurs (e.g., network issues, API errors), return an empty string.
return "";
}
}

return "";
}

/// <summary>
/// Show Alert Popup
/// </summary>
private async void ShowAlertAsync()
{
#pragma warning disable CS0618 // Type or member is obsolete
if (Application.Current?.MainPage != null && !IsCredentialValid)
{
isAlreadyValidated = true;
await Application.Current.MainPage.DisplayAlert("Alert", "The Azure API key or endpoint is missing or incorrect. Please verify your credentials. You can also continue with the offline data.", "OK");
}
#pragma warning restore CS0618 // Type or member is obsolete
}

#endregion
}
}
14 changes: 14 additions & 0 deletions ChartGeneratorAISample/ChartGenerator/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ChartGenerator"
x:Class="ChartGenerator.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
15 changes: 15 additions & 0 deletions ChartGeneratorAISample/ChartGenerator/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace ChartGenerator
{
public partial class App : Application
{
public App()
{
InitializeComponent();
}

protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new NavigationPage(new DesktopUI()));
}
}
}
14 changes: 14 additions & 0 deletions ChartGeneratorAISample/ChartGenerator/AppShell.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="ChartGenerator.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ChartGenerator"
Shell.FlyoutBehavior="Disabled"
Title="ChartGenerator">

<ShellContent
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

</Shell>
10 changes: 10 additions & 0 deletions ChartGeneratorAISample/ChartGenerator/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ChartGenerator
{
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
}
Loading
Loading