claims, string claimType) =>
try
{
var results = await chatState._catalogService.GetCatalogItemsWithSemanticRelevance(0, 8, productDescription!);
+ for (int i = 0; i < results.Data.Count; i++)
+ {
+ results.Data[i] = results.Data[i] with { PictureUrl = chatState._productImages.GetProductImageUrl(results.Data[i].Id) };
+ }
+
return JsonSerializer.Serialize(results);
}
catch (HttpRequestException e)
diff --git a/src/WebApp/Components/Chatbot/Chatbot.razor b/src/WebApp/Components/Chatbot/Chatbot.razor
index 649dca5..4d433c8 100644
--- a/src/WebApp/Components/Chatbot/Chatbot.razor
+++ b/src/WebApp/Components/Chatbot/Chatbot.razor
@@ -6,6 +6,7 @@
@inject IJSRuntime JS
@inject NavigationManager Nav
@inject CatalogService CatalogService
+@inject IProductImageUrlProvider ProductImages
@inject BasketState BasketState
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject ILoggerFactory LoggerFactory
@@ -27,7 +28,7 @@
}
else if (missingConfiguration)
{
- The chatbot is missing required configuration. Please edit appsettings.json in the WebApp project. You'll need an API key to enable AI features.
+ The chatbot is missing required configuration. Please set 'useOpenAI = true' in eShop.AppHost/Program.cs. You'll need an API key or an Azure Subscription to enable AI features.
}
@if (thinking)
@@ -57,7 +58,7 @@
if (kernel is not null)
{
AuthenticationState auth = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- chatState = new ChatState(CatalogService, BasketState, auth.User, Nav, kernel, LoggerFactory);
+ chatState = new ChatState(CatalogService, BasketState, auth.User, Nav, ProductImages, kernel, LoggerFactory);
}
else
{
diff --git a/src/WebApp/Components/Chatbot/Chatbot.razor.css b/src/WebApp/Components/Chatbot/Chatbot.razor.css
index 27ed15b..e4f329c 100644
--- a/src/WebApp/Components/Chatbot/Chatbot.razor.css
+++ b/src/WebApp/Components/Chatbot/Chatbot.razor.css
@@ -1,7 +1,7 @@
.floating-pane {
position: fixed;
width: 25rem;
- height: 40rem;
+ height: 35rem;
right: 3rem;
bottom: 3rem;
border: 1px solid silver;
diff --git a/src/WebApp/Components/Chatbot/MessageProcessor.cs b/src/WebApp/Components/Chatbot/MessageProcessor.cs
index 5a32b7a..673c932 100644
--- a/src/WebApp/Components/Chatbot/MessageProcessor.cs
+++ b/src/WebApp/Components/Chatbot/MessageProcessor.cs
@@ -5,7 +5,7 @@
namespace eShop.WebApp.Chatbot;
-public static class MessageProcessor
+public static partial class MessageProcessor
{
public static MarkupString AllowImages(string message)
{
@@ -17,7 +17,7 @@ public static MarkupString AllowImages(string message)
var prevEnd = 0;
message = message.Replace("<", "<").Replace(">", ">");
- foreach (Match match in Regex.Matches(message, @"\!?\[([^\]]+)\]\s*\((http[^\)]+)\)"))
+ foreach (Match match in FindMarkdownImages().Matches(message))
{
var contentToHere = message.Substring(prevEnd, match.Index - prevEnd);
result.Append(HtmlEncoder.Default.Encode(contentToHere));
@@ -29,4 +29,7 @@ public static MarkupString AllowImages(string message)
return new MarkupString(result.ToString());
}
+
+ [GeneratedRegex(@"\!?\[([^\]]+)\]\s*\(([^\)]+)\)")]
+ private static partial Regex FindMarkdownImages();
}
diff --git a/src/WebApp/Components/Pages/Cart/CartPage.razor.css b/src/WebApp/Components/Pages/Cart/CartPage.razor.css
index 24efa47..3b9c568 100644
--- a/src/WebApp/Components/Pages/Cart/CartPage.razor.css
+++ b/src/WebApp/Components/Pages/Cart/CartPage.razor.css
@@ -124,7 +124,7 @@
font-size: 1rem;
font-weight: 600;
border-radius: 0.75rem;
- width: 1.5rem;
+ width: 3.5rem;
height: 1.5rem;
line-height: 100%;
display: inline-flex;
diff --git a/src/WebApp/Extensions/Extensions.cs b/src/WebApp/Extensions/Extensions.cs
index 78549c1..1aec65a 100644
--- a/src/WebApp/Extensions/Extensions.cs
+++ b/src/WebApp/Extensions/Extensions.cs
@@ -1,13 +1,21 @@
-using eShop.WebApp;
+using System;
+using Azure.AI.OpenAI;
+using eShop.WebApp;
using eShop.EventBusServiceBus;
using eShop.WebAppComponents.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.SemanticKernel;
+using Microsoft.SemanticKernel.ChatCompletion;
+using Microsoft.SemanticKernel.Connectors.OpenAI;
+using Microsoft.SemanticKernel.TextGeneration;
+using eShop.WebApp.Services.OrderStatus.IntegrationEvents;
+using eShop.Basket.API.Grpc;
public static class Extensions
{
@@ -73,17 +81,13 @@ public static void AddAuthenticationServices(this IHostApplicationBuilder builde
private static void AddAIServices(this IHostApplicationBuilder builder)
{
var openAIOptions = builder.Configuration.GetSection("AI").Get()?.OpenAI;
- if (!string.IsNullOrWhiteSpace(openAIOptions?.ApiKey))
+ var deploymentName = openAIOptions?.ChatModel;
+
+ if (!string.IsNullOrWhiteSpace(builder.Configuration.GetConnectionString("openai")) && !string.IsNullOrWhiteSpace(deploymentName))
{
- var kernelBuilder = builder.Services.AddKernel();
- if (!string.IsNullOrWhiteSpace(openAIOptions.Endpoint))
- {
- kernelBuilder.AddAzureOpenAIChatCompletion(openAIOptions.ChatModel, openAIOptions.Endpoint, openAIOptions.ApiKey);
- }
- else
- {
- kernelBuilder.AddOpenAIChatCompletion(openAIOptions.ChatModel, openAIOptions.ApiKey);
- }
+ builder.Services.AddKernel();
+ builder.AddAzureOpenAIClient("openai");
+ builder.Services.AddAzureOpenAIChatCompletion(deploymentName);
}
}
diff --git a/src/WebApp/GlobalUsings.cs b/src/WebApp/GlobalUsings.cs
index 0a14e3a..d84c2b3 100644
--- a/src/WebApp/GlobalUsings.cs
+++ b/src/WebApp/GlobalUsings.cs
@@ -1,6 +1,3 @@
global using eShop.WebApp.Components;
global using eShop.WebApp.Services;
global using eShop.ServiceDefaults;
-global using eShop.EventBus.Abstractions;
-global using eShop.WebApp.Services.OrderStatus.IntegrationEvents;
-global using eShop.Basket.API.Grpc;
diff --git a/src/WebApp/Program.cs b/src/WebApp/Program.cs
index e0aa9e3..7b64091 100644
--- a/src/WebApp/Program.cs
+++ b/src/WebApp/Program.cs
@@ -1,4 +1,7 @@
-var builder = WebApplication.CreateBuilder(args);
+using eShop.WebApp.Components;
+using eShop.ServiceDefaults;
+
+var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
@@ -20,8 +23,6 @@
app.UseAntiforgery();
-app.UseHttpsRedirection();
-
app.UseStaticFiles();
app.MapRazorComponents().AddInteractiveServerRenderMode();
diff --git a/src/WebApp/WebApp.csproj b/src/WebApp/WebApp.csproj
index 193b08e..22c9f00 100644
--- a/src/WebApp/WebApp.csproj
+++ b/src/WebApp/WebApp.csproj
@@ -16,7 +16,7 @@