Compare commits

...
1 Commits
Author SHA1 Message Date
saherelm 4283c9688e Cleanup xAiService for Reconstruction ... 2026-08-15 17:23:24 +03:30
16 changed files with 88 additions and 652 deletions
View File
@@ -1,9 +0,0 @@
namespace xAiService.Configurations
{
public partial class XAIServiceConfiguration
{
public string Url { get; set; }
public string XPoweredValue { get; set; }
public int DefaultClientTimeout { get; set; } = 360;
}
}
-7
View File
@@ -1,7 +0,0 @@
namespace xAiService.Constants
{
public struct XAiApiQueryParams
{
public const string Prompt = "prompt";
}
}
-12
View File
@@ -1,12 +0,0 @@
using xExceptions.Attributes;
namespace xAiService.Constants
{
public enum XAiApiEndpoint
{
[StringValue("AskAI")]
Ask,
[StringValue("AskAIStream")]
Stream,
}
}
+1 -170
View File
@@ -1,174 +1,5 @@
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 namespace xAiService.DI
{ {
public static partial class XDIHelperExtension public static partial class XDIHelperExtension
{ { }
/// <summary>
/// Extract AI Service Configuration ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XAIServiceConfiguration GetXAIServiceConfiguration(this IConfiguration source)
{
//
XAIServiceConfiguration result = null;
//
var section = source.GetSection(ConfigurationNodeNames.AI_SERVICE_NODE);
if (!section.IsNull())
{
result = section.Get<XAIServiceConfiguration>();
}
//
return result;
}
/// <summary>
/// Add AI Service Configuration ...
/// </summary>
/// <param name="source"></param>
/// <param name="configuration"></param>
public static void AddXAIServiceConfiguration(
this IServiceCollection source,
XAIServiceConfiguration configuration
)
{
source.AddSingleton<XAIServiceConfiguration>(configuration);
}
/// <summary>
/// Adding XAiService ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="lifeTime"></param>
public static void AddXAIService(
this IServiceCollection services,
IConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Scoped
)
{
//
var config = configuration.GetXAIServiceConfiguration();
AddAIService(
services,
config,
lifeTime
);
}
/// <summary>
/// Adding XAiService ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="lifeTime"></param>
public static void AddXAIService(
this IServiceCollection services,
XAIServiceConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Scoped
)
{
//
AddAIService(
services,
configuration,
lifeTime
);
}
//
#region Private ...
/// <summary>
/// a LogTag for Service ...
/// </summary>
private static string XLogTag = "XFileService";
/// <summary>
/// print a log in Console ...
/// </summary>
/// <param name="message"></param>
private static void Log(string message)
{
Console.WriteLine($"{XLogTag} => {message}");
}
/// <summary>
/// Adding Ai Service ...
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="lifeTime"></param>
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
}
} }
View File
-25
View File
@@ -1,25 +0,0 @@
using xAiService.Configurations;
using xCommons.Extensions;
namespace xAiService.Extensions
{
public static class ModelExtensions
{
/// <summary>
/// Validate XAiServiceConfiguration ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsValid(this XAIServiceConfiguration source)
{
//
bool result =
!source.IsNull() &&
!source.Url.IsNullOrEmpty() &&
source.Url.IsValidUrl();
//
return result;
}
}
}
-60
View File
@@ -1,60 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using xAiService.Models.Dtos;
using xCommons.Extensions;
namespace xAiService.Extensions
{
public static class PromptExtensions
{
/// <summary>
/// Get Template Params Filled Prompt ...
/// </summary>
/// <param name="source"></param>
/// <param name="params"></param>
/// <returns></returns>
public static string GetMessage(
this XPromptDto source,
IDictionary<string, string> @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;
}
}
}
+86
View File
@@ -0,0 +1,86 @@
using System;
using xCommons.Extensions;
namespace xAiService.Helpers
{
public static class VectorHelper
{
/// <summary>
/// Normalize a Vector ...
/// </summary>
/// <param name="vector"></param>
public static void Normalize(float[] vector)
{
//
// Validate ...
if (vector.IsNull() || !vector.HasChild())
{
return;
}
//
float sum = 0f;
foreach (var value in vector)
{
sum += value * value;
}
//
float norm = MathF.Sqrt(sum);
if (norm <= 1e-9f)
{
return;
}
//
for (int i = 0; i < vector.Length; i++)
{
vector[i] /= norm;
}
}
/// <summary>
/// Similarity Check ...
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static float CosineSimilarity(float[] a, float[] b)
{
//
if (a.IsNull() || b.IsNull())
{
return 0f;
}
//
if (a.Length != b.Length)
{
return 0f;
}
//
float dot = 0f;
float normA = 0f;
float normB = 0f;
for (int i = 0; i < a.Length; i++)
{
//
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
//
float denominator = MathF.Sqrt(normA) * MathF.Sqrt(normB);
if (denominator <= 1e-9f)
{
return 0f;
}
//
var result = dot / denominator;
return result;
}
}
}
-83
View File
@@ -1,83 +0,0 @@
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
{
/// <summary>
/// Holds Initialized Prompts ...
/// </summary>
private static XPromptsDto prompts;
/// <summary>
/// Initialize Prompt Helper ...
/// </summary>
/// <param name="path"></param>
/// <exception cref="Exception"></exception>
/// <exception cref="InvalidDataException"></exception>
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<XPromptsDto>(json, options);
if (!root.IsNullOrDefault())
{
prompts = new XPromptsDto { Prompts = root.Prompts };
}
}
/// <summary>
/// Retrieve all Allowed Prompts as Enumerable ...
/// </summary>
/// <returns></returns>
public static IEnumerable<XPromptDto> GetPrompts()
{
return prompts!.Prompts.AsEnumerable();
}
/// <summary>
/// Get Specified Prompt ...
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static XPromptDto GetPrompt(string name)
{
//
return GetPrompts()
.FirstOrDefault(p => p.Name == name);
}
}
}
-61
View File
@@ -1,61 +0,0 @@
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
{
/// <summary>
/// XAiService Configurations ...
/// </summary>
/// <value></value>
XAIServiceConfiguration Configuration { get; }
//
#region Text Actions ...
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task<ChatResponse> GetResponseAsync(
string prompt,
XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default
);
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task<string> GetTextResponseAsync(
string prompt,
XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default
);
/// <summary>
/// Generate Text Response Stream ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Stream> GetTextReponseStreamAsync(
string prompt,
XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default
);
#endregion
}
}
-19
View File
@@ -1,19 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace xAiService.Interfaces
{
public interface IXAiServiceControllerBase
{
Task<ActionResult<string>> Ask(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
);
Task<ActionResult> AskStream(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
);
}
}
-57
View File
@@ -1,57 +0,0 @@
namespace xAiService.Models.Dtos
{
/// <summary>
/// Described Prompts in app ...
/// </summary>
public class XPromptsDto
{
public XPromptDto[] Prompts { get; set; } = [];
}
/// <summary>
/// a Single Prompt Description ...
/// </summary>
public class XPromptDto
{
/// <summary>
/// Prompt Name ...
/// </summary>
public string Name { get; set; }
/// <summary>
/// Prompt Template Message ...
/// </summary>
public string Prompt { get; set; }
/// <summary>
/// Prompt Description ...
/// </summary>
public string Description { get; set; }
/// <summary>
/// Describe Prompt Params ...
/// </summary>
public virtual XPromptParamDto[] Params { get; set; } = null;
}
/// <summary>
/// Prompt Param used to Fill dynamic Datas to Specified Prompts ...
/// </summary>
public class XPromptParamDto
{
/// <summary>
/// Param Name ...
/// </summary>
public string Name { get; set; }
/// <summary>
/// Parma Identifier ...
/// </summary>
public string Param { get; set; }
/// <summary>
/// Param Description ...
/// </summary>
public string Description { get; set; }
}
}
-143
View File
@@ -1,143 +0,0 @@
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
{
/// <summary>
/// XAiService Configurations ...
/// </summary>
/// <value></value>
public XAIServiceConfiguration Configuration { get; }
public XAiService(
ILogger<XAiService> logger,
IXTokenProvider tokenProvider,
IXIdentityProvider identityProvider,
XAIServiceConfiguration configuration,
XValidationProvider validationProvider
) : base(
configuration.Url,
logger,
configuration.XPoweredValue,
configuration.DefaultClientTimeout,
tokenProvider,
identityProvider,
validationProvider
)
{ }
//
#region Text Actions ...
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task<ChatResponse> GetResponseAsync(
string prompt,
XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default
)
{
throw new System.NotImplementedException();
}
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<string> 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<string, string>
{
{ XAiApiQueryParams.Prompt, prompt }
}
);
//
var response = await RunRestRequest<string>(
client,
request,
XHttpMethod.GET,
cancellationToken: cancellationToken
);
//
return response;
}
/// <summary>
/// Generate Text Response Stream ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<Stream> 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<string, string>
{
{ XAiApiQueryParams.Prompt, prompt }
}
);
//
return result;
}
#endregion
}
}
+1 -1
View File
@@ -2,6 +2,6 @@
<configuration> <configuration>
<packageSources> <packageSources>
<add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> <add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" disableTLSCertificateValidation="true" /> <!-- <add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" disableTLSCertificateValidation="true" /> -->
</packageSources> </packageSources>
</configuration> </configuration>
-5
View File
@@ -25,19 +25,14 @@
<!-- Local Projects --> <!-- Local Projects -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\xAiModels\xAiModels.csproj" /> <ProjectReference Include="..\xAiModels\xAiModels.csproj" />
<!-- <ProjectReference Include="..\xCommons\xCommons.csproj" />
<ProjectReference Include="..\xIdentityHelper\xIdentityHelper.csproj" /> -->
</ItemGroup> </ItemGroup>
<!-- Local Modules --> <!-- Local Modules -->
<ItemGroup> <ItemGroup>
<!-- <PackageReference Include="xDashboard.xCommons" Version="1.0.0" /> -->
<!-- <PackageReference Include="xDashboard.xIdentityService" Version="1.0.0" /> -->
</ItemGroup> </ItemGroup>
<!-- Dependencies --> <!-- Dependencies -->
<ItemGroup> <ItemGroup>
<!-- <PackageReference Include="Microsoft.Extensions.AI" Version="10.4.1" /> -->
</ItemGroup> </ItemGroup>
<!-- For XML Documentation Support --> <!-- For XML Documentation Support -->