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
4 changes: 2 additions & 2 deletions App/backend-api/Microsoft.GS.DPS.Host/API/ChatHost/Chat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static void AddAPIs(WebApplication app)
ChatRequestValidator validator,
ChatHost chatHost) =>
{
if(validator.Validate(request).IsValid == false)
if (!validator.Validate(request).IsValid)
{
return Results.BadRequest();
}
Expand All @@ -37,7 +37,7 @@ public static void AddAPIs(WebApplication app)
ChatRequestValidator validator,
ChatHost chatHost) =>
{
if (validator.Validate(request).IsValid == false)
if (!validator.Validate(request).IsValid)
{
return Results.BadRequest();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ DPS.API.KernelMemory kernelMemory
await kernelMemory.DeleteDocument(documentId);
return Results.Ok(new DocumentDeletedResult() { IsDeleted = true });
}
#pragma warning disable CA1031 // Must catch all to log and keep the process alive
catch (Exception ex)
{
app.Logger.LogError(ex, "An error occurred while deleting a document.");
return Results.BadRequest(new DocumentDeletedResult() { IsDeleted = false });
}
#pragma warning restore CA1031
})
.DisableAntiforgery();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public static void AddAPIs(WebApplication app)
var document = await documentRepository.FindByDocumentIdAsync(DocumentId);

//Check if the thumbnail is already in the cache
if (thumbnails.ContainsKey(document.MimeType))
if (thumbnails.TryGetValue(document.MimeType, out var thumbnail))
{
return Results.File(thumbnails[document.MimeType], "image/png");
return Results.File(thumbnail, "image/png");
}
else
{
Expand Down Expand Up @@ -108,14 +108,7 @@ public static void AddAPIs(WebApplication app)
{
DPS.Storage.Document.Entities.Document result = await documents.GetDocument(DocumentId);

if (result == null)
{
return Results.NotFound();
}
else
{
return Results.Ok(result);
}
return result == null ? Results.NotFound() : Results.Ok(result);
}
)
.DisableAntiforgery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public static void Inject(IHostApplicationBuilder builder)
.AddSingleton<Microsoft.GS.DPS.API.UserInterface.DataCacheManager>()
.AddSingleton<Microsoft.SemanticKernel.Kernel>(x =>
{
var aiService = x.GetRequiredService<IOptions<AIServices>>().Value;
return Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(deploymentName: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["ModelName"] ?? "",
endpoint: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["Endpoint"] ?? "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
using System;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;

namespace Microsoft.GS.DPSHost.Helpers
{
/// <summary>
/// The Azure Credential Helper class
/// </summary>
public static class AzureCredentialHelper
{
/// <summary>
/// Get the Azure Credentials based on the environment type
/// </summary>
/// <param name="clientId">The client Id in case of User assigned Managed identity</param>
/// <returns>The Credential Object</returns>
public static TokenCredential GetAzureCredential(string? clientId = null)
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";

if (string.Equals(env, "Development", StringComparison.OrdinalIgnoreCase))
{
return new DefaultAzureCredential(); // CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in development
}
else
{
return clientId != null
? new ManagedIdentityCredential(clientId)
: new ManagedIdentityCredential();
}
}
}
using System;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;

namespace Microsoft.GS.DPSHost.Helpers
{
/// <summary>
/// The Azure Credential Helper class
/// </summary>
public static class AzureCredentialHelper
{
/// <summary>
/// Get the Azure Credentials based on the environment type
/// </summary>
/// <param name="clientId">The client Id in case of User assigned Managed identity</param>
/// <returns>The Credential Object</returns>
public static TokenCredential GetAzureCredential(string? clientId = null)
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";

// CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in development
return string.Equals(env, "Development", StringComparison.OrdinalIgnoreCase)
? new DefaultAzureCredential() // CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in development
: (clientId != null ? new ManagedIdentityCredential(clientId) : new ManagedIdentityCredential());
}
}
}
14 changes: 3 additions & 11 deletions App/backend-api/Microsoft.GS.DPS/API/ChatHost/ChatHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static ChatHost()
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = System.IO.Path.GetDirectoryName(assemblyLocation);
// binding assembly directory with file path (Prompts/Chat_SystemPrompt.txt)
var systemPromptFilePath = System.IO.Path.Combine(assemblyDirectory, "Prompts/Chat_SystemPrompt.txt");
var systemPromptFilePath = System.IO.Path.Combine(assemblyDirectory, "Prompts", "Chat_SystemPrompt.txt");
ChatHost.s_systemPrompt = System.IO.File.ReadAllText(systemPromptFilePath);
ChatHost.s_assistancePrompt =
@"
Expand All @@ -74,15 +74,7 @@ Please feel free to ask me any questions related to those documents and contents

private async Task<ChatSession> makeNewSession(string? chatSessionId)
{
var sessionId = string.Empty;
if(string.IsNullOrEmpty(chatSessionId))
{
sessionId = Guid.NewGuid().ToString();
}
else
{
sessionId = chatSessionId;
}
var sessionId = string.IsNullOrEmpty(chatSessionId) ? Guid.NewGuid().ToString() : chatSessionId;

//Create New Chat History
this.chatHistory = new ChatHistory();
Expand All @@ -92,7 +84,7 @@ private async Task<ChatSession> makeNewSession(string? chatSessionId)
//Create a new ChatSession Entity for Saving into Azure Cosmos
return new ChatSession()
{
SessionId = sessionId, // New Session ID
SessionId = this.sessionId, // New Session ID
StartTime = DateTime.UtcNow // Session Created Time
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static KernelMemory()
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = System.IO.Path.GetDirectoryName(assemblyLocation);
// binding assembly directory with file path (Prompts/KeywordExtract_SystemPrompt.txt)
var systemPromptFilePath = System.IO.Path.Combine(assemblyDirectory, "Prompts/KeywordExtract_SystemPrompt.txt");
var systemPromptFilePath = System.IO.Path.Combine(assemblyDirectory, "Prompts", "KeywordExtract_SystemPrompt.txt");
KernelMemory.keywordExtractorPrompt = System.IO.File.ReadAllText(systemPromptFilePath);
}

Expand Down Expand Up @@ -197,7 +197,7 @@ private async Task<string> getSummary(string documentId, string fileName)

return keywordDict;
}
catch (Exception ex)
catch (Exception)
{
return new Dictionary<string, string>();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,86 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using Microsoft.GS.DPS.Storage.Document;
using Timers =System.Timers;

namespace Microsoft.GS.DPS.API.UserInterface
{
public class DataCacheManager
{
private readonly DocumentRepository _documentRepository;
private Dictionary<string, List<string>> _keywordCache;
private readonly Timers.Timer _cacheTimer;
private readonly object _cacheLock = new object();

public DataCacheManager(DocumentRepository documentRepository)
{
_documentRepository = documentRepository;
_keywordCache = new Dictionary<string, List<string>>();
_cacheTimer = new Timers.Timer(5 * 60 * 1000); // 5 minutes
_cacheTimer.Elapsed += async (sender, e) => await RefreshCacheAsync();
_cacheTimer.Start();
}

public async Task<Dictionary<string, List<string>>> GetConsolidatedKeywordsAsync()
{
if (_keywordCache.Count == 0)
{
await RefreshCacheAsync();
}

lock (_cacheLock)
{
return new Dictionary<string, List<string>>(_keywordCache);
}
}

public async Task RefreshCacheAsync()
{
var consolidatedKeywords = new Dictionary<string, List<string>>();
var documents = await _documentRepository.GetAllDocuments();

foreach (var document in documents)
{
if (document.Keywords != null)
{
foreach (var keywordDict in document.Keywords)
{
if (!consolidatedKeywords.ContainsKey(keywordDict.Key))
{
consolidatedKeywords[keywordDict.Key] = new List<string>();
}

var values = keywordDict.Value.Split(',').Select(v => v.Trim()).ToArray();

foreach (var value in values)
{
if (!consolidatedKeywords[keywordDict.Key].Contains(value))
{
consolidatedKeywords[keywordDict.Key].Add(value);
}
}

consolidatedKeywords[keywordDict.Key] = consolidatedKeywords[keywordDict.Key].OrderBy(v => v).ToList();
}
}
}

consolidatedKeywords = consolidatedKeywords.OrderBy(k => k.Key).ToDictionary(k => k.Key, v => v.Value);

lock (_cacheLock)
{
_keywordCache = consolidatedKeywords;
}
}

public void ManualRefresh()
{
_cacheTimer.Stop();
_cacheTimer.Start();
Task.Run(async () => await RefreshCacheAsync());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using Microsoft.GS.DPS.Storage.Document;
using Timers =System.Timers;

namespace Microsoft.GS.DPS.API.UserInterface
{
public class DataCacheManager
{
private readonly DocumentRepository _documentRepository;
private Dictionary<string, List<string>> _keywordCache;
private readonly Timers.Timer _cacheTimer;
private readonly object _cacheLock = new object();

public DataCacheManager(DocumentRepository documentRepository)
{
_documentRepository = documentRepository;
_keywordCache = new Dictionary<string, List<string>>();
_cacheTimer = new Timers.Timer(5 * 60 * 1000); // 5 minutes
_cacheTimer.Elapsed += async (sender, e) => await RefreshCacheAsync();
_cacheTimer.Start();
}

public async Task<Dictionary<string, List<string>>> GetConsolidatedKeywordsAsync()
{
if (_keywordCache.Count == 0)
{
await RefreshCacheAsync();
}

lock (_cacheLock)
{
return new Dictionary<string, List<string>>(_keywordCache);
}
}

public async Task RefreshCacheAsync()
{
var consolidatedKeywords = new Dictionary<string, List<string>>();
var documents = await _documentRepository.GetAllDocuments();

foreach (var document in documents.Where(d => d.Keywords != null))
{
foreach (var keywordDict in document.Keywords)
{
if (!consolidatedKeywords.ContainsKey(keywordDict.Key))
{
consolidatedKeywords[keywordDict.Key] = new List<string>();
}

var values = keywordDict.Value.Split(',').Select(v => v.Trim()).ToArray();

foreach (var value in values)
{
if (!consolidatedKeywords[keywordDict.Key].Contains(value))
{
consolidatedKeywords[keywordDict.Key].Add(value);
}
}
Comment on lines +56 to +62

consolidatedKeywords[keywordDict.Key] = consolidatedKeywords[keywordDict.Key].OrderBy(v => v).ToList();
}
}

consolidatedKeywords = consolidatedKeywords.OrderBy(k => k.Key).ToDictionary(k => k.Key, v => v.Value);

lock (_cacheLock)
{
_keywordCache = consolidatedKeywords;
}
}

public void ManualRefresh()
{
_cacheTimer.Stop();
_cacheTimer.Start();
Task.Run(async () => await RefreshCacheAsync());
}
}
}
Loading
Loading