last ...
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
namespace xAiApi.AI.Configuration
|
||||
{
|
||||
public class XAiApiConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// AI Provider Client URL ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Text Generator Model Name ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string TextModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Code Generator Model Name ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string CodeModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Image Generator Model Name ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string ImageModel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace xAiApi.AI.Constants
|
||||
{
|
||||
public partial struct ConfigurationNodeNames
|
||||
{
|
||||
public const string AI_API_SERVICE_NODE = "AiApiServiceConfiguration";
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,10 @@ namespace xAiApi.AI.DI
|
||||
/// Register AI Services ...
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public static void AddXAIServices(this IServiceCollection services)
|
||||
public static void AddXAIServices(
|
||||
this IServiceCollection services
|
||||
)
|
||||
{
|
||||
//
|
||||
services.AddSingleton<IXAIService, XAIService>();
|
||||
}
|
||||
|
||||
@@ -23,5 +24,9 @@ namespace xAiApi.AI.DI
|
||||
/// <param name="builder"></param>
|
||||
public static void UseXAIServices(this IApplicationBuilder builder)
|
||||
{ }
|
||||
|
||||
//
|
||||
#region Private ...
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using xAiApi.AI.Configuration;
|
||||
using xAiApi.AI.Constants;
|
||||
using xCommons.Extensions;
|
||||
|
||||
namespace xAiApi.AI.Extensions
|
||||
{
|
||||
public static class XAiApiConfigurationExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract Configuration ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static XAiApiConfiguration GetXAiApiConfiguration(this IConfiguration source)
|
||||
{
|
||||
//
|
||||
var section = source.GetSection(ConfigurationNodeNames.AI_API_SERVICE_NODE);
|
||||
var result = section.Get<XAiApiConfiguration>();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add XAiApiConfiguration ...
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddXAiApiConfiguration(
|
||||
this IServiceCollection source,
|
||||
XAiApiConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
if (!configuration.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
source.AddSingleton(configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate XAiApiConfiguration ...
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValid(this XAiApiConfiguration configuration)
|
||||
{
|
||||
//
|
||||
var result =
|
||||
!configuration.IsNull() &&
|
||||
!configuration.Url.IsNullOrEmpty() &&
|
||||
configuration.Url.IsValidUrl() &&
|
||||
!configuration.TextModel.IsNullOrEmpty();
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using xAiApi.AI.Configuration;
|
||||
|
||||
namespace xAiApi.AI.Interfaces
|
||||
{
|
||||
public interface IXAIService
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides Options for Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
ChatOptions ChatOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides History for Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
ChatHistory ChatHistory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Text Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
IChatClient TextGenreatorClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Code Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
IChatClient CodeGenreatorClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Image Chats ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
IChatClient ImageGenreatorClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
XAiApiConfiguration Configuration { get; }
|
||||
|
||||
//
|
||||
#region Actions ...
|
||||
/// <summary>
|
||||
/// Generated Text ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetTextResponseAsync(string prompt);
|
||||
Task<string> GetTextResponseAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Generated Response ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<ChatResponse> GetResponseAsync(string prompt);
|
||||
Task<ChatResponse> GetResponseAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Generate Text Response Stream ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<ChatResponseUpdate> GetTextReponseStreamAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+201
-12
@@ -1,37 +1,140 @@
|
||||
using System;
|
||||
using OllamaSharp;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.AI;
|
||||
using OllamaSharp;
|
||||
using xAiApi.AI.Interfaces;
|
||||
using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using xAiApi.AI.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using System.Threading;
|
||||
|
||||
namespace xAiApi.AI.Services
|
||||
{
|
||||
public class XAIService : IXAIService
|
||||
{
|
||||
//
|
||||
/// <summary>
|
||||
/// Provides Options for Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public ChatOptions ChatOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides History for Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public ChatHistory ChatHistory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Text Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public IChatClient TextGenreatorClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Code Chat ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public IChatClient CodeGenreatorClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a Client for Image Chats ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public IChatClient ImageGenreatorClient { get; }
|
||||
|
||||
public XAIService()
|
||||
/// <summary>
|
||||
/// Configuration ...
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public XAiApiConfiguration Configuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructing Service ...
|
||||
/// </summary>
|
||||
/// <param name="configuration">configuration ...</param>
|
||||
public XAIService(
|
||||
XAiApiConfiguration configuration
|
||||
)
|
||||
{
|
||||
//
|
||||
Configuration = configuration;
|
||||
|
||||
//
|
||||
// here we are Initialize Text Generator Model ...
|
||||
TextGenreatorClient = new OllamaApiClient(
|
||||
new Uri("http://localhost:11434"),
|
||||
"gemma3:1b"
|
||||
);
|
||||
TextGenreatorClient = new ChatClientBuilder(new OllamaApiClient(
|
||||
new Uri(configuration.Url),
|
||||
configuration.TextModel
|
||||
))
|
||||
// .UseFunctionInvocation()
|
||||
.Build();
|
||||
|
||||
//
|
||||
// Code Generator Client ...
|
||||
if (!configuration.CodeModel.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
CodeGenreatorClient = new ChatClientBuilder(new OllamaApiClient(
|
||||
new Uri(configuration.Url),
|
||||
configuration.CodeModel
|
||||
))
|
||||
// .UseFunctionInvocation()
|
||||
.Build();
|
||||
}
|
||||
|
||||
//
|
||||
// Image Generator Client ...
|
||||
if (!configuration.ImageModel.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
ImageGenreatorClient = new ChatClientBuilder(new OllamaApiClient(
|
||||
new Uri(configuration.Url),
|
||||
configuration.ImageModel
|
||||
))
|
||||
// .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"
|
||||
// )
|
||||
// ],
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
#region Actions ...
|
||||
#region Text Actions ...
|
||||
/// <summary>
|
||||
/// Generated Response ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ChatResponse> GetResponseAsync(string prompt)
|
||||
public async Task<ChatResponse> GetResponseAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate ...
|
||||
@@ -41,10 +144,21 @@ namespace xAiApi.AI.Services
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Preparing Prompt ...
|
||||
prompt = await PreparePrompt(
|
||||
prompt: prompt,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
// Generate Response ...
|
||||
var result = await TextGenreatorClient
|
||||
.GetResponseAsync(prompt);
|
||||
.GetResponseAsync(
|
||||
chatMessage: prompt,
|
||||
options: ChatOptions,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
@@ -54,13 +168,88 @@ namespace xAiApi.AI.Services
|
||||
/// Generated Text ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetTextResponseAsync(string prompt)
|
||||
public async Task<string> GetTextResponseAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var response = await GetResponseAsync(prompt);
|
||||
var response = await GetResponseAsync(
|
||||
prompt: prompt,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
return response.Text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate Text Response Stream ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public IAsyncEnumerable<ChatResponseUpdate> GetTextReponseStreamAsync(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate ...
|
||||
var isValid = !prompt.IsNullOrEmpty();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Preparing Prompt ...
|
||||
prompt = PreparePrompt(
|
||||
prompt: prompt,
|
||||
cancellationToken: cancellationToken
|
||||
)
|
||||
.RunTask();
|
||||
|
||||
//
|
||||
// Generate Response ...
|
||||
var result = TextGenreatorClient
|
||||
.GetStreamingResponseAsync(
|
||||
chatMessage: prompt,
|
||||
options: ChatOptions,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Code Actions ...
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Image Actions ...
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Private ...
|
||||
/// <summary>
|
||||
/// Preparing Prompt for AI ...
|
||||
/// </summary>
|
||||
/// <param name="prompt"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> PreparePrompt(
|
||||
string prompt,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
return await Task.FromResult(prompt);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
||||
using xAiApi.AI.Interfaces;
|
||||
using xAiApi.Base;
|
||||
using xCommons.Configurations;
|
||||
using xCommons.Extensions;
|
||||
using xCommons.Providers;
|
||||
using xIdentityService.Interfaces;
|
||||
|
||||
@@ -57,6 +58,37 @@ namespace xAiApi.Controllers.V1
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet("AskAIStream")]
|
||||
public async Task AskAIStream(
|
||||
[FromQuery] string prompt
|
||||
)
|
||||
{
|
||||
//
|
||||
// Do ...
|
||||
try
|
||||
{
|
||||
//
|
||||
var stream = aiService
|
||||
.GetTextReponseStreamAsync(prompt);
|
||||
await foreach (var message in stream)
|
||||
{
|
||||
//
|
||||
// Do What we Have to Do with Message ...
|
||||
|
||||
//
|
||||
var msgBytes = message.Text.ToBytes();
|
||||
await Response.Body.WriteAsync(msgBytes, 0, msgBytes.Length);
|
||||
await Response.Body.FlushAsync();
|
||||
}
|
||||
|
||||
//
|
||||
await Response.Body.FlushAsync();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace xAiApi.DI
|
||||
{
|
||||
public static class XPushDIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Register XPushProvider Services
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public static void AddXPushHubProvider(
|
||||
this IServiceCollection services,
|
||||
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
||||
)
|
||||
{
|
||||
AddPushHubProvider(services, lifeTime);
|
||||
}
|
||||
|
||||
//
|
||||
#region Private ...
|
||||
private static void AddPushHubProvider(
|
||||
this IServiceCollection services,
|
||||
ServiceLifetime lifeTime = ServiceLifetime.Transient
|
||||
)
|
||||
{ }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -23,11 +23,11 @@ using xDataService.DI;
|
||||
using xDataService.Interfaces;
|
||||
using xPushService.Helpers;
|
||||
using xAiApi.Extensions;
|
||||
using xAiApi.DI;
|
||||
using xAiApi.Data.Helpers;
|
||||
using xAiApi.Data;
|
||||
using xAiApi.Data.Seeder;
|
||||
using xAiApi.AI.DI;
|
||||
using xAiApi.AI.Extensions;
|
||||
// using xApi.Extensions;
|
||||
// using xDataHelper;
|
||||
// using xDataHelper.DbSeeder;
|
||||
@@ -122,7 +122,7 @@ namespace xAiApi
|
||||
//
|
||||
// Register XPushService ...
|
||||
services.AddXPushService(Configuration);
|
||||
services.AddXPushHubProvider(lifeTime);
|
||||
// services.AddXPushHubProvider(lifeTime);
|
||||
|
||||
//
|
||||
// Register XIdentityService ...
|
||||
@@ -203,6 +203,12 @@ namespace xAiApi
|
||||
});
|
||||
#endregion
|
||||
|
||||
//
|
||||
// Registering Configurations ...
|
||||
var xAiApiConfiguration = Configuration
|
||||
.GetXAiApiConfiguration();
|
||||
services.AddXAiApiConfiguration(xAiApiConfiguration);
|
||||
|
||||
//
|
||||
// Register AI Service ...
|
||||
services.AddXAIServices();
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
"http://api.saherelmhub.ir",
|
||||
"https://api.saherelmhub.ir"
|
||||
],
|
||||
"AiApiServiceConfiguration": {
|
||||
"Url":"http://localhost:11434",
|
||||
"TextModel": "gemma3:1b"
|
||||
},
|
||||
"IdentityServiceConfiguration": {
|
||||
"Authority": "https://localhost:4001",
|
||||
"ApiName": "xSaherElmAPI",
|
||||
|
||||
Reference in New Issue
Block a user