Files
BeWoPlaner/AICore/Prompt/Factories/AiPromptFactory.cs
2025-09-09 14:57:45 +02:00

203 lines
6.7 KiB
C#

using AICore.Context.Entry;
using AICore.Context.Entry.Navigation;
using AICore.Context.Summary;
using AICore.Context.SummaryMapper;
using AICore.Context.SummaryParser;
using BeWo.ServiceUtils.Core;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Exceptions;
using BS.Shared.Translation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
namespace AICore.Prompt.Factories
{
public class AiPromptFactory
{
public string CreateSystemInstructions(AiContextType uicontext, IEnumerable<IDataContract> bewoobjects, AiDataContextType aiDataContextType)
{
var sb = new StringBuilder();
sb.AppendLine(getCustomSystemPrompt());
sb.AppendLine("### **Allgemein**");
sb.AppendLine($"- Aktuelle Zeit: {DateTime.Now}");
sb.AppendLine();
sb.AppendLine("### **Ansicht**");
sb.AppendLine($"- Ich befinde mich aktuell in der \"{EnumTranslations.Ai2Translation[uicontext]}\" meiner Anwendung.");
sb.AppendLine($"- Es ist kein Filter gesetzt.");
sb.AppendLine();
sb.AppendLine("### **Daten**");
if (bewoobjects is null || bewoobjects.Count() == 0)
{
sb.AppendLine("Dir wurden keine Daten bereitgestellt.");
}
else
{
sb.AppendLine("Du erhälst folgende Daten:");
var parser = GetParser(aiDataContextType);
var parsed = CreateContext(uicontext, bewoobjects, parser);
sb.AppendLine(parsed);
}
return sb.ToString();
}
private BaseContextSummaryParser GetParser(AiDataContextType aiDataContextType)
{
switch (aiDataContextType)
{
case AiDataContextType.json:
return new JsonContextSummaryParser();
case AiDataContextType.csv:
return new CsvContextSummaryParser();
case AiDataContextType.tsv:
return new CsvContextSummaryParser("\t");
case AiDataContextType.csv2:
return new CsvContextSummaryParser(";", true);
case AiDataContextType.tsv2:
return new CsvContextSummaryParser("\t", true);
default:
break;
}
throw BeWoNotImplementedException.CreateFromEnum(aiDataContextType);
}
private string CreateContext(AiContextType uicontext, IEnumerable<IDataContract> bewoobjects, BaseContextSummaryParser parser)
{
var context = GetContext(uicontext, bewoobjects);
var parsed = parser.Parse(uicontext, context);
return parsed;
}
private BaseContextSummary GetContext(AiContextType uicontext, IEnumerable<IDataContract> bewoobjects)
{
switch (uicontext)
{
case AiContextType.SupportConceptNavigation:
return GetNavigationContext<SupportConceptNavigationContextEntry, CompactSupportConceptDC>(bewoobjects);
case AiContextType.CustomerNavigation:
return GetNavigationContext<CustomerNavigationContextEntry, CompactCustomerDC>(bewoobjects);
case AiContextType.PersonNavigation:
return GetNavigationContext<PersonNavigationContextEntry, CompactPersonDC>(bewoobjects);
case AiContextType.EmployeeNavigation:
return GetNavigationContext<EmployeeNavigationContextEntry, CompactEmployeeDC>(bewoobjects);
case AiContextType.OrganisationNavigation:
return GetNavigationContext<OrganisationNavigationContextEntry, CompactOrganisationDC>(bewoobjects);
case AiContextType.ServiceRecord:
return GetServiceRecordsContext(bewoobjects);
case AiContextType.CustomerDetail:
return GetDetailContext<CustomerDetailContextEntry, CustomerDC>(bewoobjects);
case AiContextType.PersonDetail:
return GetDetailContext<PersonDetailContextEntry, PersonDC>(bewoobjects);
case AiContextType.EmployeeDetail:
return GetDetailContext<EmployeeDetailContextEntry, EmployeeDC>(bewoobjects);
default:
throw BeWoNotImplementedException.CreateFromEnum(uicontext);
}
}
private DetailContextSummary<TEntry, TDataContract> GetDetailContext<TEntry, TDataContract>(IEnumerable<IDataContract> bewoobjects)
where TEntry : DetailContextEntry<TDataContract>
where TDataContract : IDataContract, new()
{
var entity = LoadDataContract<TDataContract>(bewoobjects);
var context = ContextSummaryFactory.CreateDetailContext<TEntry, TDataContract>(entity);
return context;
}
private NavigationContextSummary<TEntry, TDataContract> GetNavigationContext<TEntry, TDataContract>(IEnumerable<IDataContract> bewoobjects)
where TEntry : NavigationContextEntry<TDataContract>
where TDataContract : IDataContract, new()
{
var entities = LoadDataContracts<TDataContract>(bewoobjects);
var context = ContextSummaryFactory.CreateNavigationContext<TEntry, TDataContract>(entities);
return context;
}
private ServiceRecordNavigationContextSummary GetServiceRecordsContext(IEnumerable<IDataContract> bewoobjects)
{
var customer = LoadDataContract<CompactCustomerDC>(bewoobjects);
var costbearer = LoadProperty<CompactCostBearerDC, string>(bewoobjects, dc => dc.Organisation.Name);
var supportconcept = LoadProperty<CompactSupportConceptDC, string>(bewoobjects, dc => $"{dc.StartDate?.Date} - {dc.EndDate?.Date}");
var records = LoadDataContracts<ServiceRecordDC>(bewoobjects);
var context = ContextSummaryFactory.CreateServiceRecordNavigationContextSummary(records, customer, costbearer, supportconcept);
return context;
}
private TRet LoadProperty<TDataContract, TRet>
(IEnumerable<IDataContract> bewoobjects, Func<TDataContract, TRet> getPropertyFunc)
where TDataContract : IDataContract, new()
{
if(LoadDataContract<TDataContract>(bewoobjects) is TDataContract dc)
{
return getPropertyFunc(dc);
}
return default;
}
private TDataContract LoadDataContract<TDataContract>
(IEnumerable<IDataContract> bewoobjects)
where TDataContract : IDataContract, new()
{
if(bewoobjects?.FirstOrDefault(x => x is TDataContract) is IDataContract dc)
{
return (TDataContract)dc;
}
return default;
}
private IEnumerable<TDataContract> LoadDataContracts<TDataContract>
(IEnumerable<IDataContract> bewoobjects)
where TDataContract : IDataContract, new()
{
if (bewoobjects?.Where(x => x is TDataContract) is IEnumerable<IDataContract> dcs && dcs.Count() > 0)
{
return dcs.Select(x => (TDataContract)x);
}
return default;
}
private string getSystemPrompt(int i)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = $"AICore.Prompt.SystemPrompts.system_prompt{i}.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
return result;
}
}
private string getCustomSystemPrompt()
{
var path = MergedConfig.GetSetting("AiSystemPromptPath");
return File.ReadAllText(path);
}
}
}