Compare commits

...
5 Commits
Author SHA1 Message Date
saherelm 26df2c7ebc last ... 2026-10-02 22:12:26 +03:30
saherelm 755eafa7d2 Add Support for Attaching Additional Contents to Specified Prompt Message when Converting to Chat Message, Specified For File Support ... 2026-09-30 23:12:39 +03:30
saherelm 47b2cbc0d2 last ... 2026-09-30 15:27:26 +03:30
saherelm f48b9257a3 last ... 2026-09-29 17:41:17 +03:30
saherelm 5d3601ba44 last ... 2026-09-28 22:36:16 +03:30
5 changed files with 662 additions and 36 deletions
+95 -17
View File
@@ -28,7 +28,6 @@ namespace xAiModels.Extensions
var result = var result =
!source.IsNullOrDefault() && !source.IsNullOrDefault() &&
!source.OwnerId.IsNullOrEmpty() && !source.OwnerId.IsNullOrEmpty() &&
!source.Title.IsNullOrEmpty() &&
!source.Prompt.IsNullOrEmpty(); !source.Prompt.IsNullOrEmpty();
// //
@@ -40,7 +39,6 @@ namespace xAiModels.Extensions
var result = var result =
!source.IsNullOrDefault() && !source.IsNullOrDefault() &&
!source.OwnerId.IsNullOrEmpty() && !source.OwnerId.IsNullOrEmpty() &&
!source.Title.IsNullOrEmpty() &&
!source.Prompt.IsNullOrEmpty(); !source.Prompt.IsNullOrEmpty();
// //
@@ -58,7 +56,6 @@ namespace xAiModels.Extensions
var result = var result =
!source.IsNullOrDefault() && !source.IsNullOrDefault() &&
!source.OwnerId.IsNullOrEmpty() && !source.OwnerId.IsNullOrEmpty() &&
!source.Title.IsNullOrEmpty() &&
!source.ProjectId.IsNull() && !source.ProjectId.IsNull() &&
!source.ProjectId.IsDefaultGuid(); !source.ProjectId.IsDefaultGuid();
@@ -71,7 +68,6 @@ namespace xAiModels.Extensions
var result = var result =
!source.IsNullOrDefault() && !source.IsNullOrDefault() &&
!source.OwnerId.IsNullOrEmpty() && !source.OwnerId.IsNullOrEmpty() &&
!source.Title.IsNullOrEmpty() &&
!source.ProjectId.IsNull() && !source.ProjectId.IsNull() &&
!source.ProjectId.IsDefaultGuid(); !source.ProjectId.IsDefaultGuid();
@@ -195,6 +191,67 @@ namespace xAiModels.Extensions
return result; return result;
} }
/// <summary>
/// Validate a File Extraction Result ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsValid(this XFileExtractionResult source)
{
//
var result =
!source.IsNullOrDefault() &&
(
source.Images.HasChild() ||
!source.Text.IsNullOrEmpty() ||
!source.AudioTranscript.IsNullOrEmpty()
);
return result;
}
/// <summary>
/// Converts a File Extraction Result to AI Contents ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static IList<AIContent> ToAIContents(this XFileExtractionResult source)
{
//
var result = new List<AIContent>();
//
if (source.IsValid())
{
//
// Main Text ...
if (!source.Text.IsNullOrEmpty())
{
result.Add(new TextContent(source.Text));
}
//
// Images ...
if (source.Images.HasChild())
{
//
foreach (var img in source.Images)
{
result.Add(new DataContent(img.Bytes, img.MimeType));
}
}
//
// Transcripted Audio ...
if (!source.AudioTranscript.IsNullOrEmpty())
{
result.Add(new TextContent($"[Audio Transcript]\n{source.AudioTranscript}"));
}
}
//
return result;
}
/// <summary> /// <summary>
/// Check a Collection Contains Default Project for Specified Owner or not ... /// Check a Collection Contains Default Project for Specified Owner or not ...
/// </summary> /// </summary>
@@ -222,7 +279,7 @@ namespace xAiModels.Extensions
.Contains(ownerId.ToNormalString()) && .Contains(ownerId.ToNormalString()) &&
x.Title x.Title
.ToNormalString() .ToNormalString()
.Contains(XAiModelsConstants.DefaultXAiProjectDescriptionResourceID) .Contains(XAiModelsConstants.DefaultXAiProjectDescriptionResourceID.ToNormalString())
); );
// //
@@ -287,7 +344,7 @@ namespace xAiModels.Extensions
{ {
// //
// Validate Args ... // Validate Args ...
if (source.HasChild() || if (!source.HasChild() ||
ownerId.IsNullOrEmpty()) ownerId.IsNullOrEmpty())
{ {
XException.InvalidArgs.Throw(); XException.InvalidArgs.Throw();
@@ -301,7 +358,7 @@ namespace xAiModels.Extensions
.Contains(ownerId.ToNormalString()) && .Contains(ownerId.ToNormalString()) &&
x.Title x.Title
.ToNormalString() .ToNormalString()
.Contains(XAiModelsConstants.DefaultXAiProjectDescriptionResourceID) .Contains(XAiModelsConstants.XAiProjectTitleIdentifier.ToNormalString())
); );
if (item.IsNullOrDefault()) if (item.IsNullOrDefault())
{ {
@@ -327,7 +384,8 @@ namespace xAiModels.Extensions
{ {
// //
// Validate Args ... // Validate Args ...
if (source.HasChild() || if (!source.HasChild() ||
ownerId.IsNullOrEmpty() ||
projectId.IsDefaultGuid()) projectId.IsDefaultGuid())
{ {
XException.InvalidArgs.Throw(); XException.InvalidArgs.Throw();
@@ -341,11 +399,12 @@ namespace xAiModels.Extensions
.Contains(ownerId.ToNormalString()) && .Contains(ownerId.ToNormalString()) &&
x.Title x.Title
.ToNormalString() .ToNormalString()
.Contains(projectId.ToString().ToNormalString()) && .Contains(XAiModelsConstants.XAiConversationTitleIdentifier.ToNormalString())
x.Title
.ToNormalString()
.Contains(XAiModelsConstants.DefaultXAiConversationTitleResourceID)
); );
if (item.IsNullOrDefault())
{
XException.NotFound.Throw();
}
// //
var result = item.Id; var result = item.Id;
@@ -354,22 +413,42 @@ namespace xAiModels.Extensions
return result; return result;
} }
/// <summary>
/// Converts a Message Dto to ChatMessage ...
/// </summary>
/// <param name="source"></param>
/// <param name="additionalContents"></param>
/// <returns></returns>
public static ChatMessage ToChatMessages( public static ChatMessage ToChatMessages(
this XAiMessageDto source this XAiMessageDto source,
IList<AIContent> additionalContents = null
) )
{ {
//
// TODO: Handle Files Attached here ...
// //
ChatMessage result = null; ChatMessage result = null;
// //
if (!source.IsNullOrDefault()) if (!source.IsNullOrDefault())
{ {
//
var contents = new List<AIContent>
{
//
// Add Source Content ...
new TextContent(source.Content)
};
//
// Add Additional Content ...
if (additionalContents.HasChild())
{
contents.AddRange(additionalContents);
}
// //
result = new ChatMessage result = new ChatMessage
{ {
Contents = contents,
AuthorName = AuthorName =
source.Role == XAiChatRole.User && source.Role == XAiChatRole.User &&
!source.Owner.IsNullOrDefault() !source.Owner.IsNullOrDefault()
@@ -377,7 +456,6 @@ namespace xAiModels.Extensions
: string.Empty, : string.Empty,
Role = source.Role.ToChatRole(), Role = source.Role.ToChatRole(),
MessageId = source.Id.ToString(), MessageId = source.Id.ToString(),
Contents = [new TextContent(source.Content)]
}; };
} }
+49
View File
@@ -1,4 +1,5 @@
using System; using System;
using xModels.Dtos;
using System.Threading; using System.Threading;
using xAiModels.Models.Dtos; using xAiModels.Models.Dtos;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -222,12 +223,14 @@ namespace xAiModels.Interfaces
/// <summary> /// <summary>
/// Create Conversation ... /// Create Conversation ...
/// </summary> /// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param> /// <param name="projectId"></param>
/// <param name="item"></param> /// <param name="item"></param>
/// <param name="connectionId"></param> /// <param name="connectionId"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
Task<XAiConversationDto> CreateConversation( Task<XAiConversationDto> CreateConversation(
string ownerId,
Guid projectId, Guid projectId,
XAiConversationDto item = null, XAiConversationDto item = null,
string connectionId = null, string connectionId = null,
@@ -249,5 +252,51 @@ namespace xAiModels.Interfaces
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
#endregion #endregion
//
#region Query ...
/// <summary>
/// Query Projects ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XQueryResult<XAiProjectDto>> QueryProjects(
string ownerId,
XQuery query,
CancellationToken cancellationToken = default
);
/// <summary>
/// Query Conversations ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XQueryResult<XAiConversationDto>> QueryConversations(
string ownerId,
Guid projectId,
XQuery query,
CancellationToken cancellationToken = default
);
/// <summary>
/// Query Messages ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="conversationId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XQueryResult<XAiMessageDto>> QueryMessages(
string ownerId,
Guid conversationId,
XQuery query,
CancellationToken cancellationToken = default
);
#endregion
} }
} }
+71
View File
@@ -0,0 +1,71 @@
using System.Collections.Generic;
namespace xAiModels.Models
{
/// <summary>
/// Holds File Extraction Result ...
/// </summary>
public class XFileExtractionResult
{
/// <summary>
/// Extracted String Content ...
/// </summary>
public string Text { get; set; } = string.Empty;
/// <summary>
/// Extracted Images for Vision Model ...
/// </summary>
public IList<XExtractedImage> Images { get; set; } = [];
/// <summary>
/// Extracted Content from Audio File ...
/// </summary>
public string AudioTranscript { get; set; } = string.Empty;
/// <summary>
/// Main File Name ...
/// </summary>
public string FileName { get; set; }
/// <summary>
/// Main File MIME Type ...
/// </summary>
public string MimeType { get; set; }
/// <summary>
/// Specified Fallback done using Images or not ...
/// </summary>
public bool UsedImageFallback { get; set; } = false;
/// <summary>
/// Error Message ...
/// </summary>
public string ErrorMessage { get; set; }
}
/// <summary>
/// Extracted Image ...
/// </summary>
public class XExtractedImage
{
/// <summary>
/// Content as Byte ...
/// </summary>
public byte[] Bytes { get; set; }
/// <summary>
/// MIME Type of Image ...
/// </summary>
public string MimeType { get; set; } = "image/png";
/// <summary>
/// for PDF Files ...
/// </summary>
public int? PageNumber { get; set; }
/// <summary>
/// Describe Image ...
/// </summary>
public string Description { get; set; }
}
}
@@ -134,7 +134,9 @@ namespace xAiModels.Providers.Enrichers
result.Owner = owner; result.Owner = owner;
result.TitleResource = titleResource; result.TitleResource = titleResource;
result.ProjectTitleResource = projectTitleResource; result.ProjectTitleResource = projectTitleResource;
result.ProjectTitle = projectTitleResource.Resource;
result.ProjectDescriptionResource = projectDescriptionResource; result.ProjectDescriptionResource = projectDescriptionResource;
result.ProjectDescription = projectDescriptionResource.Resource;
// //
return result; return result;
+445 -19
View File
@@ -10,9 +10,12 @@ using xAiModels.Models.Dtos;
using xExceptions.Constants; using xExceptions.Constants;
using System.Threading.Tasks; using System.Threading.Tasks;
using xCommons.Configurations; using xCommons.Configurations;
using System.Linq.Expressions;
using xDataService.Extensions;
using xAiModels.Providers.Hubs; using xAiModels.Providers.Hubs;
using xAiModels.Interfaces.Dtos; using xAiModels.Interfaces.Dtos;
using xStringService.Interfaces; using xStringService.Interfaces;
using xAiModels.Models.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using xAiModels.Interfaces.Enrichers; using xAiModels.Interfaces.Enrichers;
@@ -397,6 +400,14 @@ namespace xAiModels.Providers
// //
#region Creator/Adders ... #region Creator/Adders ...
/// <summary>
/// Create Project ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiProjectDto> CreateProject( public async Task<XAiProjectDto> CreateProject(
string ownerId, string ownerId,
XAiProjectDto item = null, XAiProjectDto item = null,
@@ -420,6 +431,7 @@ namespace xAiModels.Providers
if (hasProject) if (hasProject)
{ {
// //
item.OwnerId = ownerId;
item.CreatedOn = DateTime.UtcNow; item.CreatedOn = DateTime.UtcNow;
// //
@@ -432,18 +444,132 @@ namespace xAiModels.Providers
// //
XAiProjectDto result = null; XAiProjectDto result = null;
var defaultLanguage = appConfiguration.DefaultLanguage;
// //
// Create Provided Project ... // Create Provided Project ...
if (hasProject) if (hasProject)
{ {
// //
// Add Item for ID Gneneration ...
result = await projectRepositoryService.AddAsync( result = await projectRepositoryService.AddAsync(
item: item, item: item,
saveChanges: true, saveChanges: true,
cancellationToken: cancellationToken cancellationToken: cancellationToken
); );
//
// Checking Resources ...
//
// Titles ...
var titleResource = string.Empty;
if (!item.TitleResource.IsNullOrDefault() &&
item.TitleResource.Locales.HasChild())
{
//
// Adding Title Resource Locales ...
var isDefaultLanguageHandled = false;
foreach (var trl in item.TitleResource.Locales)
{
//
// Attaching Default Language ...
if (!isDefaultLanguageHandled &&
trl.Language.IsNullOrEmpty())
{
//
trl.Language = defaultLanguage;
isDefaultLanguageHandled = false;
}
//
// Check Value Exists ...
if (trl.Value.IsNullOrEmpty())
{
continue;
}
//
var resource = await projectTitleResourceProvider.AddOrUpdateLocale(
locale: trl,
owner: ownerId,
identifier: result.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!resource.IsNullOrDefault() &&
titleResource.IsNullOrEmpty())
{
titleResource = resource.Resource;
}
}
}
//
// Descriptions ...
var descriptionResource = string.Empty;
if (!item.DescriptionResource.IsNullOrDefault() &&
item.DescriptionResource.Locales.HasChild())
{
//
// Adding Description Resource Locales ....
var isDefaultLanguageHandled = false;
foreach (var trl in item.DescriptionResource.Locales)
{
//
// Attaching Default Language ...
if (!isDefaultLanguageHandled &&
trl.Language.IsNullOrEmpty())
{
//
trl.Language = defaultLanguage;
isDefaultLanguageHandled = false;
}
//
// Check Value Exists ...
if (trl.Value.IsNullOrEmpty())
{
continue;
}
//
var resource = await projectDescriptionResourceProvider.AddOrUpdateLocale(
locale: trl,
owner: ownerId,
identifier: result.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!resource.IsNullOrDefault() &&
descriptionResource.IsNullOrEmpty())
{
descriptionResource = resource.Resource;
}
}
}
//
// Update Data ...
result.Title = titleResource;
result.Description = descriptionResource;
result = await projectRepositoryService.UpdateAsync(
item: result,
id: result.Id,
saveChanges: true,
cancellationToken: cancellationToken
);
if (!result.IsNullOrDefault())
{
//
result = await projectEnricher.Enrich(
source: result,
fillConversations: false,
fillConversationMessages: false,
cancellationToken: cancellationToken
);
}
// //
// Handling Send Push Notification ... // Handling Send Push Notification ...
if (!result.IsNullOrDefault() && if (!result.IsNullOrDefault() &&
@@ -493,11 +619,30 @@ namespace xAiModels.Providers
XException.ActionFailed.Throw(); XException.ActionFailed.Throw();
} }
//
// Handle Enrichment ...
result = await Enrich(
source: result,
fillConversations: false,
fillConversationMessages: false,
cancellationToken: cancellationToken
);
// //
return result; return result;
} }
/// <summary>
/// Create an AI Conversation ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiConversationDto> CreateConversation( public async Task<XAiConversationDto> CreateConversation(
string ownerId,
Guid projectId, Guid projectId,
XAiConversationDto item = null, XAiConversationDto item = null,
string connectionId = null, string connectionId = null,
@@ -536,6 +681,7 @@ namespace xAiModels.Providers
if (hasConversation) if (hasConversation)
{ {
// //
item.OwnerId = ownerId;
item.ProjectId = project.Id; item.ProjectId = project.Id;
item.CreatedOn = DateTime.UtcNow; item.CreatedOn = DateTime.UtcNow;
@@ -549,12 +695,14 @@ namespace xAiModels.Providers
// //
XAiConversationDto result = null; XAiConversationDto result = null;
var defaultLanguage = appConfiguration.DefaultLanguage;
// //
// Create Provided Conversation ... // Create Provided Conversation ...
if (hasConversation) if (hasConversation)
{ {
// //
// Add Item for ID Gneneration ...
result = await conversationRepositoryService.AddAsync( result = await conversationRepositoryService.AddAsync(
item: item, item: item,
saveChanges: true, saveChanges: true,
@@ -562,6 +710,72 @@ namespace xAiModels.Providers
cancellationToken: cancellationToken cancellationToken: cancellationToken
); );
//
// Checking Resources ...
//
// Titles ...
var titleResource = string.Empty;
if (!item.TitleResource.IsNullOrDefault() &&
item.TitleResource.Locales.HasChild())
{
//
// Adding Title Resource Locales ...
var isDefaultLanguageHandled = false;
foreach (var trl in item.TitleResource.Locales)
{
//
// Attaching Default Language ...
if (!isDefaultLanguageHandled &&
trl.Language.IsNullOrEmpty())
{
//
trl.Language = defaultLanguage;
isDefaultLanguageHandled = false;
}
//
// Check Value Exists ...
if (trl.Value.IsNullOrEmpty())
{
continue;
}
//
var resource = await conversationTitleResourceProvider.AddOrUpdateLocale(
locale: trl,
owner: ownerId,
identifier: result.Id,
connectionId: connectionId,
cancellationToken: cancellationToken
);
if (!resource.IsNullOrDefault() &&
titleResource.IsNullOrEmpty())
{
titleResource = resource.Resource;
}
}
}
//
// Update Data ...
result.Title = titleResource;
result = await conversationRepositoryService.UpdateAsync(
item: result,
id: result.Id,
saveChanges: true,
cancellationToken: cancellationToken
);
if (!result.IsNullOrDefault())
{
//
result = await conversationEnricher.Enrich(
source: result,
fillMessages: false,
cancellationToken: cancellationToken
);
}
// //
// Handling Send Push Notification ... // Handling Send Push Notification ...
if (!result.IsNullOrDefault() && if (!result.IsNullOrDefault() &&
@@ -613,10 +827,26 @@ namespace xAiModels.Providers
XException.ActionFailed.Throw(); XException.ActionFailed.Throw();
} }
//
// Handle Enrichment ...
result = await Enrich(
source: result,
fillMessages: false,
cancellationToken: cancellationToken
);
// //
return result; return result;
} }
/// <summary>
/// Add Message ...
/// </summary>
/// <param name="conversationId"></param>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XAiMessageDto> AddMessage( public async Task<XAiMessageDto> AddMessage(
Guid conversationId, Guid conversationId,
XAiMessageDto item, XAiMessageDto item,
@@ -653,6 +883,17 @@ namespace xAiModels.Providers
cancellationToken: cancellationToken cancellationToken: cancellationToken
); );
//
// Handle Enrichment ...
if (!result.IsNullOrDefault())
{
//
result = await Enrich(
source: result,
cancellationToken: cancellationToken
);
}
// //
// Handling Send Push Notification ... // Handling Send Push Notification ...
if (!result.IsNullOrDefault() && if (!result.IsNullOrDefault() &&
@@ -718,11 +959,10 @@ namespace xAiModels.Providers
.Contains(ownerId.ToNormalString()) && .Contains(ownerId.ToNormalString()) &&
x.ResourceTitle x.ResourceTitle
.ToNormalString() .ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier .Contains(XAiModelsConstants.XAiProjectTitleIdentifier.ToNormalString()) &&
.ToNormalString()) &&
x.TranslatedValue x.TranslatedValue
.ToNormalString() .ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix) .Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix.ToNormalString())
); );
if (resource.IsNullOrDefault()) if (resource.IsNullOrDefault())
{ {
@@ -860,6 +1100,193 @@ namespace xAiModels.Providers
} }
#endregion #endregion
//
#region Query ...
/// <summary>
/// Query Projects ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XAiProjectDto>> QueryProjects(
string ownerId,
XQuery query,
CancellationToken cancellationToken = default
)
{
//
Expression<Func<XAiProject, bool>> predicate = null;
if (ownerId.IsNullOrEmpty())
{
predicate = x => x.OwnerId == ownerId;
}
//
var result = await projectRepositoryService.QueryAsync(
query: query,
predicate: predicate,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
orderBuilder: x => x.OrderBy(y => y.CreatedOn)
);
if (!result.IsNullOrDefault() &&
result.Items.HasChild())
{
//
result.Items = [..await EnrichRange(
sources: result.Items,
fillConversations: false,
fillConversationMessages: false,
cancellationToken: cancellationToken
)];
}
//
return result;
}
/// <summary>
/// Query Conversations ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="projectId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XAiConversationDto>> QueryConversations(
string ownerId,
Guid projectId,
XQuery query,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
if (projectId.IsDefaultGuid())
{
XException.InvalidArgs.Throw();
}
//
// Retrieve Project ...
var project = await projectRepositoryService.GetAsync(
id: projectId,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (project.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
Expression<Func<XAiConversation, bool>> predicate = x =>
x.ProjectId == projectId;
if (ownerId.IsNullOrEmpty())
{
//
predicate = x =>
x.OwnerId == ownerId &&
x.ProjectId == projectId;
}
//
var result = await conversationRepositoryService.QueryAsync(
query: query,
predicate: predicate,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
orderBuilder: x => x.OrderBy(y => y.CreatedOn)
);
if (!result.IsNullOrDefault() &&
result.Items.HasChild())
{
//
result.Items = [..await EnrichRange(
fillMessages: false,
sources: result.Items,
cancellationToken: cancellationToken
)];
}
//
return result;
}
/// <summary>
/// Query Messages ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="conversationId"></param>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XAiMessageDto>> QueryMessages(
string ownerId,
Guid conversationId,
XQuery query,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
if (conversationId.IsDefaultGuid())
{
XException.InvalidArgs.Throw();
}
//
// Retrieve Conversation ...
var conversation = await conversationRepositoryService.GetAsync(
id: conversationId,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
if (conversation.IsNullOrDefault())
{
XException.NotFound.Throw();
}
//
Expression<Func<XAiMessage, bool>> predicate = x =>
x.ConversationId == conversationId;
if (ownerId.IsNullOrEmpty())
{
//
predicate = x =>
x.OwnerId == ownerId &&
x.ConversationId == conversationId;
}
//
var result = await messageRepositoryService.QueryAsync(
query: query,
predicate: predicate,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
orderBuilder: x => x.OrderBy(y => y.CreatedOn)
);
if (!result.IsNullOrDefault() &&
result.Items.HasChild())
{
//
result.Items = [..await EnrichRange(
sources: result.Items,
cancellationToken: cancellationToken
)];
}
//
return result;
}
#endregion
// //
#region Enrichers ... #region Enrichers ...
/// <summary> /// <summary>
@@ -1038,14 +1465,14 @@ namespace xAiModels.Providers
.Contains(ownerId.ToNormalString()) && .Contains(ownerId.ToNormalString()) &&
x.ResourceTitle x.ResourceTitle
.ToNormalString() .ToNormalString()
.Contains(XAiModelsConstants.XAiProjectTitleIdentifier .Contains(XAiModelsConstants.XAiProjectTitleIdentifier.ToNormalString()) &&
.ToNormalString()) &&
x.TranslatedValue x.TranslatedValue
.ToNormalString() .ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix) .Contains(XAiDataProviderConstants.XDefaultAiProjectSuffix.ToNormalString())
); );
result = !defaultProjectResource.IsNullOrDefault(); result = !defaultProjectResource.IsNullOrDefault();
//
return result; return result;
} }
@@ -1101,7 +1528,7 @@ namespace xAiModels.Providers
// Prepare Tile and Description Resource Ids ... // Prepare Tile and Description Resource Ids ...
var titleResource = await projectTitleResourceProvider.AddOrUpdateLocale( var titleResource = await projectTitleResourceProvider.AddOrUpdateLocale(
owner: ownerId, owner: ownerId,
identifier: $"{XAiDataProviderConstants.XDefaultAiProjectSuffix}_{item.Id}", identifier: item.Id,
locale: new XLocaleResourceDto locale: new XLocaleResourceDto
{ {
Language = defaultLang, Language = defaultLang,
@@ -1111,7 +1538,7 @@ namespace xAiModels.Providers
); );
var descriptionResource = await projectDescriptionResourceProvider.AddOrUpdateLocale( var descriptionResource = await projectDescriptionResourceProvider.AddOrUpdateLocale(
owner: ownerId, owner: ownerId,
identifier: $"{XAiDataProviderConstants.XDefaultAiProjectSuffix}_{item.Id}", identifier: item.Id,
new XLocaleResourceDto new XLocaleResourceDto
{ {
Language = defaultLang, Language = defaultLang,
@@ -1192,7 +1619,7 @@ namespace xAiModels.Providers
{ {
// //
project = await projectRepositoryService.GetAsync( project = await projectRepositoryService.GetAsync(
id: project.Id, id: projectId,
includeBuilder: null, includeBuilder: null,
ignoreSoftDeleteds: true, ignoreSoftDeleteds: true,
cancellationToken: cancellationToken cancellationToken: cancellationToken
@@ -1210,14 +1637,13 @@ namespace xAiModels.Providers
predicate: x => predicate: x =>
x.ResourceTitle x.ResourceTitle
.ToNormalString() .ToNormalString()
.Contains(projectId.ToString().ToNormalString()) && .Contains(ownerId.ToString().ToNormalString()) &&
x.ResourceTitle x.ResourceTitle
.ToNormalString() .ToNormalString()
.Contains(XAiModelsConstants.XAiConversationTitleIdentifier .Contains(XAiModelsConstants.XAiConversationTitleIdentifier.ToNormalString()) &&
.ToNormalString()) &&
x.TranslatedValue x.TranslatedValue
.ToNormalString() .ToNormalString()
.Contains(XAiDataProviderConstants.XDefaultAiConversationSuffix) .Contains(XAiDataProviderConstants.XDefaultAiConversationSuffix.ToNormalString())
); );
result = !resource.IsNullOrDefault(); result = !resource.IsNullOrDefault();
if (!result) if (!result)
@@ -1226,13 +1652,13 @@ namespace xAiModels.Providers
} }
// //
result = !(await conversationRepositoryService.FindOneAsync( var defaultConversation = await conversationRepositoryService.FindOneAsync(
cancellationToken: cancellationToken, cancellationToken: cancellationToken,
predicate: x => predicate: x =>
x.ProjectId == projectId && x.ProjectId == projectId &&
x.Title == resource.ResourceTitle x.Title == resource.ResourceTitle
)) );
.IsNullOrDefault(); result = !defaultConversation.IsNullOrDefault();
// //
return result; return result;
@@ -1282,7 +1708,7 @@ namespace xAiModels.Providers
{ {
// //
project = await projectRepositoryService.GetAsync( project = await projectRepositoryService.GetAsync(
id: project.Id, id: projectId,
includeBuilder: null, includeBuilder: null,
ignoreSoftDeleteds: true, ignoreSoftDeleteds: true,
cancellationToken: cancellationToken cancellationToken: cancellationToken
@@ -1324,7 +1750,7 @@ namespace xAiModels.Providers
// Prepare Title Resource Ids ... // Prepare Title Resource Ids ...
var titleResource = await conversationTitleResourceProvider.AddOrUpdateLocale( var titleResource = await conversationTitleResourceProvider.AddOrUpdateLocale(
owner: ownerId, owner: ownerId,
identifier: $"{XAiDataProviderConstants.XDefaultAiConversationSuffix}_{item.Id}", identifier: item.Id,
locale: new XLocaleResourceDto locale: new XLocaleResourceDto
{ {
Language = defaultLang, Language = defaultLang,