2025-02-18 10:24:43 +00:00
using System.Text ;
2025-02-22 19:51:06 +00:00
using AIStudio.Agents ;
2025-02-18 10:24:43 +00:00
using AIStudio.Chat ;
using AIStudio.Provider ;
2025-02-22 19:51:06 +00:00
using AIStudio.Settings ;
2025-05-04 12:59:30 +00:00
using AIStudio.Tools.PluginSystem ;
2025-02-18 10:24:43 +00:00
namespace AIStudio.Tools.RAG.AugmentationProcesses ;
public sealed class AugmentationOne : IAugmentationProcess
{
2025-09-25 17:47:18 +00:00
private static readonly ILogger < AugmentationOne > LOGGER = Program . LOGGER_FACTORY . CreateLogger < AugmentationOne > ( ) ;
2025-05-04 12:59:30 +00:00
private static string TB ( string fallbackEN ) = > I18N . I . T ( fallbackEN , typeof ( AugmentationOne ) . Namespace , nameof ( AugmentationOne ) ) ;
2025-02-18 10:24:43 +00:00
#region Implementation of IAugmentationProcess
/// <inheritdoc />
public string TechnicalName = > "AugmentationOne" ;
/// <inheritdoc />
2025-05-04 12:59:30 +00:00
public string UIName = > TB ( "Standard augmentation process" ) ;
2025-02-18 10:24:43 +00:00
/// <inheritdoc />
2025-05-04 12:59:30 +00:00
public string Description = > TB ( "This is the standard augmentation process, which uses all retrieval contexts to augment the chat thread." ) ;
2025-02-18 10:24:43 +00:00
/// <inheritdoc />
2025-09-25 17:47:18 +00:00
public async Task < ChatThread > ProcessAsync ( IProvider provider , IContent lastUserPrompt , ChatThread chatThread , IReadOnlyList < IRetrievalContext > retrievalContexts , CancellationToken token = default )
2025-02-18 10:24:43 +00:00
{
2025-02-22 19:51:06 +00:00
var settings = Program . SERVICE_PROVIDER . GetService < SettingsManager > ( ) ! ;
2025-02-18 10:24:43 +00:00
if ( retrievalContexts . Count = = 0 )
{
2025-09-25 17:47:18 +00:00
LOGGER . LogWarning ( "No retrieval contexts were issued. Skipping the augmentation process." ) ;
2025-02-18 10:24:43 +00:00
return chatThread ;
}
2025-02-22 19:51:06 +00:00
2025-02-18 10:24:43 +00:00
var numTotalRetrievalContexts = retrievalContexts . Count ;
2025-02-22 19:51:06 +00:00
// Want the user to validate all retrieval contexts?
2025-02-23 14:05:29 +00:00
if ( settings . ConfigurationData . AgentRetrievalContextValidation . EnableRetrievalContextValidation & & chatThread . DataSourceOptions . AutomaticValidation )
2025-02-22 19:51:06 +00:00
{
// Let's get the validation agent & set up its provider:
var validationAgent = Program . SERVICE_PROVIDER . GetService < AgentRetrievalContextValidation > ( ) ! ;
2026-08-14 10:03:16 +00:00
if ( validationAgent . SetLLMProvider ( provider , chatThread . DataSecurity , chatThread . DataConfidenceLevel ) )
2026-08-05 13:05:17 +00:00
{
2026-08-14 10:03:52 +00:00
try
{
// Let's validate all retrieval contexts:
var validationResults = await validationAgent . ValidateRetrievalContextsAsync ( lastUserPrompt , chatThread , retrievalContexts , token ) ;
if ( validationResults . Count = = 0 )
LOGGER . LogWarning ( "Retrieval context validation returned no results. Continuing augmentation with all retrieved contexts." ) ;
else
{
//
// Now, filter the retrieval contexts to the most relevant ones:
//
var targetWindow = validationResults . DetermineTargetWindow ( TargetWindowStrategy . TOP10_BETTER_THAN_GUESSING ) ;
var threshold = validationResults . GetConfidenceThreshold ( targetWindow ) ;
2026-08-05 13:05:17 +00:00
2026-08-14 10:03:52 +00:00
// Filter the retrieval contexts:
retrievalContexts = validationResults . Where ( x = > x . RetrievalContext is not null & & x . Confidence > = threshold ) . Select ( x = > x . RetrievalContext ! ) . ToList ( ) ;
}
}
catch ( OperationCanceledException ) when ( token . IsCancellationRequested )
{
throw ;
}
catch ( Exception exception )
{
LOGGER . LogError ( exception , "Retrieval context validation failed. Continuing augmentation with all retrieved contexts." ) ;
}
2026-08-05 13:05:17 +00:00
}
else
2026-08-14 10:03:52 +00:00
LOGGER . LogWarning ( "Skipping retrieval context validation because no sufficiently trusted validation agent provider is available. Continuing augmentation with all retrieved contexts." ) ;
2025-02-22 19:51:06 +00:00
}
2026-08-14 10:03:52 +00:00
LOGGER . LogInformation ( $"Starting the augmentation process over {retrievalContexts.Count:###,###,###,###} of {numTotalRetrievalContexts:###,###,###,###} retrieved contexts." ) ;
2025-02-18 10:24:43 +00:00
//
// We build a huge prompt from all retrieval contexts:
//
var sb = new StringBuilder ( ) ;
sb . AppendLine ( "The following useful information will help you in processing the user prompt:" ) ;
sb . AppendLine ( ) ;
2025-02-22 19:51:06 +00:00
// Let's convert all retrieval contexts to Markdown:
await retrievalContexts . AsMarkdown ( sb , token ) ;
2025-02-18 10:24:43 +00:00
2025-03-08 12:56:38 +00:00
// Add the augmented data to the chat thread:
chatThread . AugmentedData = sb . ToString ( ) ;
2025-02-18 10:24:43 +00:00
return chatThread ;
}
#endregion
}