### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Configurations\XAIServiceConfiguration.cs namespace xAiService.Configurations { public partial class XAIServiceConfiguration { public string Url { get; set; } public string XPoweredValue { get; set; } public int DefaultClientTimeout { get; set; } = 360; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\ConfigurationNodeNames.cs namespace xAiService.Constants { public partial struct ConfigurationNodeNames { public const string AI_SERVICE_NODE = "AIServiceConfiguration"; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiApiConstants.cs namespace xAiService.Constants { public struct XAiApiQueryParams { public const string Prompt = "prompt"; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Constants\XAiApiEndpoint.cs using xExceptions.Attributes; namespace xAiService.Constants { public enum XAiApiEndpoint { [StringValue("AskAI")] Ask, [StringValue("AskAIStream")] Stream, } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\DI\XDIHelperExtension.cs using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using xAiService.Configurations; using xAiService.Constants; using xAiService.Extensions; using xAiService.Interfaces; using xAiService.Services; using xCommons.Extensions; using xExceptions.Constants; namespace xAiService.DI { public static partial class XDIHelperExtension { /// /// Extract AI Service Configuration ... /// /// /// public static XAIServiceConfiguration GetXAIServiceConfiguration(this IConfiguration source) { // XAIServiceConfiguration result = null; // var section = source.GetSection(ConfigurationNodeNames.AI_SERVICE_NODE); if (!section.IsNull()) { result = section.Get(); } // return result; } /// /// Add AI Service Configuration ... /// /// /// public static void AddXAIServiceConfiguration( this IServiceCollection source, XAIServiceConfiguration configuration ) { source.AddSingleton(configuration); } /// /// Adding XAiService ... /// /// /// /// public static void AddXAIService( this IServiceCollection services, IConfiguration configuration, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // var config = configuration.GetXAIServiceConfiguration(); AddAIService( services, config, lifeTime ); } /// /// Adding XAiService ... /// /// /// /// public static void AddXAIService( this IServiceCollection services, XAIServiceConfiguration configuration, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // AddAIService( services, configuration, lifeTime ); } // #region Private ... /// /// a LogTag for Service ... /// private static string XLogTag = "XFileService"; /// /// print a log in Console ... /// /// private static void Log(string message) { Console.WriteLine($"{XLogTag} => {message}"); } /// /// Adding Ai Service ... /// /// /// /// private static void AddAIService( this IServiceCollection services, XAIServiceConfiguration configuration, ServiceLifetime lifeTime = ServiceLifetime.Singleton ) { // var exception = XException.InvalidArgs.ToException(); ; // // Services ... var isServicesExists = !services.IsNull(); if (!isServicesExists) { // Log("AddAIService failed, services not provided ..."); throw exception; } // // Lifetime ... var isLifetimeExists = !lifeTime.IsNull(); if (!isLifetimeExists) { // Log("AddAIService failed, lifetime not provided ..."); throw exception; } // // Check Dependencies Exists ... var isDependenciesPassed = true; if (!isDependenciesPassed) { // Log("AddAIService failed due Dependencies Issues, not provided ..."); throw exception; } // // Validate Configurations ... var isConfigurationExists = !configuration.IsNull() && configuration.IsValid(); if (!isConfigurationExists) { // Log("AddAIService failed due InValid Service Configuration or not provided ..."); throw exception; } // // Register Configurations ... services.AddXAIServiceConfiguration(configuration); // // Register Services ... services.Add(new ServiceDescriptor(typeof(IXAiService), typeof(XAiService), lifeTime)); } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Extensions\ConfigurationExtensions.cs using xAiService.Configurations; using xCommons.Extensions; namespace xAiService.Extensions { public static class ModelExtensions { /// /// Validate XAiServiceConfiguration ... /// /// /// public static bool IsValid(this XAIServiceConfiguration source) { // bool result = !source.IsNull() && !source.Url.IsNullOrEmpty() && source.Url.IsValidUrl(); // return result; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Extensions\PromptExtensions.cs using System.Collections.Generic; using System.Linq; using xAiService.Models.Dtos; using xCommons.Extensions; namespace xAiService.Extensions { public static class PromptExtensions { /// /// Get Template Params Filled Prompt ... /// /// /// /// public static string GetMessage( this XPromptDto source, IDictionary @params = null ) { // var result = string.Empty; // if (!source.IsNullOrDefault() && !source.Prompt.IsNullOrEmpty() ) { result = source.Prompt; } // // Check Params Conditions ... if (!source.Params.IsNullOrDefault() && source.Params.HasChild() && !@params.IsNullOrDefault() && @params.HasChild() ) { // // Select Params ... var existsParams = source.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\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Helpers\XPromptHelper.cs using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using xAiService.Models.Dtos; using xCommons.Extensions; namespace xAiService.Helpers { public static class XPromptHelper { /// /// Holds Initialized Prompts ... /// private static XPromptsDto prompts; /// /// Initialize Prompt Helper ... /// /// /// /// public static void Initialize(string path = "prompts.json") { // // Create full Path and Check File Exists ... var fullPath = Path.Combine(AppContext.BaseDirectory, path); if (!File.Exists(fullPath)) { throw new Exception($"Prompts Resources not found: {fullPath}"); } // // Read File as Json Text ... var json = File.ReadAllText(fullPath); var options = new JsonSerializerOptions { AllowTrailingCommas = true, PropertyNameCaseInsensitive = true, ReadCommentHandling = JsonCommentHandling.Skip, Converters = { new JsonStringEnumConverter( namingPolicy: null, allowIntegerValues: false ) } }; // // Serialized Root Object ... var root = JsonSerializer.Deserialize(json, options); if (!root.IsNullOrDefault()) { prompts = new XPromptsDto { Prompts = root.Prompts }; } } /// /// Retrieve all Allowed Prompts as Enumerable ... /// /// public static IEnumerable GetPrompts() { return prompts!.Prompts.AsEnumerable(); } /// /// Get Specified Prompt ... /// /// /// /// public static XPromptDto GetPrompt(string name) { // return GetPrompts() .FirstOrDefault(p => p.Name == name); } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Interfaces\IXAiService.cs using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; using xAiService.Configurations; using xIdentityModels.Models; using xIdentityService.Interfaces; namespace xAiService.Interfaces { public interface IXAiService : IXBaseIdentityHttpProvider { /// /// XAiService Configurations ... /// /// XAIServiceConfiguration Configuration { get; } // #region Text Actions ... /// /// Generated Response ... /// /// /// /// /// public Task GetResponseAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ); /// /// Generated Response ... /// /// /// /// /// public Task GetTextResponseAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ); /// /// Generate Text Response Stream ... /// /// /// /// /// Task GetTextReponseStreamAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Interfaces\IXAiServiceControllerBase.cs using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace xAiService.Interfaces { public interface IXAiServiceControllerBase { Task> Ask( [FromQuery] string prompt, CancellationToken cancellationToken = default ); Task AskStream( [FromQuery] string prompt, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Models\Dtos\XPromptsDto.cs namespace xAiService.Models.Dtos { /// /// Described Prompts in app ... /// public class XPromptsDto { public XPromptDto[] Prompts { get; set; } = []; } /// /// a Single Prompt Description ... /// public class XPromptDto { /// /// Prompt Name ... /// public string Name { get; set; } /// /// Prompt Template Message ... /// public string Prompt { get; set; } /// /// Prompt Description ... /// public string Description { get; set; } /// /// Describe Prompt Params ... /// public virtual XPromptParamDto[] Params { get; set; } = null; } /// /// Prompt Param used to Fill dynamic Datas to Specified Prompts ... /// public class XPromptParamDto { /// /// Param Name ... /// public string Name { get; set; } /// /// Parma Identifier ... /// public string Param { get; set; } /// /// Param Description ... /// public string Description { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xAiService\Services\XAiService.cs using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; using Microsoft.Extensions.Logging; using xAiService.Configurations; using xAiService.Constants; using xAiService.Interfaces; using xCommons.Providers; using xHttpService.Constants; using xIdentityModels.Models; using xIdentityService.Interfaces; using xIdentityService.Providers; namespace xAiService.Services { public class XAiService : XBaseIdentityHttpProvider, IXAiService { /// /// XAiService Configurations ... /// /// public XAIServiceConfiguration Configuration { get; } public XAiService( ILogger logger, IXTokenProvider tokenProvider, IXIdentityProvider identityProvider, XAIServiceConfiguration configuration, XValidationProvider validationProvider ) : base( configuration.Url, logger, configuration.XPoweredValue, configuration.DefaultClientTimeout, tokenProvider, identityProvider, validationProvider ) { } // #region Text Actions ... /// /// Generated Response ... /// /// /// /// /// public Task GetResponseAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ) { throw new System.NotImplementedException(); } /// /// Generated Response ... /// /// /// /// /// public async Task GetTextResponseAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ) { // // Validate Args ... ValidationProvider.NotEmpty(prompt); // var client = GetRestClient(userInfo); var request = GetRestRequet( endpoint: XAiApiEndpoint.Ask, addXPoweredValue: true, queryStrings: new Dictionary { { XAiApiQueryParams.Prompt, prompt } } ); // var response = await RunRestRequest( client, request, XHttpMethod.GET, cancellationToken: cancellationToken ); // return response; } /// /// Generate Text Response Stream ... /// /// /// /// /// public async Task GetTextReponseStreamAsync( string prompt, XUserClaimsInfoDto userInfo, CancellationToken cancellationToken = default ) { // // Validate Args ... ValidationProvider .GroupValidationBuilder() .AddNotEmpty(prompt) .AddNotNull(userInfo) .AddNotZero(userInfo.ExpiresAt) .AddNotEmpty(userInfo.AccessToken) .AddNotEmpty(userInfo.RefreshToken) .ValidateGroup(); // var tokens = ToTokenResponse(userInfo); var result = await StreamData( tokens: tokens, addXPoweredValue: true, endpoint: XAiApiEndpoint.Stream, cancellationToken: cancellationToken, queryStrings: new Dictionary { { XAiApiQueryParams.Prompt, prompt } } ); // return result; } #endregion } }