From bb5dc64a7dd52eaafd23c4c9411202f55aa6d344 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 24 Apr 2026 22:06:13 +0330 Subject: [PATCH] last ... --- AI/Configuration/XAiApiConfiguration.cs | 11 + AI/Constants/XAiProjectEnum.cs | 17 + AI/Interfaces/IXAiProvider.cs | 85 ++- AI/Services/XAiProvider.cs | 579 ++++++++++++++++-- .../Ef/XAiConversationEfRepository.cs | 11 +- .../Repositories/Ef/XAiMessageEfRepository.cs | 10 +- .../Repositories/Ef/XAiProjectEfRepository.cs | 10 +- .../Mongo/XAiConversationMongoRepository.cs | 4 + .../Mongo/XAiMessageMongoRepository.cs | 4 + .../Mongo/XAiProjectMongoRepository.cs | 6 + appsettings.Development.json | 4 +- 11 files changed, 682 insertions(+), 59 deletions(-) create mode 100644 AI/Constants/XAiProjectEnum.cs diff --git a/AI/Configuration/XAiApiConfiguration.cs b/AI/Configuration/XAiApiConfiguration.cs index 22d70ae..0aa1e61 100644 --- a/AI/Configuration/XAiApiConfiguration.cs +++ b/AI/Configuration/XAiApiConfiguration.cs @@ -8,6 +8,17 @@ namespace xAiApi.AI.Configuration /// public string Url { get; set; } + /// + /// a System Message to Introduce Model ... + /// + public string Introduction { get; set; } + + /// + /// Model Name ... + /// + /// + public string Model { get; set; } + /// /// Text Generator Model Name ... /// diff --git a/AI/Constants/XAiProjectEnum.cs b/AI/Constants/XAiProjectEnum.cs new file mode 100644 index 0000000..3b760d7 --- /dev/null +++ b/AI/Constants/XAiProjectEnum.cs @@ -0,0 +1,17 @@ +using xExceptions.Attributes; + +namespace xAiApi.AI.Constants +{ + /// + /// Several Ai Projects Type ... + /// + public enum XAiProjectEnum + { + [StringValue("None")] + None, + [StringValue("Default")] + Default, + [StringValue("Custom")] + Custom + } +} \ No newline at end of file diff --git a/AI/Interfaces/IXAiProvider.cs b/AI/Interfaces/IXAiProvider.cs index 91f658c..a96b983 100644 --- a/AI/Interfaces/IXAiProvider.cs +++ b/AI/Interfaces/IXAiProvider.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; +using xAiApi.AI.Configuration; using xAiApi.AI.Models.Entities; using xAiModels.Models; using xIdentityModels.Models; @@ -15,10 +17,11 @@ namespace xAiApi.AI.Interfaces public interface IXAiProvider { /// - /// Ai Service for Getting Features ... + /// Configuration ... /// - IXAIService AiService { get; } - + /// + public XAiApiConfiguration Configuration { get; } + // #region Helpers ... /// @@ -26,91 +29,135 @@ namespace xAiApi.AI.Interfaces /// /// /// + /// /// - Task ToDto(XAiProject entity); + Task ToDto( + XAiProject entity, + CancellationToken cancellationToken = default + ); /// /// Converts Entity to Dto ... /// /// /// + /// /// - Task ToDto(XAiMessage entity); + Task ToDto( + XAiMessage entity, + CancellationToken cancellationToken = default + ); /// /// Converts Entity to Dto ... /// /// /// + /// /// - Task ToDto(XAiConversation entity); + Task ToDto( + XAiConversation entity, + CancellationToken cancellationToken = default + ); /// /// Converts a List of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtos(IEnumerable entities); + Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ); /// /// Converts a List of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtos(IEnumerable entities); + Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ); /// /// Converts a List of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtos(IEnumerable entities); + Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ); /// /// Converts a QueryResult of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtoQueryResult(XQueryResult queryResult); + Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ); /// /// Converts a QueryResult of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtoQueryResult(XQueryResult queryResult); + Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ); /// /// Converts a QueryResult of Entities to Dtos ... /// /// /// + /// /// - Task> ToDtoQueryResult(XQueryResult queryResult); - + Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ); + /// /// Check Permission for Ai Actions ... /// + /// /// + /// /// Task HasPermission( - XUserClaimsInfoDto userInfo + string projectId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default ); /// /// Prepare Prompt ... /// /// + /// /// + /// /// Task PreparePrompt( string prompt, - XUserClaimsInfoDto userInfo + string projectId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default ); #endregion @@ -118,13 +165,17 @@ namespace xAiApi.AI.Interfaces /// Ask a Question ... /// /// + /// /// /// + /// /// Task Ask( string prompt, - Guid conversationId, - XUserClaimsInfoDto userInfo + string projectId = null, + string conversationId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default ); } } \ No newline at end of file diff --git a/AI/Services/XAiProvider.cs b/AI/Services/XAiProvider.cs index 3f1e6a5..6de8c45 100644 --- a/AI/Services/XAiProvider.cs +++ b/AI/Services/XAiProvider.cs @@ -1,10 +1,19 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.AI; +using Microsoft.SemanticKernel.ChatCompletion; +using OllamaSharp; +using xAiApi.AI.Configuration; +using xAiApi.AI.Constants; using xAiApi.AI.Extensions; using xAiApi.AI.Interfaces; +using xAiApi.AI.Interfaces.Entities; using xAiApi.AI.Models.Entities; +using xAiModels.Constants; +using xAiModels.Extensions; using xAiModels.Models; using xCommons.Extensions; using xExceptions.Constants; @@ -15,20 +24,77 @@ using xModels.Dtos; namespace xAiApi.AI.Services { + /// + /// Provide Ai Capabilities Using AI Service ... + /// using User Data Info ... + /// public class XAiProvider : IXAiProvider { + /// + /// Configuration ... + /// + /// + public XAiApiConfiguration Configuration { get; } + // - public IXAIService AiService { get; } + private readonly IChatClient chatClient; + private readonly ChatOptions chatOptions; private readonly IXIdentityProvider identityProvider; + private readonly IXAiProjectRepository aiProjectRepository; + private readonly IXAiMessageRepository aiMessagetRepository; + private readonly IXAiConversationRepository aiConversationRepository; public XAiProvider( - IXAIService aiService, - IXIdentityProvider identityProvider + XAiApiConfiguration configuration, + IXIdentityProvider identityProvider, + IXAiProjectRepository aiProjectRepository, + IXAiMessageRepository aiMessagetRepository, + IXAiConversationRepository aiConversationRepository ) { // - AiService = aiService; + Configuration = configuration; + + // this.identityProvider = identityProvider; + this.aiProjectRepository = aiProjectRepository; + this.aiMessagetRepository = aiMessagetRepository; + this.aiConversationRepository = aiConversationRepository; + + // + // Prepare Chat Model ... + chatClient = new ChatClientBuilder(new OllamaApiClient( + new Uri(configuration.Url), + configuration.Model + )) + // .UseFunctionInvocation() + .Build(); + + // + // Configuring Chant Options ... + chatOptions = new ChatOptions() + { + // + // Preparing Tools ... + // Tools = [ + // // + // // Tempreature Tool ... + // AIFunctionFactory.Create((string location, string unit) => { + // // + // var temp = Random.Shared.Next(5, 20); + // var cond = Random.Shared.Next(0, 1) == 0 ? "sunny" : "rainy"; + + // // + // var result = $"The weather is {temp} degrees C and {cond}."; + + // // + // return result; + // }, + // "get_current_weather", + // "Get the current weather in given location" + // ) + // ], + }; } // @@ -38,8 +104,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task ToDto(XAiProject entity) + public async Task ToDto( + XAiProject entity, + CancellationToken cancellationToken = default + ) { // XAiProjectDto result = null; @@ -51,11 +121,18 @@ namespace xAiApi.AI.Services result = entity.ToDto(); if (!entity.OwnerId.IsNullOrEmpty()) { - result.Owner = await GetPerson(entity.OwnerId); + // + result.Owner = await GetPerson( + entity.OwnerId, + cancellationToken + ); } // - result.Conversations = await ToDtos(entity.Conversations); + result.Conversations = await ToDtos( + entity.Conversations, + cancellationToken + ); } // @@ -67,8 +144,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task ToDto(XAiMessage entity) + public async Task ToDto( + XAiMessage entity, + CancellationToken cancellationToken = default + ) { // XAiMessageDto result = null; @@ -80,11 +161,18 @@ namespace xAiApi.AI.Services result = entity.ToDto(); if (!entity.OwnerId.IsNullOrEmpty()) { - result.Owner = await GetPerson(entity.OwnerId); + // + result.Owner = await GetPerson( + entity.OwnerId, + cancellationToken + ); } // - result.Conversation = await ToDto(entity.Conversation); + result.Conversation = await ToDto( + entity.Conversation, + cancellationToken + ); } // @@ -96,8 +184,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task ToDto(XAiConversation entity) + public async Task ToDto( + XAiConversation entity, + CancellationToken cancellationToken = default + ) { // XAiConversationDto result = null; @@ -109,12 +201,24 @@ namespace xAiApi.AI.Services result = entity.ToDto(); if (!entity.OwnerId.IsNullOrEmpty()) { - result.Owner = await GetPerson(entity.OwnerId); + // + result.Owner = await GetPerson( + entity.OwnerId, + cancellationToken + ); } // - result.Project = await ToDto(entity.Project); - result.Messages = await ToDtos(entity.Messages); + result.Project = await ToDto( + entity.Project, + cancellationToken + ); + + // + result.Messages = await ToDtos( + entity.Messages, + cancellationToken + ); } // @@ -126,18 +230,25 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtos(IEnumerable entities) + public async Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ) { // IList list = new List(); // - var enumerable = entities.ToAsyncEnumerable(); + var enumerable = entities.ToAsyncEnumerable(cancellationToken); await foreach (var entity in enumerable) { // - var dto = await ToDto(entity); + var dto = await ToDto( + entity, + cancellationToken + ); if (!dto.IsNullOrDefault()) { list.Add(dto); @@ -153,18 +264,25 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtos(IEnumerable entities) + public async Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ) { // IList list = new List(); // - var enumerable = entities.ToAsyncEnumerable(); + var enumerable = entities.ToAsyncEnumerable(cancellationToken); await foreach (var entity in enumerable) { // - var dto = await ToDto(entity); + var dto = await ToDto( + entity, + cancellationToken + ); if (!dto.IsNullOrDefault()) { list.Add(dto); @@ -180,18 +298,25 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtos(IEnumerable entities) + public async Task> ToDtos( + IEnumerable entities, + CancellationToken cancellationToken = default + ) { // IList list = new List(); // - var enumerable = entities.ToAsyncEnumerable(); + var enumerable = entities.ToAsyncEnumerable(cancellationToken); await foreach (var entity in enumerable) { // - var dto = await ToDto(entity); + var dto = await ToDto( + entity, + cancellationToken + ); if (!dto.IsNullOrDefault()) { list.Add(dto); @@ -207,8 +332,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtoQueryResult(XQueryResult queryResult) + public async Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ) { // var result = new XQueryResult(); @@ -228,7 +357,11 @@ namespace xAiApi.AI.Services // if (queryResult.Items.HasChild()) { - result.Items = await ToDtos(queryResult.Items); + // + result.Items = await ToDtos( + queryResult.Items, + cancellationToken + ); } } @@ -241,8 +374,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtoQueryResult(XQueryResult queryResult) + public async Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ) { // var result = new XQueryResult(); @@ -262,7 +399,11 @@ namespace xAiApi.AI.Services // if (queryResult.Items.HasChild()) { - result.Items = await ToDtos(queryResult.Items); + // + result.Items = await ToDtos( + queryResult.Items, + cancellationToken + ); } } @@ -275,8 +416,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - public async Task> ToDtoQueryResult(XQueryResult queryResult) + public async Task> ToDtoQueryResult( + XQueryResult queryResult, + CancellationToken cancellationToken = default + ) { // var result = new XQueryResult(); @@ -296,7 +441,11 @@ namespace xAiApi.AI.Services // if (queryResult.Items.HasChild()) { - result.Items = await ToDtos(queryResult.Items); + // + result.Items = await ToDtos( + queryResult.Items, + cancellationToken + ); } } @@ -307,27 +456,60 @@ namespace xAiApi.AI.Services /// /// Check Permission for Ai Actions ... /// + /// /// + /// /// - public async Task HasPermission(XUserClaimsInfoDto userInfo) + public async Task HasPermission( + string projectId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) { // - var result = true; + var result = + !userInfo.IsNullOrDefault() && + !userInfo.UserId.IsNullOrEmpty(); + if (!result) + { + return result; + } // - // TODO: Complete this ... + try + { + // + var person = await GetPerson( + ownerId: userInfo.UserId, + cancellationToken: cancellationToken + ); + + // + result = !person.IsNullOrDefault(); + } + catch + { + result = false; + } // - return await Task.FromResult(result); + return result; } /// /// Prepare Prompt ... /// /// + /// /// + /// /// - public async Task PreparePrompt(string prompt, XUserClaimsInfoDto userInfo) + public async Task PreparePrompt( + string prompt, + string projectId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) { // var result = prompt; @@ -344,15 +526,135 @@ namespace xAiApi.AI.Services /// Ask a Question ... /// /// + /// /// /// + /// /// - public Task Ask( + public async Task Ask( string prompt, - Guid conversationId, - XUserClaimsInfoDto userInfo + string projectId = null, + string conversationId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default ) { + // + // Access Project ... + var project = await GetProject( + userInfo: userInfo, + projectId: projectId, + cancellationToken: cancellationToken + ); + var isValid = !project.IsNullOrDefault(); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + // Check Project is Default Project or not ... + var isDefaultProject = project.Title == XAiProjectEnum.Default.GetStringValue(); + + // + // Access Conversation ... + var conversation = await GetConversation( + userInfo: userInfo, + projectId: projectId, + conversationId: conversationId, + cancellationToken: cancellationToken + ); + isValid = !conversation.IsNullOrDefault(); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + // Check First Question or not ... + var isFirstConversation = !conversation.Messages.HasChild(); + + // + // Check Permissions ... + isValid = await HasPermission( + userInfo: userInfo, + projectId: projectId, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + // Preparing Chat History ... + IList chatHistory = null; + + // + // Check if First Question ... + if (isFirstConversation) + { + // + // Add Introduction Prompt ... + chatHistory.Add( + new ChatMessage( + content: Configuration.Introduction, + role: XAiChatRole.System.ToChatRole() + ) + ); + + // + // Add Project Prompt, if not Default Project ... + if (!isDefaultProject) + { + // + chatHistory.Add( + new ChatMessage( + content: project.Prompt, + role: XAiChatRole.System.ToChatRole() + ) + ); + } + } + else + { + // + // Complete Chat History ... + // TODO: Complete this ... + } + + // + // Prepare Prompt ... + prompt = await PreparePrompt( + prompt: prompt, + userInfo: userInfo, + projectId: projectId, + cancellationToken: cancellationToken + ); + if (chatHistory.IsNull()) + { + chatHistory = new List(); + } + chatHistory.Add( + new ChatMessage( + content: prompt, + role: XAiChatRole.User.ToChatRole() + ) + ); + + // + // Getting Response Message from LLM ... + var chatResult = await chatClient + .GetResponseAsync( + options: chatOptions, + messages: chatHistory, + cancellationToken: cancellationToken + ); + + // + // TODO: Handle Here ... + + // throw new NotImplementedException(); } @@ -363,8 +665,12 @@ namespace xAiApi.AI.Services /// /// /// + /// /// - private async Task GetPerson(string ownerId) + private async Task GetPerson( + string ownerId, + CancellationToken cancellationToken = default + ) { // XPersonDto result = null; @@ -390,6 +696,203 @@ namespace xAiApi.AI.Services // return result; } + + /// + /// Retrieve Specified Project or Default ... + /// + /// + /// + /// + /// + private async Task GetProject( + string projectId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate UserInfo ... + var isValid = + !userInfo.IsNullOrDefault() && + !userInfo.UserId.IsNullOrEmpty(); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + // Check UserInfo ... + var personDto = await GetPerson( + ownerId: userInfo.UserId, + cancellationToken: cancellationToken + ); + isValid = !personDto.IsNullOrDefault(); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + XAiProject project = null; + + // + // Check Default Project is Exists or not ... + var defaultProject = await aiProjectRepository.FindOneAsync( + containsDetail: true, + ignoreSoftDeleteds: true, + whereClause: x => + x.OwnerId == userInfo.UserId && + x.Title == XAiProjectEnum.Default.GetStringValue() + ); + var isExists = !defaultProject.IsNullOrDefault(); + if (!isExists) + { + // + // Create Default Project ... + defaultProject = new XAiProject + { + Prompt = string.Empty, + OwnerId = userInfo.UserId, + Description = string.Empty, + CreatedOn = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + Title = XAiProjectEnum.Default.GetStringValue(), + }; + + // + defaultProject = await aiProjectRepository.AddAsync( + saveChanges: true, + item: defaultProject + ); + + // + isExists = !defaultProject.IsNullOrDefault(); + } + + // + // Validate Project ID ... + if (projectId.IsNullOrEmpty()) + { + // + // Default Project ... + project = defaultProject; + projectId = defaultProject.Id.ToString(); + } + else + { + // + // Special Project ... + project = await aiProjectRepository.FindOneAsync( + containsDetail: false, + ignoreSoftDeleteds: true, + whereClause: x => + x.Id.ToString() == projectId && + x.OwnerId == userInfo.UserId + ); + isExists = !project.IsNullOrDefault(); + if (!isExists) + { + // + // If Not Exists Use Default ... + project = defaultProject; + } + } + + // + // Converts to Dto ... + var result = await ToDto( + entity: project, + cancellationToken: cancellationToken + ); + + // + return result; + } + + /// + /// Retrieve Conversation for Asking ... + /// + /// + /// + /// + /// + /// + private async Task GetConversation( + string projectId = null, + string conversationId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate User Info ... + var isValid = await HasPermission( + userInfo: userInfo, + projectId: projectId, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + var project = await GetProject( + userInfo: userInfo, + projectId: projectId, + cancellationToken: cancellationToken + ); + isValid = !project.IsNullOrDefault(); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + // Check Conversation Exists ... + var result = + project.Conversations + .FirstOrDefault(x => + x.OwnerId == userInfo.UserId && + x.Id.ToString() == conversationId + ); + var isExists = + !result.IsNullOrDefault() && + !conversationId.IsNullOrEmpty(); + if (!isExists) + { + // + var title = $"Conversation {Guid.NewGuid()}"; + var conversationEntity = new XAiConversation + { + Title = title, + ProjectId = project.Id, + OwnerId = userInfo.UserId, + CreatedOn = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + }; + + // + conversationEntity = await aiConversationRepository.AddAsync( + saveChanges: true, + item: conversationEntity + ); + isExists = !conversationEntity.IsNullOrDefault(); + if (!isExists) + { + XException.NotFound.Throw(); + } + + // + result = await ToDto( + entity: conversationEntity, + cancellationToken: cancellationToken + ); + } + + // + return result; + } #endregion } } \ No newline at end of file diff --git a/Data/Repositories/Ef/XAiConversationEfRepository.cs b/Data/Repositories/Ef/XAiConversationEfRepository.cs index 995c078..54022b9 100644 --- a/Data/Repositories/Ef/XAiConversationEfRepository.cs +++ b/Data/Repositories/Ef/XAiConversationEfRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Microsoft.EntityFrameworkCore; using xAiApi.AI.Interfaces.Entities; using xAiApi.AI.Models.Entities; using xDataService.Configuration; @@ -9,6 +10,11 @@ using xDataService.Interfaces; namespace xAiApi.Data.Repositories.Ef { + /// + /// a Repository Pattern Implementation for + /// manipulating AiConversations ... + /// + /// public class XAiConversationEfRepository : XBaseEFRepository, IXAiConversationRepository where TDbContext : XDbContext { @@ -28,7 +34,10 @@ namespace xAiApi.Data.Repositories.Ef public override IQueryable GetFullDbSet() { - return dbSet; + // + return dbSet + .Include(x => x.Project) + .Include(x => x.Messages); } // diff --git a/Data/Repositories/Ef/XAiMessageEfRepository.cs b/Data/Repositories/Ef/XAiMessageEfRepository.cs index a04011d..e29ff7e 100644 --- a/Data/Repositories/Ef/XAiMessageEfRepository.cs +++ b/Data/Repositories/Ef/XAiMessageEfRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Microsoft.EntityFrameworkCore; using xAiApi.AI.Interfaces.Entities; using xAiApi.AI.Models.Entities; using xDataService.Configuration; @@ -9,6 +10,11 @@ using xDataService.Interfaces; namespace xAiApi.Data.Repositories.Ef { + /// + /// a Repository Pattern Implementation for + /// manipulating AiMessage ... + /// + /// public class XAiMessageEfRepository : XBaseEFRepository, IXAiMessageRepository where TDbContext : XDbContext { @@ -28,7 +34,9 @@ namespace xAiApi.Data.Repositories.Ef public override IQueryable GetFullDbSet() { - return dbSet; + // + return dbSet + .Include(x => x.Conversation); } // diff --git a/Data/Repositories/Ef/XAiProjectEfRepository.cs b/Data/Repositories/Ef/XAiProjectEfRepository.cs index 9970d39..c61a87b 100644 --- a/Data/Repositories/Ef/XAiProjectEfRepository.cs +++ b/Data/Repositories/Ef/XAiProjectEfRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Microsoft.EntityFrameworkCore; using xAiApi.AI.Interfaces.Entities; using xAiApi.AI.Models.Entities; using xDataService.Configuration; @@ -9,6 +10,11 @@ using xDataService.Interfaces; namespace xAiApi.Data.Repositories.Ef { + /// + /// a Repository Pattern Implementation for + /// manipulating AiProjects ... + /// + /// public class XAiProjectEfRepository : XBaseEFRepository, IXAiProjectRepository where TDbContext : XDbContext { @@ -28,7 +34,9 @@ namespace xAiApi.Data.Repositories.Ef public override IQueryable GetFullDbSet() { - return dbSet; + // + return dbSet + .Include(x => x.Conversations); } // diff --git a/Data/Repositories/Mongo/XAiConversationMongoRepository.cs b/Data/Repositories/Mongo/XAiConversationMongoRepository.cs index f7139af..b5368f9 100644 --- a/Data/Repositories/Mongo/XAiConversationMongoRepository.cs +++ b/Data/Repositories/Mongo/XAiConversationMongoRepository.cs @@ -10,6 +10,10 @@ using xDataService.MongoRepositories; namespace xAiApi.Data.Repositories.Mongo { + /// + /// a Repository Pattern Implementation for + /// manipulating AiConversations ... + /// public class XAiConversationMongoRepository : XBaseMongoRepository, IXAiConversationRepository { // diff --git a/Data/Repositories/Mongo/XAiMessageMongoRepository.cs b/Data/Repositories/Mongo/XAiMessageMongoRepository.cs index dc78dc1..0cbb446 100644 --- a/Data/Repositories/Mongo/XAiMessageMongoRepository.cs +++ b/Data/Repositories/Mongo/XAiMessageMongoRepository.cs @@ -10,6 +10,10 @@ using xDataService.MongoRepositories; namespace xAiApi.Data.Repositories.Mongo { + /// + /// a Repository Pattern Implementation for + /// manipulating AiMessage ... + /// public class XAiMessageMongoRepository : XBaseMongoRepository, IXAiMessageRepository { // diff --git a/Data/Repositories/Mongo/XAiProjectMongoRepository.cs b/Data/Repositories/Mongo/XAiProjectMongoRepository.cs index 0196e9e..5024f73 100644 --- a/Data/Repositories/Mongo/XAiProjectMongoRepository.cs +++ b/Data/Repositories/Mongo/XAiProjectMongoRepository.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Microsoft.EntityFrameworkCore; using MongoDB.Driver; using MongoDB.Driver.Linq; using xAiApi.AI.Interfaces.Entities; @@ -10,6 +11,10 @@ using xDataService.MongoRepositories; namespace xAiApi.Data.Repositories.Mongo { + /// + /// a Repository Pattern Implementation for + /// manipulating AiProjects ... + /// public class XAiProjectMongoRepository : XBaseMongoRepository, IXAiProjectRepository { // @@ -28,6 +33,7 @@ namespace xAiApi.Data.Repositories.Mongo public override IMongoQueryable GetFullDbSet() { + // return collection .AsQueryable(); } diff --git a/appsettings.Development.json b/appsettings.Development.json index 03590fd..6f96aed 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -9,7 +9,9 @@ ], "AiApiServiceConfiguration": { "Url":"http://localhost:11434", - "TextModel": "gemma3:1b" + "Model": "gemma3:1b", + "TextModel": "gemma3:1b", + "Introduction": "Your Name is xSaherElm AI, you extends by SaherElm IT Center, your trainer is Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com), you are an ai assistant which acts as a senior Software Architecture, senior Software Developer and Senior Trader" }, "IdentityServiceConfiguration": { "Authority": "https://localhost:4001",