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 { /// /// a Controller Which Provides Actions for /// using Ai Service ... /// public class AIController : XIBaseV1Controller { /// /// Ai Provider ... /// private readonly IXAiProvider aiService; // #region Constructor ... public AIController( IXAiProvider aiService, ILogger logger, XAppConfiguration appConfiguration, IXIdentityProvider identityProvider, XValidationProvider validationProvider ) : base( logger, appConfiguration, identityProvider, validationProvider ) { this.aiService = aiService; } #endregion // #region Actions ... /// /// As a Message from Ai ... /// /// /// /// /// /// [HttpGet("Ask")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> 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; } } /// /// As a Message from Ai ... /// /// /// /// specified prompt /// active Project Id /// active Conversation Id /// /// Ai Model's answer [HttpGet("AskAI")] [Authorize(Policy = XPolicies.EnabledUser)] public async Task> 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; } } /// /// Ask a Message from Ai using Streamin Pattern ... /// /// /// /// /// /// [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) { } } /// /// Ask a Message from Ai using Streamin Pattern ... /// /// /// /// /// /// [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 } }