Files
xSaherElmAiApi/Controllers/V1/AIController.cs
T
2026-04-30 12:01:56 +03:30

313 lines
9.5 KiB
C#

using System;
using System.Threading;
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 OpenAI.Realtime;
using xAiApi.AI.Interfaces;
using xAiApi.AI.Models.Dtos;
using xAiApi.Base;
using xAiModels.Models;
using xCommons.Configurations;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xIdentityHelper;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
namespace xAiApi.Controllers.V1
{
/// <summary>
/// a Controller Which Provides Actions for
/// using Ai Service ...
/// </summary>
public class AIController : XIBaseV1Controller
{
/// <summary>
/// Ai Provider ...
/// </summary>
private readonly IXAiProvider aiService;
//
#region Constructor ...
public AIController(
IXAiProvider aiService,
ILogger<XIBaseV1Controller> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{
this.aiService = aiService;
}
#endregion
//
#region Actions ...
/// <summary>
/// As a Message from Ai ...
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Ask")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XAiMessageDto>> Ask(
[FromQuery] XAiAskRequestDto request,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
// Validate Model ...
var isValid =
ModelState.IsValid &&
!request.IsNull() &&
!request.Prompt.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Retrieve User Info ...
var userInfo = await GetUserInfo();
//
// Retrieve Result ...
var result = await aiService
.Ask(
userInfo: userInfo,
prompt: request.Prompt,
projectId: request.ProjectId,
cancellationToken: cancellationToken,
conversationId: request.ConversationId
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// As a Message from Ai ...
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="prompt">specified prompt</param>
/// <param name="projectId">active Project Id</param>
/// <param name="conversationId">active Conversation Id</param>
/// <param name="cancellationToken"></param>
/// <returns>Ai Model's answer <see cref="XAiMessageDto"/></returns>
[HttpGet("AskAI")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task<ActionResult<XAiMessageDto>> AskAI(
[FromQuery] string prompt,
[FromQuery] string projectId = null,
[FromQuery] string conversationId = null,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
var userInfo = await GetUserInfo();
var result = await aiService
.Ask(
prompt: prompt,
userInfo: userInfo,
projectId: projectId,
conversationId: conversationId,
cancellationToken: cancellationToken
);
//
return Ok(result.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
/// <summary>
/// Ask a Message from Ai using Streamin Pattern ...
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("AskStream")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task AskStream(
[FromQuery] XAiAskRequestDto request,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
// Validate Model ...
var isValid =
ModelState.IsValid &&
!request.IsNull() &&
!request.Prompt.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Adding Content Type ...
Response.Headers
.Append("Content-Type", "text/event-stream");
//
// Retrieve User Info ...
var userInfo = await GetUserInfo();
//
// Access Async Enumerable ...
var stream = aiService
.AskStream(
userInfo: userInfo,
prompt: request.Prompt,
projectId: request.ProjectId,
cancellationToken: cancellationToken,
conversationId: request.ConversationId
);
//
// Loop through Enumerable ...
await foreach (var message in stream)
{
//
// Converts Model to Json String ...
var json = message.ToJSON();
//
// Generates Json byte[] ...
var bytes = json.ToBytes();
//
// Write Bytes to Stream ...
await Response.Body.WriteAsync(
bytes,
0,
bytes.Length,
cancellationToken
);
//
// Flushing Stream ...
await Response.Body.FlushAsync(cancellationToken);
}
//
// Closing Connection ...
await Response.Body.FlushAsync();
}
catch (Exception)
{ }
}
/// <summary>
/// Ask a Message from Ai using Streamin Pattern ...
/// </summary>
/// <param name="prompt"></param>
/// <param name="projectId"></param>
/// <param name="conversationId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("AskAIStream")]
[Authorize(Policy = XPolicies.EnabledUser)]
public async Task AskAIStream(
[FromQuery] string prompt,
[FromQuery] string projectId = null,
[FromQuery] string conversationId = null,
CancellationToken cancellationToken = default
)
{
//
// Do ...
try
{
//
// Adding Content Type ...
Response.Headers
.Append("Content-Type", "text/event-stream");
//
var userInfo = await GetUserInfo();
var stream = aiService
.AskStream(
prompt: prompt,
userInfo: userInfo,
projectId: projectId,
conversationId: conversationId,
cancellationToken: cancellationToken
);
//
// Loop through Enumerable ...
await foreach (var message in stream)
{
//
// Converts Model to Json String ...
var json = message.ToJSON();
//
// Generates Json byte[] ...
var bytes = json.ToBytes();
//
// Write Bytes to Stream ...
await Response.Body.WriteAsync(
bytes,
0,
bytes.Length,
cancellationToken
);
//
// Flushing Stream ...
await Response.Body.FlushAsync(cancellationToken);
}
//
// Closing Connection ...
await Response.Body.FlushAsync();
}
catch (Exception)
{ }
}
#endregion
}
}