Skip to content

Commit 1838ec9

Browse files
Merge pull request #1 from SyncfusionExamples/Update-sample-project-and-readme
Blog sample updated
2 parents d47d4e2 + db8f386 commit 1838ec9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+11843
-0
lines changed
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.12.35506.116 d17.12
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChartGenerator", "ChartGenerator\ChartGenerator.csproj", "{EC5A9A69-964B-4546-B344-41C7A240CD6D}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{EC5A9A69-964B-4546-B344-41C7A240CD6D}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
using Microsoft.SemanticKernel;
2+
using Microsoft.SemanticKernel.ChatCompletion;
3+
4+
namespace ChartGenerator
5+
{
6+
internal class ChartAIService
7+
{
8+
#region Fields
9+
10+
/// <summary>
11+
/// The EndPoint
12+
/// </summary>
13+
internal const string endpoint = "https://mobilemaui.openai.azure.com/";
14+
15+
/// <summary>
16+
/// The Deployment name
17+
/// </summary>
18+
internal const string deploymentName = "deployment name";
19+
20+
/// <summary>
21+
/// The Image Deployment name
22+
/// </summary>
23+
internal const string imageDeploymentName = "IMAGE_MODEL_NAME";
24+
25+
/// <summary>
26+
/// The API key
27+
/// </summary>
28+
internal const string key = "API key";
29+
30+
/// <summary>
31+
/// The chat completion service
32+
/// </summary>
33+
private IChatCompletionService? chatCompletions;
34+
35+
/// <summary>
36+
/// The kernal
37+
/// </summary>
38+
private Kernel? kernel;
39+
40+
/// <summary>
41+
/// The chat histroy
42+
/// </summary>
43+
private ChatHistory? chatHistory;
44+
45+
/// <summary>
46+
/// The credential valid field
47+
/// </summary>
48+
private static bool isCredentialValid;
49+
50+
/// <summary>
51+
/// The already credential validated field
52+
/// </summary>
53+
private static bool isAlreadyValidated;
54+
55+
/// <summary>
56+
/// The uri result field
57+
/// </summary>
58+
private Uri? uriResult;
59+
60+
#endregion
61+
62+
public ChartAIService()
63+
{
64+
ValidateCredential();
65+
}
66+
67+
#region Properties
68+
69+
/// <summary>
70+
/// Gets or Set a value indicating whether an credentials are valid or not.
71+
/// Returns <c>true</c> if the credentials are valid; otherwise, <c>false</c>.
72+
/// </summary>
73+
public static bool IsCredentialValid
74+
{
75+
get
76+
{
77+
return isCredentialValid;
78+
}
79+
set
80+
{
81+
isCredentialValid = value;
82+
}
83+
}
84+
85+
/// <summary>
86+
/// Gets or sets a value indicating the chat history object
87+
/// </summary>
88+
public ChatHistory? ChatHistory
89+
{
90+
get
91+
{
92+
return chatHistory;
93+
}
94+
set
95+
{
96+
chatHistory = value;
97+
}
98+
}
99+
100+
/// <summary>
101+
/// Gets or sets a value indicating the chat completions object
102+
/// </summary>
103+
public IChatCompletionService? ChatCompletions
104+
{
105+
get
106+
{
107+
return chatCompletions;
108+
}
109+
set
110+
{
111+
chatCompletions = value;
112+
}
113+
}
114+
115+
/// <summary>
116+
/// Gets or sets a value indicating the kernal object
117+
/// </summary>
118+
public Kernel? Kernel
119+
{
120+
get
121+
{
122+
return kernel;
123+
}
124+
set
125+
{
126+
kernel = value;
127+
}
128+
}
129+
130+
#endregion
131+
132+
#region Private Methods
133+
134+
/// <summary>
135+
/// Validate Azure Credentials
136+
/// </summary>
137+
private async void ValidateCredential()
138+
{
139+
#region Azure OpenAI
140+
// Use below method for Azure Open AI
141+
this.GetAzureOpenAIKernal();
142+
#endregion
143+
144+
if (isAlreadyValidated)
145+
{
146+
return;
147+
}
148+
bool isValidUri = Uri.TryCreate(endpoint, UriKind.Absolute, out uriResult)
149+
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
150+
151+
if (!isValidUri || !endpoint.Contains("http") || string.IsNullOrEmpty(key) || key.Contains("API key") || string.IsNullOrEmpty(deploymentName) || deploymentName.Contains("deployment name") || string.IsNullOrEmpty(imageDeploymentName))
152+
{
153+
ShowAlertAsync();
154+
return;
155+
}
156+
try
157+
{
158+
if (ChatHistory != null && chatCompletions != null)
159+
{
160+
// test the semantic kernal with message.
161+
ChatHistory.AddSystemMessage("Hello, Test Check");
162+
await chatCompletions.GetChatMessageContentAsync(chatHistory: ChatHistory, kernel: kernel);
163+
}
164+
}
165+
catch (Exception)
166+
{
167+
// Handle any exceptions that indicate the credentials or endpoint are invalid.
168+
ShowAlertAsync();
169+
return;
170+
}
171+
IsCredentialValid = true;
172+
isAlreadyValidated = true;
173+
}
174+
175+
#region Azure OpenAI
176+
/// <summary>
177+
/// To get the Azure open ai kernal method
178+
/// </summary>
179+
private void GetAzureOpenAIKernal()
180+
{
181+
// Create the chat history
182+
chatHistory = new ChatHistory();
183+
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, key);
184+
185+
// Get the kernal from build
186+
kernel = builder.Build();
187+
188+
//Get the chat completions from kernal
189+
chatCompletions = kernel.GetRequiredService<IChatCompletionService>();
190+
}
191+
#endregion
192+
193+
/// <summary>
194+
/// Retrieves an answer from the deployment name model using the provided user prompt.
195+
/// </summary>
196+
/// <param name="userPrompt">The user prompt.</param>
197+
/// <returns>The AI response.</returns>
198+
internal async Task<string> GetAnswerFromGPT(string userPrompt)
199+
{
200+
if (IsCredentialValid && ChatCompletions != null && ChatHistory != null)
201+
{
202+
ChatHistory.Clear();
203+
204+
// Add the user's prompt as a user message to the conversation.
205+
ChatHistory.AddUserMessage(userPrompt);
206+
try
207+
{
208+
//// Send the chat completion request to the OpenAI API and await the response.
209+
var response = await ChatCompletions.GetChatMessageContentAsync(chatHistory: ChatHistory, kernel: Kernel);
210+
return response.ToString();
211+
}
212+
catch
213+
{
214+
// If an exception occurs (e.g., network issues, API errors), return an empty string.
215+
return "";
216+
}
217+
}
218+
219+
return "";
220+
}
221+
222+
/// <summary>
223+
/// Show Alert Popup
224+
/// </summary>
225+
private async void ShowAlertAsync()
226+
{
227+
#pragma warning disable CS0618 // Type or member is obsolete
228+
if (Application.Current?.MainPage != null && !IsCredentialValid)
229+
{
230+
isAlreadyValidated = true;
231+
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");
232+
}
233+
#pragma warning restore CS0618 // Type or member is obsolete
234+
}
235+
236+
#endregion
237+
}
238+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version = "1.0" encoding = "UTF-8" ?>
2+
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:local="clr-namespace:ChartGenerator"
5+
x:Class="ChartGenerator.App">
6+
<Application.Resources>
7+
<ResourceDictionary>
8+
<ResourceDictionary.MergedDictionaries>
9+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
10+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
11+
</ResourceDictionary.MergedDictionaries>
12+
</ResourceDictionary>
13+
</Application.Resources>
14+
</Application>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace ChartGenerator
2+
{
3+
public partial class App : Application
4+
{
5+
public App()
6+
{
7+
InitializeComponent();
8+
}
9+
10+
protected override Window CreateWindow(IActivationState? activationState)
11+
{
12+
return new Window(new NavigationPage(new DesktopUI()));
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Shell
3+
x:Class="ChartGenerator.AppShell"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:ChartGenerator"
7+
Shell.FlyoutBehavior="Disabled"
8+
Title="ChartGenerator">
9+
10+
<ShellContent
11+
ContentTemplate="{DataTemplate local:MainPage}"
12+
Route="MainPage" />
13+
14+
</Shell>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace ChartGenerator
2+
{
3+
public partial class AppShell : Shell
4+
{
5+
public AppShell()
6+
{
7+
InitializeComponent();
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)