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 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> /// <summary>
/// Generate Text Response Stream ... /// Generate Text Response Stream ...
/// </summary> /// </summary>
/// <param name="prompt"></param> /// <param name="prompt"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <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, string prompt,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
+172 -2
View File
@@ -9,6 +9,7 @@ using xAiApi.AI.Configuration;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.ChatCompletion;
using System.Runtime.CompilerServices;
namespace xAiApi.AI.Services namespace xAiApi.AI.Services
{ {
@@ -164,6 +165,84 @@ namespace xAiApi.AI.Services
return result; 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
);
//
return result;
}
/// <summary> /// <summary>
/// Generated Text ... /// Generated Text ...
/// </summary> /// </summary>
@@ -191,7 +270,59 @@ namespace xAiApi.AI.Services
/// <param name="prompt"></param> /// <param name="prompt"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <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, string prompt,
CancellationToken cancellationToken = default 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 #endregion
} }
+73 -1
View File
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using xAiApi.AI.Interfaces; using xAiApi.AI.Interfaces;
using xAiApi.Base; 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")] [HttpGet("AskAIStream")]
[Authorize(Policy = XPolicies.EnabledUser)] [Authorize(Policy = XPolicies.EnabledUser)]
public async Task AskAIStream( public async Task AskAIStream(
@@ -97,7 +127,7 @@ namespace xAiApi.Controllers.V1
// Do What we Have to Do with Message ... // Do What we Have to Do with Message ...
// //
var msgBytes = message.Text.ToBytes(); var msgBytes = message.ToBytes();
await Response.Body.WriteAsync( await Response.Body.WriteAsync(
msgBytes, msgBytes,
0, 0,
@@ -113,6 +143,48 @@ namespace xAiApi.Controllers.V1
catch (Exception) 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 #endregion
} }
} }
+2 -1
View File
@@ -17,12 +17,13 @@
<!-- Local Projects --> <!-- Local Projects -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Modules\xCommons\xCommons.csproj" />
<ProjectReference Include="..\Modules\xIdentityHelper\xIdentityHelper.csproj" /> <ProjectReference Include="..\Modules\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.xDataService" Version="1.0.0" /> <PackageReference Include="xDashboard.xDataService" Version="1.0.0" />
<PackageReference Include="xDashboard.xPushService" Version="1.0.0" /> <PackageReference Include="xDashboard.xPushService" Version="1.0.0" />
</ItemGroup> </ItemGroup>