This commit is contained in:
2026-09-28 16:34:36 +03:30
parent a4dee3b5a4
commit 2aa0607e85
5 changed files with 758 additions and 188 deletions
+54 -5
View File
@@ -1,10 +1,12 @@
using System;
using System.Linq;
using xAiModels.Models;
using xModels.Extensions;
using xCommons.Extensions;
using xAiModels.Constants;
using xAiModels.Models.Dtos;
using xExceptions.Constants;
using Microsoft.Extensions.AI;
using xAiModels.Models.Entities;
using System.Collections.Generic;
@@ -177,6 +179,22 @@ namespace xAiModels.Extensions
return result;
}
/// <summary>
/// Validate a Request for Retrieve Response in Controllers ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsValid(this XAiResponseRequest source)
{
//
var result =
!source.IsNullOrDefault() &&
!source.Prompt.IsNullOrEmpty();
//
return result;
}
/// <summary>
/// Check a Collection Contains Default Project for Specified Owner or not ...
/// </summary>
@@ -211,7 +229,7 @@ namespace xAiModels.Extensions
var result = !item.IsNullOrDefault();
//
return result;
return result;
}
/// <summary>
@@ -253,7 +271,7 @@ namespace xAiModels.Extensions
var result = !item.IsNullOrDefault();
//
return result;
return result;
}
/// <summary>
@@ -293,7 +311,7 @@ namespace xAiModels.Extensions
//
return item.Id;
}
/// <summary>
/// Get Default Conversation Id from a Collection Contains ...
/// </summary>
@@ -333,7 +351,38 @@ namespace xAiModels.Extensions
var result = item.Id;
//
return result;
}
return result;
}
public static ChatMessage ToChatMessages(
this XAiMessageDto source
)
{
//
// TODO: Handle Files Attached here ...
//
ChatMessage result = null;
//
if (!source.IsNullOrDefault())
{
//
result = new ChatMessage
{
AuthorName =
source.Role == XAiChatRole.User &&
!source.Owner.IsNullOrDefault()
? source.Owner.GetFullname()
: string.Empty,
Role = source.Role.ToChatRole(),
MessageId = source.Id.ToString(),
Contents = [new TextContent(source.Content)]
};
}
//
return result;
}
}
}
+146 -1
View File
@@ -11,18 +11,51 @@ namespace xAiModels.Interfaces
/// </summary>
public interface IXAiDataProvider
{
//
#region Getters ...
/// <summary>
/// Retrieve Specified Project ...
/// </summary>
/// <param name="id"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiProjectDto> GetProject(
Guid id,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Specified Conversation ...
/// </summary>
/// <param name="id"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiConversationDto> GetConversation(
Guid id,
bool fillMessages = false,
CancellationToken cancellationToken = default
);
#endregion
//
#region Loaders ...
/// <summary>
/// Load Projects List of Specified Owner ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="connectionId"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XAiProjectDto>> LoadProjects(
string ownerId,
string connectionId = null,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
@@ -33,11 +66,13 @@ namespace xAiModels.Interfaces
/// </summary>
/// <param name="projectId"></param>
/// <param name="fillMessages"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XAiConversationDto>> LoadConversations(
Guid projectId,
bool fillMessages = false,
string connectionId = null,
CancellationToken cancellationToken = default
);
@@ -54,7 +89,117 @@ namespace xAiModels.Interfaces
#endregion
//
#region Default Identifiers ...
#region Enrichers ...
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiProjectDto> Enrich(
XAiProjectDto source,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XAiProjectDto>> EnrichRange(
IEnumerable<XAiProjectDto> sources,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiConversationDto> Enrich(
XAiConversationDto source,
bool fillMessages = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XAiConversationDto>> EnrichRange(
IEnumerable<XAiConversationDto> sources,
bool fillMessages = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiMessageDto> Enrich(
XAiMessageDto source,
CancellationToken cancellationToken = default
);
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<XAiMessageDto>> EnrichRange(
IEnumerable<XAiMessageDto> sources,
CancellationToken cancellationToken = default
);
#endregion
//
#region Defaults ...
/// <summary>
/// Retrieve Default Project of Specified Owner ...
/// Create it if not Handled ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiProjectDto> GetDefaultProject(
string ownerId,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Default Conversation of Specified Owner ...
/// Create it if not Handled ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XAiConversationDto> GetDefaultConversation(
string ownerId,
Guid projectId,
string connectionId = null,
CancellationToken cancellationToken = default
);
#endregion
//
+16
View File
@@ -0,0 +1,16 @@
using System;
using xModels.Base;
using xAiModels.Constants;
namespace xAiModels.Models
{
public class XAiResonseMessage : XBaseDto
{
public long Sequence { get; set; }
public Guid RespondTo { get; set; }
public string OwnerId { get; set; }
public string Content { get; set; }
public XAiChatRole Role { get; set; }
public DateTime RespondedOn { get; set; }
}
}
+25
View File
@@ -0,0 +1,25 @@
using System;
namespace xAiModels.Models
{
/// <summary>
/// /Request for a Response in Controllers ...
/// </summary>
public class XAiResponseRequest
{
/// <summary>
/// Prompt Text ...
/// </summary>
public string Prompt { get; set; }
/// <summary>
/// Specified Project Id ...
/// </summary>
public Guid ProjectId { get; set; }
/// <summary>
/// Specified Conversation Id ...
/// </summary>
public Guid ConversationId { get; set; }
}
}
+517 -182
View File
@@ -15,6 +15,7 @@ using xAiModels.Interfaces.Dtos;
using xStringService.Interfaces;
using System.Collections.Generic;
using Microsoft.AspNetCore.SignalR;
using xAiModels.Interfaces.Enrichers;
namespace xAiModels.Providers
{
@@ -28,6 +29,9 @@ namespace xAiModels.Providers
private readonly IXStringProvider stringProvider;
private readonly XAppConfiguration appConfiguration;
private readonly IHubContext<XAiDataProviderHub> hub;
private readonly IXAiMessageEnricher messageEnricher;
private readonly IXAiProjectEnricher projectEnricher;
private readonly IXAiConversationEnricher conversationEnricher;
private readonly IXAiMessageRepositoryService messageRepositoryService;
private readonly IXAiProjectRepositoryService projectRepositoryService;
private readonly IXAiProjectTitleResourceProvider projectTitleResourceProvider;
@@ -40,6 +44,9 @@ namespace xAiModels.Providers
IXStringProvider stringProvider,
XAppConfiguration appConfiguration,
IHubContext<XAiDataProviderHub> hub,
IXAiProjectEnricher projectEnricher,
IXAiMessageEnricher messageEnricher,
IXAiConversationEnricher conversationEnricher,
IXAiMessageRepositoryService messageRepositoryService,
IXAiProjectRepositoryService projectRepositoryService,
IXAiProjectTitleResourceProvider projectTitleResourceProvider,
@@ -50,7 +57,10 @@ namespace xAiModels.Providers
{
this.hub = hub;
this.stringProvider = stringProvider;
this.projectEnricher = projectEnricher;
this.messageEnricher = messageEnricher;
this.appConfiguration = appConfiguration;
this.conversationEnricher = conversationEnricher;
this.messageRepositoryService = messageRepositoryService;
this.projectRepositoryService = projectRepositoryService;
this.projectTitleResourceProvider = projectTitleResourceProvider;
@@ -65,12 +75,14 @@ namespace xAiModels.Providers
/// Load Projects List of Specified Owner ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="connectionId"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XAiProjectDto>> LoadProjects(
string ownerId,
string connectionId = null,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
@@ -85,6 +97,9 @@ namespace xAiModels.Providers
//
// Handle Default Project and Conversation ...
//
// Default Project ...
bool hasDefault = await HasDefaultProject(
ownerId: ownerId,
cancellationToken: cancellationToken
@@ -94,7 +109,30 @@ namespace xAiModels.Providers
//
await CreateDefaultProject(
ownerId: ownerId,
connectionId: null,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
var defaultProject = await GetDefaultProject(
ownerId: ownerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
// Default Project's Default Conversation ...
hasDefault = await HasDefaultConversation(
ownerId: ownerId,
projectId: defaultProject.Id,
cancellationToken: cancellationToken
);
if (!hasDefault)
{
//
await CreateDefaultConversation(
ownerId: ownerId,
connectionId: connectionId,
projectId: defaultProject.Id,
cancellationToken: cancellationToken
);
}
@@ -109,6 +147,18 @@ namespace xAiModels.Providers
orderBuilder: x => x.OrderBy(y => y.CreatedOn)
);
//
if (result.HasChild())
{
//
result = await projectEnricher.EnrichRange(
sources: result,
cancellationToken: cancellationToken,
fillConversations: fillConversations,
fillConversationMessages: fillConversationMessages
);
}
//
return result;
}
@@ -117,12 +167,14 @@ namespace xAiModels.Providers
/// Load List of Conversations for Specified Project ...
/// </summary>
/// <param name="projectId"></param>
/// <param name="connectionId"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XAiConversationDto>> LoadConversations(
Guid projectId,
bool fillMessages = false,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
@@ -135,6 +187,38 @@ namespace xAiModels.Providers
XException.InvalidArgs.Throw();
}
//
// Retrieve Project ...
var project = await projectRepositoryService.GetAsync(
id: projectId,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (project.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Default Conversation ...
var hasDefault = await HasDefaultConversation(
projectId: projectId,
ownerId: project.OwnerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!hasDefault)
{
//
await CreateDefaultConversation(
projectId: projectId,
ownerId: project.OwnerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
//
// Retrieve Conversation's List ...
var result = await conversationRepositoryService.FindManyAsync(
@@ -145,6 +229,17 @@ namespace xAiModels.Providers
orderBuilder: x => x.OrderBy(y => y.CreatedOn)
);
//
if (result.HasChild())
{
//
result = await conversationEnricher.EnrichRange(
sources: result,
fillMessages: fillMessages,
cancellationToken: cancellationToken
);
}
//
return result;
}
@@ -169,6 +264,18 @@ namespace xAiModels.Providers
XException.InvalidArgs.Throw();
}
//
var conversation = await conversationRepositoryService.GetAsync(
id: conversationId,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (conversation.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Retrieve Message Lists of Specified Conversation ...
var result = await messageRepositoryService.FindManyAsync(
@@ -179,6 +286,110 @@ namespace xAiModels.Providers
predicate: x => x.ConversationId == conversationId
);
//
if (result.HasChild())
{
//
result = await messageEnricher.EnrichRange(
sources: result,
cancellationToken: cancellationToken
);
}
//
return result;
}
#endregion
//
#region Getters ...
/// <summary>
/// Retrieve Specified Project ...
/// </summary>
/// <param name="id"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiProjectDto> GetProject(
Guid id,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
if (id.IsDefaultGuid())
{
XException.InvalidArgs.Throw();
}
//
var result = await projectRepositoryService.GetAsync(
id: id,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Handle Enrichment ...
result = await projectEnricher.Enrich(
source: result,
fillConversations: fillConversations,
cancellationToken: cancellationToken,
fillConversationMessages: fillConversationMessages
);
//
return result;
}
/// <summary>
/// Retrieve Specified Conversation ...
/// </summary>
/// <param name="id"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiConversationDto> GetConversation(
Guid id,
bool fillMessages = false,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
if (id.IsDefaultGuid())
{
XException.InvalidArgs.Throw();
}
//
var result = await conversationRepositoryService.GetAsync(
id: id,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Handle Enrichment ...
result = await conversationEnricher.Enrich(
source: result,
fillMessages: fillMessages,
cancellationToken: cancellationToken
);
//
return result;
}
@@ -467,48 +678,7 @@ namespace xAiModels.Providers
#endregion
//
#region Private ...
/// <summary>
/// Check Default Project Exists or not ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<bool> HasDefaultProject(
string ownerId,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
var result = !ownerId.IsNullOrEmpty();
if (!result)
{
return result;
}
//
// Check Default Owner Exists or not ...
result = !(await stringProvider.FindOne(
cancellationToken: cancellationToken,
predicate: x =>
x.ResourceTitle
.ToNormalString()
.Contains(ownerId.ToNormalString()) &&
x.ResourceTitle
.ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier
.ToNormalString()) &&
x.TranslatedValue
.ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix)
))
.IsNullOrDefault();
return result;
}
#region Defaults ...
/// <summary>
/// Retrieve Default Project of Specified Owner ...
/// Create it if not Handled ...
@@ -517,7 +687,7 @@ namespace xAiModels.Providers
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XAiProjectDto> GetDefaultProject(
public async Task<XAiProjectDto> GetDefaultProject(
string ownerId,
string connectionId = null,
CancellationToken cancellationToken = default
@@ -527,7 +697,6 @@ namespace xAiModels.Providers
// Check Default Project Exists or noit ...
var isExists = await HasDefaultProject(
ownerId: ownerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!isExists)
@@ -578,6 +747,309 @@ namespace xAiModels.Providers
return result;
}
/// <summary>
/// Retrieve Default Conversation of Specified Owner ...
/// Create it if not Handled ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiConversationDto> GetDefaultConversation(
string ownerId,
Guid projectId,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
if (ownerId.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Prepare Project ...
XAiProjectDto project = null;
if (projectId.IsNull() ||
projectId.IsDefaultGuid()
)
{
//
project = await GetDefaultProject(
ownerId: ownerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
else
{
//
project = await projectRepositoryService.GetAsync(
id: project.Id,
includeBuilder: null,
ignoreSoftDeleteds: true,
// fillConversations: false,
// fillConversationMessages: false,
cancellationToken: cancellationToken
);
}
if (project.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Check Default Conversation Exists or noit ...
var isExists = await HasDefaultConversation(
ownerId: ownerId,
projectId: project.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!isExists)
{
//
await CreateDefaultConversation(
ownerId: ownerId,
projectId: project.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
//
// Detect Conversation Resource ...
var resource = await stringProvider.FindOne(
cancellationToken: cancellationToken,
predicate: x =>
x.ResourceTitle
.ToNormalString()
.Contains(ownerId.ToNormalString()) &&
x.ResourceTitle
.ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier
.ToNormalString()) &&
x.TranslatedValue
.ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix)
);
if (resource.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Find Default Conversation ...
var result = await conversationRepositoryService.FindOneAsync(
cancellationToken: cancellationToken,
predicate: x => x.Title
.Equals(
resource.ResourceTitle,
StringComparison.InvariantCultureIgnoreCase
) &&
x.ProjectId == project.Id
);
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
return result;
}
#endregion
//
#region Enrichers ...
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiProjectDto> Enrich(
XAiProjectDto source,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
)
{
//
var result = await projectEnricher.Enrich(
source: source,
fillConversations: fillConversations,
cancellationToken: cancellationToken,
fillConversationMessages: fillConversationMessages
);
//
return result;
}
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="fillConversations"></param>
/// <param name="fillConversationMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XAiProjectDto>> EnrichRange(
IEnumerable<XAiProjectDto> sources,
bool fillConversations = false,
bool fillConversationMessages = false,
CancellationToken cancellationToken = default
)
{
//
var result = await projectEnricher.EnrichRange(
sources: sources,
fillConversations: fillConversations,
cancellationToken: cancellationToken,
fillConversationMessages: fillConversationMessages
);
//
return result;
}
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiConversationDto> Enrich(
XAiConversationDto source,
bool fillMessages = false,
CancellationToken cancellationToken = default
)
{
//
var result = await conversationEnricher.Enrich(
source: source,
fillMessages: fillMessages,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="fillMessages"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XAiConversationDto>> EnrichRange(
IEnumerable<XAiConversationDto> sources,
bool fillMessages = false,
CancellationToken cancellationToken = default
)
{
//
var result = await conversationEnricher.EnrichRange(
sources: sources,
fillMessages: fillMessages,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Enrich Specified Item ...
/// </summary>
/// <param name="source"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiMessageDto> Enrich(
XAiMessageDto source,
CancellationToken cancellationToken = default
)
{
//
var result = await messageEnricher.Enrich(
source: source,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Enrich Specified Items ...
/// </summary>
/// <param name="sources"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XAiMessageDto>> EnrichRange(
IEnumerable<XAiMessageDto> sources,
CancellationToken cancellationToken = default
)
{
//
var result = await messageEnricher.EnrichRange(
sources: sources,
cancellationToken: cancellationToken
);
//
return result;
}
#endregion
//
#region Private ...
/// <summary>
/// Check Default Project Exists or not ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<bool> HasDefaultProject(
string ownerId,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
var result = !ownerId.IsNullOrEmpty();
if (!result)
{
return result;
}
//
// Check Default Owner Exists or not ...
result = !(await stringProvider.FindOne(
cancellationToken: cancellationToken,
predicate: x =>
x.ResourceTitle
.ToNormalString()
.Contains(ownerId.ToNormalString()) &&
x.ResourceTitle
.ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier
.ToNormalString()) &&
x.TranslatedValue
.ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix)
))
.IsNullOrDefault();
return result;
}
/// <summary>
/// Create Default Project for Specified Owner ...
/// </summary>
@@ -890,143 +1362,6 @@ namespace xAiModels.Providers
}
}
/// <summary>
/// Retrieve Default Conversation of Specified Owner ...
/// Create it if not Handled ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XAiConversationDto> GetDefaultConversation(
string ownerId,
Guid projectId,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
if (ownerId.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Prepare Project ...
XAiProjectDto project = null;
if (projectId.IsNull() ||
projectId.IsDefaultGuid()
)
{
//
project = await GetDefaultProject(
ownerId: ownerId,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
else
{
//
project = await projectRepositoryService.GetAsync(
id: project.Id,
includeBuilder: null,
ignoreSoftDeleteds: true,
// fillConversations: false,
// fillConversationMessages: false,
cancellationToken: cancellationToken
);
}
if (project.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Check Default Conversation Exists or noit ...
var isExists = await HasDefaultConversation(
ownerId: ownerId,
projectId: project.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!isExists)
{
//
await CreateDefaultConversation(
ownerId: ownerId,
projectId: project.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
//
// Detect Conversation Resource ...
var resource = await stringProvider.FindOne(
cancellationToken: cancellationToken,
predicate: x =>
x.ResourceTitle
.ToNormalString()
.Contains(ownerId.ToNormalString()) &&
x.ResourceTitle
.ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier
.ToNormalString()) &&
x.TranslatedValue
.ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix)
);
if (resource.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
// Find Default Conversation ...
var result = await conversationRepositoryService.FindOneAsync(
cancellationToken: cancellationToken,
predicate: x => x.Title
.Equals(
resource.ResourceTitle,
StringComparison.InvariantCultureIgnoreCase
) &&
x.ProjectId == project.Id
);
if (result.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
return result;
}
/// <summary>
/// Normalize and Validate Language ...
/// </summary>
/// <param name="language"></param>
/// <returns></returns>
private string NormalizeAndValidateLanguage(string language)
{
//
if (language.IsNullOrEmpty())
{
language = appConfiguration.DefaultLanguage;
}
//
if (language.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
return language;
}
/// <summary>
/// Send Custom Push Message ...
/// </summary>