Compare commits

...
1 Commits
Author SHA1 Message Date
saherelm 7b1f16bd18 last works on AiApi:
- Default Ai Service and Controller;
- Default Embeding and Controller;
- ...
2026-08-15 17:25:33 +03:30
13 changed files with 453 additions and 4 deletions
+4
View File
@@ -10,5 +10,9 @@ namespace xAiApi.Constants
// //
public const string XDILogTag = "XAiApi"; public const string XDILogTag = "XAiApi";
public const string XAiApiIntroductionPromptName = "Introduction"; public const string XAiApiIntroductionPromptName = "Introduction";
//
public const string XAiEmbeddingModelName = "Embed";
public const string XAiEmbeddingPromptName = "Embedding";
} }
} }
+31
View File
@@ -0,0 +1,31 @@
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<IXDefaultEmbeddingService>
{
public DefaultEmbeddingController(
ILogger<DefaultEmbeddingController> logger,
IXDefaultEmbeddingService aiService,
XAppConfiguration appConfiguration,
XValidationProvider validationProvider
) : base(
logger,
aiService,
appConfiguration,
validationProvider
)
{ }
}
}
@@ -0,0 +1,110 @@
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<TAiService> : XAiServiceControllerBase<TAiService>, 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;
}
/// <summary>
/// Request For Embedding Specified String ...
/// </summary>
/// <param name="content"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("Embeding")]
public async Task<ActionResult<float[]>> 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;
}
}
/// <summary>
/// Request For Embedding Specified Batch ...
/// </summary>
/// <param name="batch"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("Embedings")]
public async Task<ActionResult<IReadOnlyList<float[]>>> 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;
}
}
}
}
+41
View File
@@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using OllamaSharp;
namespace xAiApi.Interfaces
{
/// <summary>
/// Base Embedding Provider Service ...
/// </summary>
public interface IXAiEmbeddingServiceBase : IXAiServiceBase
{
/// <summary>
/// Embedding Specified String ...
/// </summary>
/// <param name="content"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<float[]> Embeding(
string content,
CancellationToken cancellationToken = default
);
/// <summary>
/// Embedding Specified Batch ...
/// </summary>
/// <param name="batch"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IReadOnlyList<float[]>> Embedings(
string[] batch,
CancellationToken cancellationToken = default
);
/// <summary>
/// Access Embedding Client ...
/// </summary>
/// <returns></returns>
OllamaApiClient GetEmbeddingClient();
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace xAiApi.Interfaces
{
public interface IXAiEmbeddingServiceControllerBase : IXAiServiceControllerBase
{
/// <summary>
/// Request For Embedding Specified String ...
/// </summary>
/// <param name="content"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Embeding")]
Task<ActionResult<float[]>> Embeding(
[FromQuery] string content,
CancellationToken cancellationToken = default
);
/// <summary>
/// Request For Embedding Specified Batch ...
/// </summary>
/// <param name="batch"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Embedings")]
Task<ActionResult<IReadOnlyList<float[]>>> Embedings(
[FromQuery] string[] batch,
CancellationToken cancellationToken = default
);
}
}
+5
View File
@@ -0,0 +1,5 @@
namespace xAiApi.Interfaces
{
public interface IXDefaultEmbeddingService : IXAiEmbeddingServiceBase
{ }
}
+190
View File
@@ -0,0 +1,190 @@
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
{
/// <summary>
/// Base Embedding Provider Service ...
/// </summary>
public abstract class XAiEmbeddingServiceBase : XAIServiceBase, IXAiEmbeddingServiceBase
{
private readonly XAiModelDescriptor descriptor;
protected XAiEmbeddingServiceBase(
IXAiDataProvider dataProvider,
XAiApiConfiguration configuration,
ILogger<XAiEmbeddingServiceBase> logger,
string embeddingModelName = XAiApiConstants.XAiEmbeddingModelName
) : base(
dataProvider,
logger,
configuration
)
{
//
// Prepare Embedding Model Descriptor ...
descriptor = configuration.GetModel(embeddingModelName);
if (!descriptor.IsValid())
{
XException.InvalidConfiguration.Throw();
}
}
/// <summary>
/// Embedding Specified String ...
/// </summary>
/// <param name="content"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<float[]> 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;
}
/// <summary>
/// Embedding Specified Batch ...
/// </summary>
/// <param name="batch"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IReadOnlyList<float[]>> 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;
}
/// <summary>
/// Access Embedding Client ...
/// </summary>
/// <returns></returns>
public OllamaApiClient GetEmbeddingClient()
{
//
var result = new OllamaApiClient(new Uri(descriptor.Url));
//
return result;
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace xAiApi.Providers
{ {
public XDefaultAiService( public XDefaultAiService(
IXAiDataProvider dataProvider, IXAiDataProvider dataProvider,
ILogger<XAIServiceBase> logger, ILogger<XDefaultAiService> logger,
XAiApiConfiguration configuration XAiApiConfiguration configuration
) : base( ) : base(
dataProvider, dataProvider,
+21
View File
@@ -0,0 +1,21 @@
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<XDefaultEmbeddingService> logger
) : base(
dataProvider,
configuration,
logger
)
{ }
}
}
+1 -1
View File
@@ -27,7 +27,6 @@ using Microsoft.Extensions.DependencyInjection;
using IdentityModel.AspNetCore.OAuth2Introspection; using IdentityModel.AspNetCore.OAuth2Introspection;
using xPushService.Helpers; using xPushService.Helpers;
using xAiApi.DI; using xAiApi.DI;
using xExceptions.Constants;
using xAiApi.Interfaces; using xAiApi.Interfaces;
using xAiApi.Providers; using xAiApi.Providers;
using xAiModels.DI; using xAiModels.DI;
@@ -189,6 +188,7 @@ namespace xAiApi
// //
// Register Default Ai Service ... // Register Default Ai Service ...
services.AddScoped<IXDefaultAiService, XDefaultAiService>(); services.AddScoped<IXDefaultAiService, XDefaultAiService>();
services.AddScoped<IXDefaultEmbeddingService, XDefaultEmbeddingService>();
} }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+13
View File
@@ -43,6 +43,13 @@
"LLM": "gemma3:1b", "LLM": "gemma3:1b",
"Provider": "Ollama", "Provider": "Ollama",
"Url": "http://localhost:11434" "Url": "http://localhost:11434"
},
{
"ApiKey": "",
"Name": "Embed",
"LLM": "bge-m3",
"Provider": "Ollama",
"Url": "http://localhost:11434"
} }
], ],
"Prompts": [ "Prompts": [
@@ -51,6 +58,12 @@
"Template": "your name is xSaherElmAi, you are a professional ai assistant which develped by SaherElm IT Center", "Template": "your name is xSaherElmAi, you are a professional ai assistant which develped by SaherElm IT Center",
"Description": "", "Description": "",
"Params": [] "Params": []
},
{
"Name": "Embedding",
"Template": "your name is xSaherElmAi, you are a professional ai assistant which develped by SaherElm IT Center specified for Embedding Documents",
"Description": "",
"Params": []
} }
] ]
}, },
+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" /> <!-- <add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" /> -->
</packageSources> </packageSources>
</configuration> </configuration>
+1 -1
View File
@@ -35,7 +35,7 @@
<!-- Local Dependencies --> <!-- Local Dependencies -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="../Modules/xCommons/xCommons.csproj" /> <ProjectReference Include="../Modules/xCommons/xCommons.csproj" />
<ProjectReference Include="../Modules/xAiModels/xAiModels.csproj" /> <ProjectReference Include="../Modules/xAiService/xAiService.csproj" />
<ProjectReference Include="../Modules/xTagService/xTagService.csproj" /> <ProjectReference Include="../Modules/xTagService/xTagService.csproj" />
<ProjectReference Include="../Modules/xDataService/xDataService.csproj" /> <ProjectReference Include="../Modules/xDataService/xDataService.csproj" />
<ProjectReference Include="../Modules/xPushService/xPushService.csproj" /> <ProjectReference Include="../Modules/xPushService/xPushService.csproj" />