### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Program.cs using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; namespace xAiApi { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Startup.cs using System; using System.IO; using System.Linq; using xTagService.DI; using System.Net.Http; using xAiApi.Database; using xHttpService.DI; using xPushService.DI; using xFileService.DI; using xDataService.DI; using Newtonsoft.Json; using System.Reflection; using xAiApi.Extensions; using xStringService.DI; using xStorageService.DI; using xIdentityService.DI; using xDataService.Models; using xCommons.Extensions; using xCommons.Configurations; using System.Collections.Generic; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Newtonsoft.Json.Serialization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using IdentityModel.AspNetCore.OAuth2Introspection; using xPushService.Helpers; using xAiApi.DI; using xAiApi.Interfaces; using xAiApi.Providers; using xAiModels.DI; namespace xAiApi { public class Startup { // #region Props ... public IConfiguration Configuration { get; } private readonly List databases; private readonly XAiApiDatabaseDescriptor apiDatabaseDescriptor; #endregion // #region Constructor(s) ... public Startup(IConfiguration configuration) { // Configuration = configuration; // // Create an Api Descriptor Class Instance ... apiDatabaseDescriptor = new XAiApiDatabaseDescriptor(); databases = new List { apiDatabaseDescriptor }; } #endregion public void ConfigureServices(IServiceCollection services) { // // Register Validation Provider and all XCommons Module Services ... services.AddXCommons(); // // Register App Configuration ... services.AddXAppConfiguration(Configuration); var appConfiguration = services.GetRegisteredService(); // // Register Allowed Origins ... services.AddXCors(appConfiguration.AllowedOrigins); // // Register Swagger ... var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); services.AddXSwagger(Configuration, xmlFilePath: xmlPath); // // Register HttpService ... services.AddXHttpService(Configuration); // // Add Api V1 Versioning ... services.AddXApiV1Versioning(); // // OAuthIntrospectin Http Client Handler ... // this is for handling SSLErrors ... services.AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName) .ConfigurePrimaryHttpMessageHandler(() => { return new HttpClientHandler { ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true }; }); // // Register Authorizations ... services.AddXAuthorization(); // services.AddControllers() .AddNewtonsoftJson(x => { x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; x.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // var lifeTime = ServiceLifetime.Scoped; var repositoryType = xDataService.Constants.XRepositoryType.EF; // // Register XIdentity Service ... services.AddXIdentityService( lifeTime: lifeTime, configuration: Configuration ); // // Storage Service ... services.AddXStorageService(Configuration); // // Push Service ... services.AddXPushService( lifeTime: lifeTime, config: Configuration ); // // Preparing DataBases ... if (databases.HasChild()) { // databases .ToList() .ForEach(database => { // // Register DataBase ... services.AddXDatabase( lifeTime: lifeTime, descriptor: database, configuration: Configuration ); }); } // // Register String Service ... services.AddXStringService( lifeTime: lifeTime, repositoryType: repositoryType ); // // Register Tag Service ... services.AddXTagService( lifeTime: lifeTime, repositoryType: repositoryType ); // // Register File Service ... services.AddXFileService( lifeTime: lifeTime, repositoryType: repositoryType ); // // Register AiApi Data Service ... services.AddXAiDataService( lifeTime: lifeTime, repositoryType: repositoryType ); // // Register XAiApi Configuration ... services.AddXAiApiConfiguration(Configuration); // // Register Default Ai Service ... services.AddScoped(); services.AddScoped(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // // Configure the HTTP request pipeline. var isDevelopmentEnvironment = false; if (env.IsDevelopment()) { isDevelopmentEnvironment = true; app.UseDeveloperExceptionPage(); } // // Use Swagger Middleware ... app.UseXSwagger(); // // Force Https Redirection ... app.UseHttpsRedirection(); // // Using Cors ... app.UseXCors(); // // Using Routing ... app.UseRouting(); // // Use xIdentityService ... app.UseXIdentityService(); // // Use Authorization ... app.UseAuthorization(); // app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); // // Use Storage Service ... app.UseXStorageService(); // // Use PushService ... var pushHelper = new XPushServiceHelper(); app.UseXPushService(pushHelper); // // Using DataBase ... if (databases.HasChild()) { // databases .ToList() .ForEach(database => { // app.UseXDatabase( descriptor: database, isDevelopmentEnvironment: isDevelopmentEnvironment ); }); } // // Using String Service ... app.UseXStringService( isDevelopmentEnvironment: isDevelopmentEnvironment ); // // Using XTag Service ... app.UseXTagService( isDevelopmentEnvironment: isDevelopmentEnvironment ); // // Using File Service ... app.UseXFileService( isDevelopmentEnvironment: isDevelopmentEnvironment ); } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Configurations\XAiApiConfiguration.cs using xAiApi.Models; namespace xAiApi.Configurations { public class XAiApiConfiguration { /// /// Allowed Models to Use ... /// public XAiModelDescriptor[] Models { get; set; } = []; /// /// Allowed Prompts to Use ... /// public XAiPromptDescriptor[] Prompts { get; set; } = []; } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Constants\ConfigurationNodeNames.cs namespace xAiApi.Constants { public partial struct ConfigurationNodeNames { public const string AI_API_NODE = "AiAPiConfiguration"; } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Constants\XAiApiConstants.cs namespace xAiApi.Constants { public struct XAiApiConstants { // // Database Descriptor ... public const string XAiApiDbIdentifier = "xAiApiDb"; public const string XAiApiMigrationsAssemblyIdentifier = "xAiApi"; // public const string XDILogTag = "XAiApi"; public const string XAiApiIntroductionPromptName = "Introduction"; // public const string XAiEmbeddingModelName = "Embed"; public const string XAiEmbeddingPromptName = "Embedding"; } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Constants\XAiProvider.cs namespace xAiApi.Constants { public enum XAiProvider { None, Ollama, DeepSeek, HuggingFace } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Controllers\DefaultAiController.cs using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using xAiApi.Interfaces; using xCommons.Configurations; using xCommons.Providers; namespace xAiApi.Controllers { [Authorize] [Route ("[controller]")] public class DefaultAiController : XAiServiceControllerBase { public DefaultAiController( ILogger logger, IXDefaultAiService aiService, XAppConfiguration appConfiguration, XValidationProvider validationProvider ) : base( logger, aiService, appConfiguration, validationProvider ) { } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Controllers\DefaultEmbeddingController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using xAiApi.Interfaces; using xCommons.Configurations; using xCommons.Providers; namespace xAiApi.Controllers { [Authorize] [Route("[controller]")] public class DefaultEmbeddingController : XAiEmbeddingServiceControllerBase { public DefaultEmbeddingController( ILogger logger, IXDefaultEmbeddingService aiService, XAppConfiguration appConfiguration, XValidationProvider validationProvider ) : base( logger, aiService, appConfiguration, validationProvider ) { } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Controllers\StartupController.cs using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using xCommons.Configurations; using xCommons.Controllers; using xCommons.Providers; namespace xAiApi.Controllers { /// /// Runing when application start ... /// [Route("")] [AllowAnonymous] public class StartupController : XBaseController { public StartupController( ILogger logger, XAppConfiguration appConfiguration, XValidationProvider validationProvider ) : base( logger, appConfiguration, validationProvider ) { } /// /// Show Configured Welcome Message /// /// [HttpGet("")] [AllowAnonymous] public virtual ActionResult Index() { // var controllerName = GetControllerName(); var message = $"{AppConfiguration.WelcomeMessage}"; // return Ok(message); } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Controllers\XAiEmbeddingServiceControllerBase.cs using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using xAiApi.Interfaces; using xCommons.Configurations; using xCommons.Providers; namespace xAiApi.Controllers { [Authorize] [Route("[controller]")] public abstract class XAiEmbeddingServiceControllerBase : XAiServiceControllerBase, IXAiEmbeddingServiceControllerBase where TAiService : IXAiEmbeddingServiceBase { private readonly TAiService aiService; protected XAiEmbeddingServiceControllerBase( ILogger logger, TAiService aiService, XAppConfiguration appConfiguration, XValidationProvider validationProvider ) : base( logger, aiService, appConfiguration, validationProvider ) { this.aiService = aiService; } /// /// Request For Embedding Specified String ... /// /// /// /// [AllowAnonymous] [HttpGet("Embeding")] public async Task> Embeding( [FromQuery] string content, CancellationToken cancellationToken = default ) { // try { // // Validate ... ValidationProvider.NotEmpty(content); // var result = await aiService.Embeding( content: content, cancellationToken: cancellationToken ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Request For Embedding Specified Batch ... /// /// /// /// [AllowAnonymous] [HttpGet("Embedings")] public async Task>> Embedings( [FromQuery] string[] batch, CancellationToken cancellationToken = default ) { // try { // // Validate ... ValidationProvider.NotZeroChilds(batch); // var result = await aiService.Embedings( batch: batch, cancellationToken: cancellationToken ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Controllers\XAiServiceControllerBase.cs using System; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using xAiApi.Interfaces; using xCommons.Configurations; using xCommons.Controllers; using xCommons.Providers; namespace xAiApi.Controllers { [Authorize] [Route ("[controller]")] public abstract class XAiServiceControllerBase : XBaseController, IXAiServiceControllerBase where TAiService : IXAiServiceBase { private readonly TAiService aiService; protected XAiServiceControllerBase( ILogger logger, TAiService aiService, XAppConfiguration appConfiguration, XValidationProvider validationProvider ) : base( logger, appConfiguration, validationProvider ) { this.aiService = aiService; } /// /// Ask Question and Get Response ... /// /// /// /// [AllowAnonymous] [HttpGet("Ask")] public virtual async Task> Ask( [FromQuery] string question, CancellationToken cancellationToken = default ) { // try { // // Validate ... ValidationProvider.NotEmpty(question); // var result = await aiService.AskAsync( prompt: question, cancellationToken: cancellationToken ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Database\XAiApiDatabaseDescriptor.cs using xAiApi.Constants; using xDataService.Interfaces; using xDataService.Models; namespace xAiApi.Database { /// /// Ai Api Database Descriptor ... /// public class XAiApiDatabaseDescriptor : XDatabaseDescriptor, IXDatabaseDescriptor { public XAiApiDatabaseDescriptor() : base( name: XAiApiConstants.XAiApiDbIdentifier, repositories: [] ) { OptionsBuilder = b => b.MigrationsAssembly(XAiApiConstants.XAiApiMigrationsAssemblyIdentifier); } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Database\XAiApiDbContext.cs using Microsoft.EntityFrameworkCore; using xAiApi.Constants; using xAiModels.Providers; using xDataService.Configuration; using xDataService.Db; using xDataService.Providers; using xFileService.Providers; using xStringService.Providers; using xTagService.Providers; namespace xAiApi.Database { /// /// Db Context of AiApi ... /// public class XAiApiDbContext : XDbContext { // #region DbSets ... #endregion // #region Navigation Property Entities ... #endregion // #region Constructor ... public XAiApiDbContext( DbContextOptions options, XDataServiceConfiguration config, XEntityRegisterarHandlerService dynamicEntityHandlers ) : base( config: config, options: options, database: XAiApiConstants.XAiApiDbIdentifier, dynamicEntityHandlers: dynamicEntityHandlers, dynamicEntityRegisterarsNames: [ nameof(XTagEntityRegisterar), nameof(XFileEntityRegisterar), nameof(XStringEntityRegisterar), nameof(XAiMessageEntityRegisterar), nameof(XAiProjectEntityRegisterar), nameof(XAiConversationEntityRegisterar), ] ) { } #endregion // #region Overrides ... // public override void OnXModelCreating(ModelBuilder modelBuilder) { } // public override void OnXConfiguring(DbContextOptionsBuilder optionsBuilder) { } #endregion } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\DI\XDIHelperExtension.cs using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using xAiApi.Configurations; using xAiApi.Constants; using xAiApi.Extensions; using xCommons.Extensions; using xExceptions.Constants; namespace xAiApi.DI { public static partial class XDIHelperExtension { /// /// Extract AI Configuration ... /// /// /// public static XAiApiConfiguration GetXAiApiConfiguration(this IConfiguration source) { // XAiApiConfiguration result = null; // var section = source.GetSection(ConfigurationNodeNames.AI_API_NODE); if (!section.IsNull()) { result = section.Get(); } // return result; } /// /// Register AiApi Configuration ... /// /// /// public static void AddXAiApiConfiguration( this IServiceCollection source, IConfiguration configuration ) { // var apiConfig = configuration.GetXAiApiConfiguration(); source.AddXAiApiConfiguration(apiConfig); } /// /// Register AiApi Configuration ... /// /// /// public static void AddXAiApiConfiguration( this IServiceCollection source, XAiApiConfiguration configuration ) { // if (!configuration.IsValid()) { XException.InvalidConfiguration.Throw(); } // source.AddSingleton(configuration); } // #region Private ... /// /// a LogTag for Service ... /// private static string XLogTag = XAiApiConstants.XDILogTag; /// /// print a log in Console ... /// /// private static void Log(string message) { Console.WriteLine($"{XLogTag} => {message}"); } #endregion } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Extensions\XModelsExtensions.cs using System.Collections.Generic; using System.Linq; using xAiApi.Configurations; using xAiApi.Constants; using xAiApi.Models; using xCommons.Extensions; namespace xAiApi.Extensions { public static class XModelsExtensions { /// /// Validate a Model Descriptor ... /// /// /// public static bool IsValid(this XAiModelDescriptor source) { // var result = !source.IsNullOrDefault() && !source.Name.IsNullOrEmpty() && !source.Url.IsNullOrEmpty() && source.Url.IsValidUrl() && !source.LLM.IsNullOrEmpty() && source.Provider != Constants.XAiProvider.None; // return result; } /// /// Validate Configurations ... /// /// /// public static bool IsValid(this XAiApiConfiguration source) { // var result = !source.IsNullOrDefault() && source.Models.HasChild() && source.Models.All(m => m.IsValid()) && source.Prompts.All(m => m.IsValid()) && source.Prompts.Any(p => p.Name .Equals( XAiApiConstants.XAiApiIntroductionPromptName, System.StringComparison.InvariantCultureIgnoreCase)); // return result; } /// /// Validate Specified Param ... /// /// /// public static bool IsValid(this XAiPromptParam source) { // var result = !source.IsNullOrDefault() && !source.Name.IsNullOrEmpty() && !source.Param.IsNullOrEmpty(); // return result; } /// /// Validate Specified Prompt ... /// /// /// public static bool IsValid(this XAiPromptDescriptor source) { // var result = !source.IsNullOrDefault() && !source.Name.IsNullOrEmpty() && !source.Template.IsNullOrEmpty(); if (!result) { return result; } // if (source.Params.HasChild()) { result = result && source.Params.All(x => x.IsValid()); } // return result; } /// /// Extract Default Model Descriptor ... /// /// /// public static XAiModelDescriptor GetDefaultModel(this XAiApiConfiguration source) { // XAiModelDescriptor result = null; // if (source.IsValid()) { result = source.Models[0]; } // return result; } /// /// Retrieve Specified Model from Config ... /// /// /// /// public static XAiModelDescriptor GetModel( this XAiApiConfiguration source, string name ) { // XAiModelDescriptor result = null; // if (source.IsValid()) { // if (name.IsNullOrEmpty()) { result = source.GetDefaultModel(); } else { result = source.Models .FirstOrDefault(m => m.Name .Equals(name, System.StringComparison.InvariantCultureIgnoreCase)); } } // return result; } /// /// Retrieve Introduction Prompt ... /// /// /// public static XAiPromptDescriptor GetIntroductionPrompt(this XAiApiConfiguration source) { // XAiPromptDescriptor result = null; // if (source.IsValid()) { // result = source.Prompts .FirstOrDefault(p => p.Name .Equals( XAiApiConstants.XAiApiIntroductionPromptName, System.StringComparison.InvariantCultureIgnoreCase)); } // return result; } /// /// Select Specified Prompts and Parse it's Template /// and Generate Message ... /// /// /// /// /// public static string GetPrompt( this XAiApiConfiguration source, string name = null, IDictionary @params = null ) { // var result = string.Empty; // // Normalize ... if (name.IsNullOrEmpty()) { name = XAiApiConstants.XAiApiIntroductionPromptName; } // if (source.IsValid()) { // var prompt = source.Prompts .FirstOrDefault(p => p.Name .Equals( name, System.StringComparison.InvariantCultureIgnoreCase ) ); if (!prompt.IsNullOrDefault()) { // result = prompt.Template; // // Handle Params ... if (!@params.IsNullOrDefault() && @params.HasChild()) { // // Select Params ... var existsParams = prompt.Params .Where(p => @params.Any(pr => pr.Key == p.Name)) .Distinct() .ToList(); // // Replace Selected Params ... existsParams .ForEach(pk => { result = result.Replace(pk.Param, @params[pk.Name]); }); } } } // return result; } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Extensions\XProgramExtensions.cs using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.DependencyInjection; using xCommons.Authorization; using xCommons.Extensions; using xIdentityHelper; namespace xAiApi.Extensions { public static class XProgramExtensions { /// /// Register Authorization Policies /// /// /// public static void AddXAuthorization( this IServiceCollection services, IDictionary policies = null ) { // services.AddAuthorization(options => { // if (!policies.IsNull()) { // // Fill Policies ... using (var policiesEnumerator = policies.GetEnumerator()) { while (policiesEnumerator.MoveNext()) { var policyDescriptor = policiesEnumerator.Current; options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value); } } } // var xPolicies = XAuthorizationHelper.GetXAuthorizationPolicies(); if (!xPolicies.IsNull()) { // // Fill Policies ... using (var policiesEnumerator = xPolicies.GetEnumerator()) { while (policiesEnumerator.MoveNext()) { var policyDescriptor = policiesEnumerator.Current; options.AddPolicy(policyDescriptor.Key, policyDescriptor.Value); } } } }); // services.AddSingleton(); } /// /// Use Forward Headers Options for resolving behind a proxy issues ... /// /// /// public static void UseXForwardOptions(this IApplicationBuilder source) { // var forwardOptions = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, RequireHeaderSymmetry = false }; // forwardOptions.KnownNetworks.Clear(); forwardOptions.KnownProxies.Clear(); // // ref: https://github.com/aspnet/Docs/issues/2384 source.UseForwardedHeaders(forwardOptions); } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXAiEmbeddingServiceBase.cs using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using OllamaSharp; namespace xAiApi.Interfaces { /// /// Base Embedding Provider Service ... /// public interface IXAiEmbeddingServiceBase : IXAiServiceBase { /// /// Embedding Specified String ... /// /// /// /// Task Embeding( string content, CancellationToken cancellationToken = default ); /// /// Embedding Specified Batch ... /// /// /// /// Task> Embedings( string[] batch, CancellationToken cancellationToken = default ); /// /// Access Embedding Client ... /// /// OllamaApiClient GetEmbeddingClient(); } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXAiEmbeddingServiceControllerBase.cs using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace xAiApi.Interfaces { public interface IXAiEmbeddingServiceControllerBase : IXAiServiceControllerBase { /// /// Request For Embedding Specified String ... /// /// /// /// [HttpGet("Embeding")] Task> Embeding( [FromQuery] string content, CancellationToken cancellationToken = default ); /// /// Request For Embedding Specified Batch ... /// /// /// /// [HttpGet("Embedings")] Task>> Embedings( [FromQuery] string[] batch, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXAiServiceBase.cs using System; using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; namespace xAiApi.Interfaces { /// /// Describe a Base Service Actions of any Ai Based Services ... /// public interface IXAiServiceBase : IDisposable { /// /// Base Method for Communicate with LLM ... /// /// /// /// Task AskAsync( string prompt, CancellationToken cancellationToken = default ); /// /// Base Method for Communicate with LLM ... /// /// /// /// IAsyncEnumerable AskAsEnumerable( string prompt, CancellationToken cancellationToken = default ); /// /// Get LLM Client instance for Communicating with LLM ... /// /// /// IChatClient GetClient(string llm = null); /// /// Create Custom HttpClient for Communicating with LLM API ... /// /// /// HttpClient GetHttpClient(string url = null); /// /// Prepare a Message History List for LLM Communication based on Prompt ... /// /// /// /// IList GetHistory( string prompt = null, bool forcePrompt = true ); /// /// Prepare a Message History List for LLM Communication based on Prompt ... /// /// /// /// IList GetHistory( ChatMessage message = null, bool forceMessage = true ); } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXAiServiceControllerBase.cs using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace xAiApi.Interfaces { public interface IXAiServiceControllerBase { /// /// Ask Question and Get Response ... /// /// /// /// [HttpGet("Ask")] Task> Ask( [FromQuery] string question, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXDefaultAiService.cs namespace xAiApi.Interfaces { public interface IXDefaultAiService : IXAiServiceBase { } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Interfaces\IXDefaultEmbeddingService.cs namespace xAiApi.Interfaces { public interface IXDefaultEmbeddingService : IXAiEmbeddingServiceBase { } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Migrations\20260906032616_InitialMigrationAiApi.cs using System; using Microsoft.EntityFrameworkCore.Migrations; namespace xAiApi.Migrations { public partial class InitialMigrationAiApi : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "AiConversations", columns: table => new { Id = table.Column(nullable: false), Deleted = table.Column(nullable: false), OwnerId = table.Column(maxLength: 255, nullable: false), Title = table.Column(maxLength: 255, nullable: false), CreatedOn = table.Column(nullable: false), UpdatedAt = table.Column(nullable: false), ProjectId = table.Column(nullable: false) }, constraints: table => { table.PrimaryKey("PK_AiConversations", x => x.Id); }); migrationBuilder.CreateTable( name: "AiMessages", columns: table => new { Id = table.Column(nullable: false), Deleted = table.Column(nullable: false), OwnerId = table.Column(maxLength: 255, nullable: false), Content = table.Column(nullable: false), Role = table.Column(nullable: false), CreatedOn = table.Column(nullable: false), UpdatedAt = table.Column(nullable: false), ConversationId = table.Column(maxLength: 255, nullable: false), MeatDatas = table.Column(nullable: true) }, constraints: table => { table.PrimaryKey("PK_AiMessages", x => x.Id); }); migrationBuilder.CreateTable( name: "AiProjects", columns: table => new { Id = table.Column(nullable: false), Deleted = table.Column(nullable: false), OwnerId = table.Column(maxLength: 255, nullable: false), Title = table.Column(maxLength: 255, nullable: false), Description = table.Column(maxLength: 1000, nullable: true), Prompt = table.Column(nullable: true), CreatedOn = table.Column(nullable: false), UpdatedAt = table.Column(nullable: false) }, constraints: table => { table.PrimaryKey("PK_AiProjects", x => x.Id); }); migrationBuilder.CreateTable( name: "Files", columns: table => new { Id = table.Column(nullable: false), Deleted = table.Column(nullable: false), Type = table.Column(nullable: false), OwnerId = table.Column(maxLength: 255, nullable: false), Name = table.Column(maxLength: 255, nullable: false), Path = table.Column(nullable: false), Thumb = table.Column(nullable: true), ThumbPath = table.Column(nullable: true), UploadedOn = table.Column(nullable: false), FileName = table.Column(nullable: true), References = table.Column(nullable: true) }, constraints: table => { table.PrimaryKey("PK_Files", x => x.Id); }); migrationBuilder.CreateTable( name: "Strings", columns: table => new { Id = table.Column(nullable: false) .Annotation("Sqlite:Autoincrement", true), Deleted = table.Column(nullable: false), Language = table.Column(maxLength: 10, nullable: false), ResourceTitle = table.Column(maxLength: 255, nullable: false), TranslatedValue = table.Column(nullable: false) }, constraints: table => { table.PrimaryKey("PK_Strings", x => x.Id); }); migrationBuilder.CreateTable( name: "Tags", columns: table => new { Id = table.Column(nullable: false) .Annotation("Sqlite:Autoincrement", true), Deleted = table.Column(nullable: false), Tag = table.Column(maxLength: 255, nullable: false), References = table.Column(nullable: true) }, constraints: table => { table.PrimaryKey("PK_Tags", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "AiConversations"); migrationBuilder.DropTable( name: "AiMessages"); migrationBuilder.DropTable( name: "AiProjects"); migrationBuilder.DropTable( name: "Files"); migrationBuilder.DropTable( name: "Strings"); migrationBuilder.DropTable( name: "Tags"); } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Migrations\20260906032616_InitialMigrationAiApi.Designer.cs // using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using xAiApi.Database; namespace xAiApi.Migrations { [DbContext(typeof(XAiApiDbContext))] [Migration("20260906032616_InitialMigrationAiApi")] partial class InitialMigrationAiApi { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "3.1.14"); modelBuilder.Entity("xAiModels.Models.Entities.XAiConversation", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("ProjectId") .HasColumnType("TEXT"); b.Property("Title") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiConversations"); }); modelBuilder.Entity("xAiModels.Models.Entities.XAiMessage", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("Content") .IsRequired() .HasColumnType("TEXT"); b.Property("ConversationId") .HasColumnType("TEXT") .HasMaxLength(255); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("MeatDatas") .HasColumnType("TEXT"); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Role") .HasColumnType("INTEGER"); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiMessages"); }); modelBuilder.Entity("xAiModels.Models.Entities.XAiProject", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("Description") .HasColumnType("TEXT") .HasMaxLength(1000); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Prompt") .HasColumnType("TEXT"); b.Property("Title") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiProjects"); }); modelBuilder.Entity("xFileService.Models.Entities.XFile", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("FileName") .HasColumnType("TEXT"); b.Property("Name") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Path") .IsRequired() .HasColumnType("TEXT"); b.Property("References") .HasColumnType("TEXT"); b.Property("Thumb") .HasColumnType("TEXT"); b.Property("ThumbPath") .HasColumnType("TEXT"); b.Property("Type") .HasColumnType("INTEGER"); b.Property("UploadedOn") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("Files"); }); modelBuilder.Entity("xStringService.Models.Entities.XString", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("Language") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(10); b.Property("ResourceTitle") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("TranslatedValue") .IsRequired() .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("Strings"); }); modelBuilder.Entity("xTagService.Models.Entities.XTag", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("References") .HasColumnType("TEXT"); b.Property("Tag") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.HasKey("Id"); b.ToTable("Tags"); }); #pragma warning restore 612, 618 } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Migrations\XAiApiDbContextModelSnapshot.cs // using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using xAiApi.Database; namespace xAiApi.Migrations { [DbContext(typeof(XAiApiDbContext))] partial class XAiApiDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "3.1.14"); modelBuilder.Entity("xAiModels.Models.Entities.XAiConversation", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("ProjectId") .HasColumnType("TEXT"); b.Property("Title") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiConversations"); }); modelBuilder.Entity("xAiModels.Models.Entities.XAiMessage", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("Content") .IsRequired() .HasColumnType("TEXT"); b.Property("ConversationId") .HasColumnType("TEXT") .HasMaxLength(255); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("MeatDatas") .HasColumnType("TEXT"); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Role") .HasColumnType("INTEGER"); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiMessages"); }); modelBuilder.Entity("xAiModels.Models.Entities.XAiProject", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("CreatedOn") .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("Description") .HasColumnType("TEXT") .HasMaxLength(1000); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Prompt") .HasColumnType("TEXT"); b.Property("Title") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("UpdatedAt") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("AiProjects"); }); modelBuilder.Entity("xFileService.Models.Entities.XFile", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("TEXT"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("FileName") .HasColumnType("TEXT"); b.Property("Name") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("OwnerId") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("Path") .IsRequired() .HasColumnType("TEXT"); b.Property("References") .HasColumnType("TEXT"); b.Property("Thumb") .HasColumnType("TEXT"); b.Property("ThumbPath") .HasColumnType("TEXT"); b.Property("Type") .HasColumnType("INTEGER"); b.Property("UploadedOn") .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("Files"); }); modelBuilder.Entity("xStringService.Models.Entities.XString", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("Language") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(10); b.Property("ResourceTitle") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.Property("TranslatedValue") .IsRequired() .HasColumnType("TEXT"); b.HasKey("Id"); b.ToTable("Strings"); }); modelBuilder.Entity("xTagService.Models.Entities.XTag", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); b.Property("Deleted") .HasColumnType("INTEGER"); b.Property("References") .HasColumnType("TEXT"); b.Property("Tag") .IsRequired() .HasColumnType("TEXT") .HasMaxLength(255); b.HasKey("Id"); b.ToTable("Tags"); }); #pragma warning restore 612, 618 } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Models\XAiModelDescriptor.cs using xAiApi.Constants; namespace xAiApi.Models { /// /// Describe an Ai Model ... /// public class XAiModelDescriptor { /// /// Provider Name ... /// public string Name { get; set; } /// /// LLM Provider Url ... /// public string Url { get; set; } /// /// Model Name ... /// public string LLM { get; set; } /// /// Api Key for Connection ... /// public string ApiKey { get; set; } = null; /// /// Model Provider ... /// public XAiProvider Provider { get; set; } = XAiProvider.Ollama; } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Models\XAiPromptDescriptor.cs namespace xAiApi.Models { /// /// Describe Specified Prompt ... /// public class XAiPromptDescriptor { /// /// Prompt Name ... /// public string Name { get; set; } /// /// Prompt Template ... /// public string Template { get; set; } /// /// Prompt Description ... /// public string Description { get; set; } /// /// Prompt Template Params ... /// public XAiPromptParam[] Params { get; set; } = []; } /// /// Specified a Prompt Param ... /// public class XAiPromptParam { /// /// Param Name ... /// public string Name { get; set; } /// /// Param Identifier ... /// public string Param { get; set; } /// /// Parma Description ... /// public string Description { get; set; } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Providers\XAiEmbeddingServiceBase.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OllamaSharp; using OllamaSharp.Models; using xAiApi.Configurations; using xAiApi.Constants; using xAiApi.Extensions; using xAiApi.Interfaces; using xAiApi.Models; using xAiModels.Interfaces; using xAiService.Helpers; using xCommons.Extensions; using xExceptions.Constants; namespace xAiApi.Providers { /// /// Base Embedding Provider Service ... /// public abstract class XAiEmbeddingServiceBase : XAIServiceBase, IXAiEmbeddingServiceBase { private readonly XAiModelDescriptor descriptor; protected XAiEmbeddingServiceBase( IXAiDataProvider dataProvider, XAiApiConfiguration configuration, ILogger logger, string embeddingModelName = XAiApiConstants.XAiEmbeddingModelName ) : base( dataProvider, logger, configuration ) { // // Prepare Embedding Model Descriptor ... descriptor = configuration.GetModel(embeddingModelName); if (!descriptor.IsValid()) { XException.InvalidConfiguration.Throw(); } } /// /// Embedding Specified String ... /// /// /// /// public virtual async Task Embeding( string content, CancellationToken cancellationToken = default ) { // // Validate ... if (content.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // // Retrieve Ollama Client ... using var client = GetEmbeddingClient(); // // Create Embeding Request .... var request = new EmbedRequest { Input = [content], Model = descriptor.LLM, }; // // Make Request and Recieve Response ... var response = await client.EmbedAsync( request: request, cancellationToken: cancellationToken ); if (response.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // // Generae Result ... var result = response? .Embeddings? .FirstOrDefault() ?? []; if (result.Length == 0) { XException.ActionFailed.Throw(); } // // Normalize ... VectorHelper.Normalize(result); // return result; } /// /// Embedding Specified Batch ... /// /// /// /// public virtual async Task> Embedings( string[] batch, CancellationToken cancellationToken = default ) { // // Validate ... if (!batch.HasChild() || !batch.All(x => !x.IsNullOrEmpty()) ) { XException.InvalidArgs.Throw(); } // // Retrieve Ollama Client ... using var client = GetEmbeddingClient(); // // Create Embeding Request .... var request = new EmbedRequest { Input = [.. batch], Model = descriptor.LLM, }; // // Make Request and Recieve Response ... var response = await client.EmbedAsync( request: request, cancellationToken: cancellationToken ); if (response.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // // Generae Result ... var result = response? .Embeddings .ToArray() ?? []; // // Validate Result ... if (result.Length == 0) { XException.ActionFailed.Throw(); } // // Normalize ... foreach (var vector in result) { VectorHelper.Normalize(vector); } // return result; } /// /// Access Embedding Client ... /// /// public OllamaApiClient GetEmbeddingClient() { // var result = new OllamaApiClient(new Uri(descriptor.Url)); // return result; } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Providers\XAIServiceBase.cs using System; using System.Threading; using xAiApi.Interfaces; using xCommons.Extensions; using xAiModels.Interfaces; using xExceptions.Constants; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.Extensions.Logging; using System.Runtime.CompilerServices; using Microsoft.Extensions.AI; using xAiModels.Extensions; using xAiApi.Configurations; using xAiApi.Extensions; using System.Net.Http; using OllamaSharp; namespace xAiApi.Providers { public abstract class XAIServiceBase : IXAiServiceBase { private readonly IXAiDataProvider dataProvider; private readonly ILogger logger; private readonly XAiApiConfiguration configuration; protected XAIServiceBase( IXAiDataProvider dataProvider, ILogger logger, XAiApiConfiguration configuration ) { this.logger = logger; this.dataProvider = dataProvider; this.configuration = configuration; } // #region Actions ... /// /// Base Method for Communicate with LLM ... /// /// /// /// public virtual async Task AskAsync( string prompt, CancellationToken cancellationToken = default ) { // // Check Prompt Exists ... if (prompt.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // using var client = GetClient(); var history = GetHistory(prompt); var response = await client.GetResponseAsync( messages: history, cancellationToken: cancellationToken ); // // Validate Response ... if (!response.IsValid()) { // // Dispose Client ... client.Dispose(); XException.ActionFailed.Throw(); } // // Retrieve Response Text ... var result = response.Text; // // Dispose Client ... client.Dispose(); // return result; } /// /// Base Method for Communicate with LLM ... /// /// /// /// public virtual async IAsyncEnumerable AskAsEnumerable( string prompt, [EnumeratorCancellation] CancellationToken cancellationToken = default ) { // // Check Prompt Exists ... if (prompt.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // using var client = GetClient(); var history = GetHistory(prompt); var enumerable = client.GetStreamingResponseAsync( options: null, messages: history ); // var result = ""; await foreach (var res in enumerable) { // // Cancellation Token ... if (cancellationToken.IsCancellationRequested) { yield break; } // result += res.Text; } // // Dispose Client ... client.Dispose(); // yield return result; } /// /// Get LLM Client instance for Communicating with LLM ... /// /// /// public virtual IChatClient GetClient(string llm = null) { // // Retrieve Model Descriptor ... var modelDescriptor = configuration.GetModel(llm); if (modelDescriptor.IsNullOrDefault()) { XException.NotFound.Throw(); } // // Try to Initialize LLm ... var model = modelDescriptor.LLM; var apiKey = modelDescriptor.ApiKey; var url = new Uri(modelDescriptor.Url); var httpClient = GetHttpClient(modelDescriptor.Url); // IChatClient result = null; switch (modelDescriptor.Provider) { // case Constants.XAiProvider.Ollama: // // Instance Ollama Client using Custom HttpCLient ... var ollamaClient = new OllamaApiClient(httpClient, model); result = new ChatClientBuilder(ollamaClient) .Build(); break; // case Constants.XAiProvider.DeepSeek: break; // case Constants.XAiProvider.HuggingFace: break; // default: break; } // // // if (isOllamaBased) // { // } // else if (isDeepSeekBased) // { // // // if (apiKey is null || // string.IsNullOrWhiteSpace(apiKey)) // { // throw new Exception("Inavlid Args ..."); // } // // // var deepseekClient = new DeepSeekChatClient(apiKey: apiKey); // result = deepseekClient; // } // else // { // // // // TODO: Implement this ... // } // if (result.IsNullOrDefault()) { XException.InvalidData.Throw(); } // return result; } /// /// Create Custom HttpClient for Communicating with LLM API ... /// /// /// public virtual HttpClient GetHttpClient(string url = null) { // var result = new HttpClient { // // Disable timeout completely (not recommended for production) Timeout = Timeout.InfiniteTimeSpan, // BaseAddress = url.IsNullOrEmpty() ? null : new Uri(url), // // OR set a very long timeout (e.g., 30 minutes for large file uploads) // Timeout = TimeSpan.FromMinutes(30) }; // return result; } /// /// Prepare a Message History List for LLM Communication based on Prompt ... /// /// /// /// public virtual IList GetHistory( string prompt = null, bool forcePrompt = true ) { // // Validate Args ... if (prompt.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // // User Prompt ... var promptMessage = new ChatMessage( ChatRole.User, prompt ); // // Preparing Introduction Prompt ... var introductionPrompt = new ChatMessage( ChatRole.System, configuration.GetPrompt() ); // List result = [ introductionPrompt, ]; if (forcePrompt && prompt is not null && !string.IsNullOrWhiteSpace(prompt)) { result.Add(promptMessage); } // return result; } /// /// Prepare a Message History List for LLM Communication based on Prompt ... /// /// /// /// public virtual IList GetHistory( ChatMessage message = null, bool forceMessage = true ) { // // Preparing Introduction Prompt ... var introductionPrompt = new ChatMessage( ChatRole.System, configuration.GetPrompt() ); // List result = [ introductionPrompt, ]; if (forceMessage && message is not null) { result.Add(message); } // return result; } #endregion /// /// Base Dispose Action ... /// /// public virtual void Dispose() { } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Providers\XDefaultAiService.cs using Microsoft.Extensions.Logging; using xAiApi.Configurations; using xAiApi.Interfaces; using xAiModels.Interfaces; namespace xAiApi.Providers { public class XDefaultAiService : XAIServiceBase, IXDefaultAiService { public XDefaultAiService( IXAiDataProvider dataProvider, ILogger logger, XAiApiConfiguration configuration ) : base( dataProvider, logger, configuration ) { } } } ### FILE: C:\Users\hkhazaeeasl\Documents\Projets\XProjects\xSaherelmWorkspace\xAiApi\Providers\XDefaultEmbeddingService.cs using Microsoft.Extensions.Logging; using xAiApi.Configurations; using xAiApi.Interfaces; using xAiModels.Interfaces; namespace xAiApi.Providers { public class XDefaultEmbeddingService : XAiEmbeddingServiceBase, IXDefaultEmbeddingService { public XDefaultEmbeddingService( IXAiDataProvider dataProvider, XAiApiConfiguration configuration, ILogger logger ) : base( dataProvider, configuration, logger ) { } } }