diff --git a/AiAssistview/AiAssistview.csproj b/AiAssistview/AiAssistview.csproj
index 9f7c8eda..0bdc3012 100644
--- a/AiAssistview/AiAssistview.csproj
+++ b/AiAssistview/AiAssistview.csproj
@@ -7,8 +7,13 @@
-
-
+
+
+
+
+
+
+
diff --git a/AiAssistview/Components/App.razor b/AiAssistview/Components/App.razor
index 464bbe8c..58cc9291 100644
--- a/AiAssistview/Components/App.razor
+++ b/AiAssistview/Components/App.razor
@@ -17,14 +17,14 @@
display: flex;
}
- .content table {
- display: block;
- margin: 50px 10px;
- }
+ .content table {
+ display: block;
+ margin: 50px 10px;
+ }
.aiassist-container {
- margin: 10% auto;
- }
+ margin: 10% auto;
+ }
diff --git a/AiAssistview/Components/Pages/AiIntegration/AiIntegrationNav.razor b/AiAssistview/Components/Pages/AiIntegration/AiIntegrationNav.razor
index 8fae75f2..abee4eff 100644
--- a/AiAssistview/Components/Pages/AiIntegration/AiIntegrationNav.razor
+++ b/AiAssistview/Components/Pages/AiIntegration/AiIntegrationNav.razor
@@ -1,8 +1,8 @@
- 1.Gemini Integration
- 2.open AI Integration
+ 1.Gemini Integration
+ 2.open AI Integration
3.Ollama LLM Integration
|
diff --git a/AiAssistview/Components/Pages/AiIntegration/OpenAiIntegration.razor b/AiAssistview/Components/Pages/AiIntegration/OpenAiIntegration.razor
index ae8d7a69..e1a61ce8 100644
--- a/AiAssistview/Components/Pages/AiIntegration/OpenAiIntegration.razor
+++ b/AiAssistview/Components/Pages/AiIntegration/OpenAiIntegration.razor
@@ -1,7 +1,7 @@
@page "/openaiintegration"
@rendermode InteractiveServer
-@using AIAssistView_AzureAI.Components.Services
+@using AIAssistview.Components.Services
@using Syncfusion.Blazor.InteractiveChat
@using Syncfusion.Blazor.Navigations
@inject AzureOpenAIService OpenAIService
diff --git a/AiAssistview/Components/Pages/Speech/SpeechNav.razor b/AiAssistview/Components/Pages/Speech/SpeechNav.razor
index c66904f5..e884faf0 100644
--- a/AiAssistview/Components/Pages/Speech/SpeechNav.razor
+++ b/AiAssistview/Components/Pages/Speech/SpeechNav.razor
@@ -1,7 +1,7 @@
- 1.SpeechToText
+ 1.SpeechToText
2.TextToSpeech
|
diff --git a/AiAssistview/Components/Pages/Speech/SpeechToText.razor b/AiAssistview/Components/Pages/Speech/SpeechToText.razor
index 899305d3..0bbbce8a 100644
--- a/AiAssistview/Components/Pages/Speech/SpeechToText.razor
+++ b/AiAssistview/Components/Pages/Speech/SpeechToText.razor
@@ -2,7 +2,7 @@
@rendermode InteractiveServer
@using Syncfusion.Blazor.InteractiveChat
-@using AssistView_OpenAI.Components.Services
+@using AIAssistview.Components.Services
@using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Buttons
@@ -174,7 +174,7 @@
display: none;
}
-@media only screen and (max-width: 750px) {
+@@media only screen and (max-width: 750px) {
.integration-speechtotext-section {
width: 100%;
}
diff --git a/AiAssistview/Components/Pages/Speech/TextToSpeech.razor b/AiAssistview/Components/Pages/Speech/TextToSpeech.razor
index 16f8c2f5..6262971c 100644
--- a/AiAssistview/Components/Pages/Speech/TextToSpeech.razor
+++ b/AiAssistview/Components/Pages/Speech/TextToSpeech.razor
@@ -2,7 +2,7 @@
@rendermode InteractiveServer
@using Syncfusion.Blazor.InteractiveChat
-@using AssistView_OpenAI.Components.Services
+@using AIAssistview.Components.Services
@using Syncfusion.Blazor.Navigations
@inject AzureOpenAIService OpenAIService
@inject IJSRuntime JSRuntime
@@ -42,7 +42,7 @@
private string audioTooltip = "Read Aloud";
private bool IsSpeaking = false;
// If component class name isn’t Home (file is not Home.razor), update DotNetObjectReference to match the actual component type.
- private DotNetObjectReference? dotNetRef;
+ private DotNetObjectReference? dotNetRef;
protected override void OnInitialized()
{
@@ -159,7 +159,7 @@
gap: 10px;
text-align: center;
}
-@media only screen and (max-width: 750px) {
+@@media only screen and (max-width: 750px) {
.integration-texttospeech-section {
width: 100%;
}
diff --git a/AiAssistview/Components/Service/AzureOpenaiService.cs b/AiAssistview/Components/Service/AzureOpenaiService.cs
new file mode 100644
index 00000000..bbe7e290
--- /dev/null
+++ b/AiAssistview/Components/Service/AzureOpenaiService.cs
@@ -0,0 +1,87 @@
+using System.Text.Json;
+using Markdig;
+using System.Text.RegularExpressions;
+
+namespace AIAssistview.Components.Services
+{
+ public class AzureOpenAIService
+ {
+ private readonly HttpClient _httpClient;
+ private readonly string _endpoint;
+ private readonly string _apiKey;
+ private readonly string _deploymentName;
+
+ public AzureOpenAIService(HttpClient httpClient, string endpoint, string apiKey, string deploymentName)
+ {
+ _httpClient = httpClient;
+ _endpoint = endpoint;
+ _apiKey = apiKey;
+ _deploymentName = deploymentName;
+ }
+
+ public async IAsyncEnumerable GetChatResponseStreamAsync(string prompt)
+ {
+ var request = new
+ {
+ messages = new[] { new { role = "user", content = prompt } },
+ max_tokens = 500,
+ };
+
+ var url = $"{_endpoint}/openai/deployments/{_deploymentName}/chat/completions?api-version=2024-02-15-preview";
+ _httpClient.DefaultRequestHeaders.Add("api-key", _apiKey);
+
+ Stream responseStream = null;
+ List results = new List();
+
+ try
+ {
+ var response = await _httpClient.PostAsJsonAsync(url, request);
+
+ if (response.IsSuccessStatusCode)
+ {
+ responseStream = await response.Content.ReadAsStreamAsync();
+ using var jsonDocument = JsonDocument.Parse(responseStream);
+ var choices = jsonDocument.RootElement.GetProperty("choices");
+ if (choices.GetArrayLength() > 0)
+ {
+ var content = choices[0].GetProperty("message").GetProperty("content").GetString();
+ var htmlContent = Markdown.ToHtml(content);
+ htmlContent = Regex.Replace(htmlContent, @"\s+", " ").Trim();
+ // Collect each character to the results list before yielding
+ foreach (var chunk in htmlContent)
+ {
+ results.Add(chunk.ToString());
+ }
+ }
+ else
+ {
+ results.Add("Error: No choices returned in the response.");
+ }
+ }
+ else
+ {
+ var error = await response.Content.ReadAsStringAsync();
+ results.Add($"Error: {error}");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Collect the error message to be yielded later
+ results.Add($"Error: {ex.Message}");
+ }
+ finally
+ {
+ if (responseStream != null)
+ {
+ responseStream.Dispose();
+ }
+ }
+
+ // Now yield each collected result
+ foreach (var result in results)
+ {
+ yield return result;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AiAssistview/Program.cs b/AiAssistview/Program.cs
index 65d3c904..ae40bd41 100644
--- a/AiAssistview/Program.cs
+++ b/AiAssistview/Program.cs
@@ -1,6 +1,10 @@
using AiAssistview.Components;
-using AIAssistView_AzureAI.Components.Services;
using Syncfusion.Blazor;
+using AIAssistview.Components.Services;
+using Microsoft.Extensions.AI;
+using OllamaSharp;
+using Azure.AI.OpenAI;
+using Azure;
var builder = WebApplication.CreateBuilder(args);
@@ -8,7 +12,7 @@
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddSyncfusionBlazor();
-
+builder.Services.AddHttpClient();
builder.Services.AddScoped(sp =>
{
var httpClientFactory = sp.GetRequiredService();
@@ -21,6 +25,13 @@
return new AzureOpenAIService(httpClient, endpoint, apiKey, deploymentName);
});
+builder.Services.AddDistributedMemoryCache();
+
+// Ollama configuration
+builder.Services.AddChatClient(new OllamaApiClient(new Uri("http://localhost:11434/"), "llama3.2"))
+ .UseDistributedCache()
+ .UseLogging();
+
var app = builder.Build();
// Configure the HTTP request pipeline.
diff --git a/AiAssistview/wwwroot/Script/speechtotext.js b/AiAssistview/wwwroot/Script/speechtotext.js
new file mode 100644
index 00000000..1b83ba61
--- /dev/null
+++ b/AiAssistview/wwwroot/Script/speechtotext.js
@@ -0,0 +1,32 @@
+// Checks if the contenteditable element contains meaningful text and cleans up.
+window.isFooterContainsValue = function (elementref) {
+ if (!elementref) return "";
+
+ const text = (elementref.innerText || "").trim();
+
+ // If empty, normalize stray
or empty HTML to empty string
+ if (text === "") {
+ const html = (elementref.innerHTML || "").trim();
+ if (html === "
" || html === "") {
+ elementref.innerHTML = "";
+ }
+ return "";
+ }
+
+ return elementref.innerText || "";
+};
+
+// Clears the text content of a contenteditable element.
+window.emptyFooterValue = function (elementref) {
+ if (elementref) {
+ elementref.innerText = "";
+ }
+};
+
+// Updates the text content of a contenteditable element with a specified value.
+window.updateContentEditableDiv = function (element, value) {
+ if (element) {
+ // Using innerText preserves plain text; switch to innerHTML if you need HTML.
+ element.innerText = value || "";
+ }
+};
\ No newline at end of file