This commit is contained in:
2026-04-17 03:04:14 +03:30
parent 43d0433a8e
commit 8868afe656
5 changed files with 307 additions and 6 deletions
+25
View File
@@ -0,0 +1,25 @@
using xCommons.Extensions;
using System.Collections.Generic;
using Microsoft.Extensions.AI;
using System.Linq;
namespace xAiApi.AI.Extensions
{
public static class AiModelsExtensions
{
public static AIContent GetLast(IList<AIContent> source)
{
//
AIContent result = null;
//
if (source.HasChild())
{
result = source.ElementAt(source.Count - 1);
}
//
return result;
}
}
}
+34 -1
View File
@@ -69,13 +69,46 @@ namespace xAiApi.AI.Interfaces
CancellationToken cancellationToken = default
);
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="message">ChatMessage instance</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<ChatResponse> GetResponseByChatMessageAsync(
ChatMessage message,
CancellationToken cancellationToken = default
);
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="messages">ChatMessage Enumerable instance</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<ChatResponse> GetResponseByChatMessagesAsync(
IEnumerable<ChatMessage> messages,
CancellationToken cancellationToken = default
);
/// <summary>
/// Generate Text Response Stream ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<ChatResponseUpdate> GetTextReponseStreamAsync(
IAsyncEnumerable<ChatResponseUpdate> GetReponseStreamAsync(
string prompt,
CancellationToken cancellationToken = default
);
/// <summary>
/// Generate Text Response Stream ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<string> GetTextReponseStreamAsync(
string prompt,
CancellationToken cancellationToken = default
);
+173 -3
View File
@@ -9,6 +9,7 @@ using xAiApi.AI.Configuration;
using System.Collections.Generic;
using System.Threading;
using Microsoft.SemanticKernel.ChatCompletion;
using System.Runtime.CompilerServices;
namespace xAiApi.AI.Services
{
@@ -155,7 +156,85 @@ namespace xAiApi.AI.Services
// Generate Response ...
var result = await TextGenreatorClient
.GetResponseAsync(
chatMessage: prompt,
chatMessage: prompt,
options: ChatOptions,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="message">ChatMessage instance</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<ChatResponse> GetResponseByChatMessageAsync(
ChatMessage message,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid = !message.IsNull() && !message.Contents.HasChild();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Preparing Prompt ...
var prompt = await PreparePrompt(
message: message,
cancellationToken: cancellationToken
);
//
// Generate Response ...
var result = await TextGenreatorClient
.GetResponseAsync(
chatMessage: prompt,
options: ChatOptions,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Generated Response ...
/// </summary>
/// <param name="messages">ChatMessage Enumerable instance</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<ChatResponse> GetResponseByChatMessagesAsync(
IEnumerable<ChatMessage> messages,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid = !messages.IsNull() && messages.HasChild();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Preparing Prompt ...
var prompt = await PreparePrompt(
messages: messages,
cancellationToken: cancellationToken
);
//
// Generate Response ...
var result = await TextGenreatorClient
.GetResponseAsync(
messages: prompt,
options: ChatOptions,
cancellationToken: cancellationToken
);
@@ -191,7 +270,59 @@ namespace xAiApi.AI.Services
/// <param name="prompt"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public IAsyncEnumerable<ChatResponseUpdate> GetTextReponseStreamAsync(
public async IAsyncEnumerable<string> GetTextReponseStreamAsync(
string prompt,
[EnumeratorCancellation]
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 stream = TextGenreatorClient
.GetStreamingResponseAsync(
chatMessage: prompt,
options: ChatOptions,
cancellationToken: cancellationToken
);
//
await foreach (var response in stream)
{
//
if (response.IsNull())
{
yield break;
}
//
var model = response.Text;
yield return model;
}
}
/// <summary>
/// Generate Text Response Stream ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public IAsyncEnumerable<ChatResponseUpdate> GetReponseStreamAsync(
string prompt,
CancellationToken cancellationToken = default
)
@@ -248,7 +379,46 @@ namespace xAiApi.AI.Services
)
{
//
return await Task.FromResult(prompt);
return await Task.Run(() =>
{
return prompt;
}, cancellationToken);
}
/// <summary>
/// Preparing Prompt for AI ...
/// </summary>
/// <param name="message"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<ChatMessage> PreparePrompt(
ChatMessage message,
CancellationToken cancellationToken = default
)
{
//
return await Task.Run(() =>
{
return message;
}, cancellationToken);
}
/// <summary>
/// Preparing Prompt for AI ...
/// </summary>
/// <param name="messages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<IEnumerable<ChatMessage>> PreparePrompt(
IEnumerable<ChatMessage> messages,
CancellationToken cancellationToken = default
)
{
//
return await Task.Run(() =>
{
return messages;
}, cancellationToken);
}
#endregion
}
+73 -1
View File
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using xAiApi.AI.Interfaces;
using xAiApi.Base;
@@ -66,6 +67,35 @@ namespace xAiApi.Controllers.V1
}
}
[HttpGet("AskAIAsChatMessage")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<ChatMessage>> AskAIAsChatMessage(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
var result = await aiService
.GetResponseAsync(
prompt: prompt,
cancellationToken: cancellationToken
);
//
return Ok(result);
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
[HttpGet("AskAIStream")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task AskAIStream(
@@ -97,7 +127,7 @@ namespace xAiApi.Controllers.V1
// Do What we Have to Do with Message ...
//
var msgBytes = message.Text.ToBytes();
var msgBytes = message.ToBytes();
await Response.Body.WriteAsync(
msgBytes,
0,
@@ -113,6 +143,48 @@ namespace xAiApi.Controllers.V1
catch (Exception)
{ }
}
[HttpGet("AskAIStreamAsChatMessage")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task AskAIStreamAsChatMessage(
[FromQuery] string prompt,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
// Adding Content Type ...
Response.Headers
.Append("Content-Type", "text/event-stream");
//
// Retrieving Stream ...
var stream = aiService
.GetReponseStreamAsync(
prompt: prompt,
cancellationToken: cancellationToken
);
//
await foreach (var message in stream)
{
//
await Response.Body.WriteModelToStream(
model: message,
cancellationToken: cancellationToken
);
}
//
// Closing Connection ...
await Response.Body.FlushAsync();
}
catch (Exception)
{ }
}
#endregion
}
}
+2 -1
View File
@@ -17,12 +17,13 @@
<!-- Local Projects -->
<ItemGroup>
<ProjectReference Include="..\Modules\xCommons\xCommons.csproj" />
<ProjectReference Include="..\Modules\xIdentityHelper\xIdentityHelper.csproj" />
</ItemGroup>
<!-- Local Modules -->
<ItemGroup>
<PackageReference Include="xDashboard.xCommons" Version="1.0.0" />
<!-- <PackageReference Include="xDashboard.xCommons" Version="1.0.0" /> -->
<PackageReference Include="xDashboard.xDataService" Version="1.0.0" />
<PackageReference Include="xDashboard.xPushService" Version="1.0.0" />
</ItemGroup>