Compare commits

...
10 Commits
Author SHA1 Message Date
saherelm e33479f9b6 last ... 2026-08-01 10:52:38 +03:30
saherelm fed2b7d934 cleanup Dependencies ... 2026-07-30 15:58:23 +03:30
saherelm 4245ba726f last ... 2026-07-26 21:19:46 +03:30
saherelm cece849cdf last ... 2026-06-12 23:42:48 +03:30
saherelm 11881dcd9c Update Lang Version to 12 ... 2026-06-12 02:11:06 +03:30
saherelm 0f8b8e8211 last ... 2026-05-22 20:27:46 +03:30
saherelm a78b2ae254 last ... 2026-04-24 13:42:35 +03:30
saherelm 990fec2c38 last ... 2026-04-24 00:33:24 +03:30
saherelm 9b84dde456 oreoare nuget source for built on mirrors ... 2026-04-19 22:39:18 +03:30
saherelm c72534614f last ... 2026-04-17 03:04:28 +03:30
14 changed files with 225 additions and 113 deletions
View File
View File
-100
View File
@@ -1,100 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xAiService.Interfaces;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Controllers;
using xIdentityService.Interfaces;
namespace xAiService.Controllers
{
/// <summary>
/// a Controller base Class which implement based Actions to Provides AI Service Access ...
/// </summary>
public abstract class XAiServiceControllerBase : XIBaseProviderController, IXAiServiceControllerBase
{
private readonly IXAiService aiService;
protected XAiServiceControllerBase(
ILogger logger,
IXAiService aiService,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{
this.aiService = aiService;
}
//
#region Text Actions ...
[HttpGet("Ask")]
public virtual async Task<ActionResult<string>> Ask(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
var userInfo = await GetUserInfo();
var result = await aiService
.GetTextResponseAsync(
prompt: prompt,
userInfo: userInfo,
cancellationToken: cancellationToken
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
[HttpGet("AskStream")]
public async Task<ActionResult> AskAIStream(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
var userInfo = await GetUserInfo();
var result = aiService
.GetTextReponseStreamAsync(
prompt: prompt,
userInfo: userInfo,
cancellationToken: cancellationToken
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
}
}
View File
View File
+60
View File
@@ -0,0 +1,60 @@
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;
}
}
}
+83
View File
@@ -0,0 +1,83 @@
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);
}
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
using System.Collections.Generic; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.AI; using Microsoft.Extensions.AI;
@@ -51,7 +51,7 @@ namespace xAiService.Interfaces
/// <param name="userInfo"></param> /// <param name="userInfo"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
IAsyncEnumerable<string> GetTextReponseStreamAsync( Task<Stream> GetTextReponseStreamAsync(
string prompt, string prompt,
XUserClaimsInfoDto userInfo, XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
+1 -1
View File
@@ -11,7 +11,7 @@ namespace xAiService.Interfaces
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
Task<ActionResult> AskAIStream( Task<ActionResult> AskStream(
[FromQuery] string prompt, [FromQuery] string prompt,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
+57
View File
@@ -0,0 +1,57 @@
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; }
}
}
+3 -2
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.AI; using Microsoft.Extensions.AI;
@@ -104,7 +105,7 @@ namespace xAiService.Services
/// <param name="userInfo"></param> /// <param name="userInfo"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
public IAsyncEnumerable<string> GetTextReponseStreamAsync( public async Task<Stream> GetTextReponseStreamAsync(
string prompt, string prompt,
XUserClaimsInfoDto userInfo, XUserClaimsInfoDto userInfo,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
@@ -123,7 +124,7 @@ namespace xAiService.Services
// //
var tokens = ToTokenResponse(userInfo); var tokens = ToTokenResponse(userInfo);
var result = StreamData<string>( var result = await StreamData(
tokens: tokens, tokens: tokens,
addXPoweredValue: true, addXPoweredValue: true,
endpoint: XAiApiEndpoint.Stream, endpoint: XAiApiEndpoint.Stream,
+1 -2
View File
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<packageSources> <packageSources>
<add key="megan" value="https://hub.megan.ir/nuget/index.json" />
<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" /> <add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" disableTLSCertificateValidation="true" />
</packageSources> </packageSources>
</configuration> </configuration>
+16 -4
View File
@@ -1,12 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<!-- Runtime Definition --> <!-- Runtime Definition -->
<PropertyGroup> <PropertyGroup>
<Version>1.0.0</Version> <Version>1.0.0</Version>
<LangVersion>8.0</LangVersion> <LangVersion>12.0</LangVersion>
<PackageId>xSaherelm.xAiService</PackageId> <PackageId>xSaherelm.xAiService</PackageId>
<Authors>Hadi Khazaee Asl</Authors> <Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company> <Company>SaherElm IT Center</Company>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Description> <Description>
it is a Part of xSaherElm project which Provides Services to use xSaherElm AI Features ... it is a Part of xSaherElm project which Provides Services to use xSaherElm AI Features ...
</Description> </Description>
@@ -22,17 +24,27 @@
<!-- Local Projects --> <!-- Local Projects -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\xIdentityHelper\xIdentityHelper.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.xCommons" Version="1.0.0" /> -->
<!-- <PackageReference Include="xDashboard.xIdentityService" 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" /> <!-- <PackageReference Include="Microsoft.Extensions.AI" Version="10.4.1" /> -->
</ItemGroup> </ItemGroup>
<!-- For XML Documentation Support -->
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
</Project> </Project>