Files
BeWoPlaner/AICore/Prompt/Factories/JsonAiPromptFactory.cs
2025-07-25 14:27:57 +02:00

202 lines
6.0 KiB
C#

using AICore.Context.Entry;
using AICore.Context.Summary;
using AICore.Context.SummaryMapper;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.ServiceUtils.Core;
using BS.Shared;
using BS.Shared.Exceptions;
using BS.Shared.Translation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.Json;
namespace AICore.Prompt.Factories
{
public class JsonAiPromptFactory
{
public string CreateSystemInstructions(AiContextType uicontext, Dictionary<TableID, long[]> bewoobjects)
{
var sb = new StringBuilder();
sb.AppendLine(getCustomSystemPrompt());
sb.AppendLine($"Ich befinde mich aktuell in der \"{Translator.Translate(uicontext)}\" meiner Anwendung.");
sb.AppendLine("Es ist kein Filter gesetzt.");
if (bewoobjects is null || bewoobjects.Count == 0)
{
sb.AppendLine("Dir wurden keine Daten bereitgestellt.");
}
else
{
sb.AppendLine("Du erhälst folgendes:");
var parsed = LoadContext(uicontext, bewoobjects);
sb.AppendLine(parsed);
}
return sb.ToString();
}
private string LoadContext(AiContextType uicontext, Dictionary<TableID, long[]> bewoobjects)
{
var context = GetContext(uicontext, bewoobjects);
var parsed = Parse(uicontext, context);
return parsed;
}
protected virtual string Parse(AiContextType uicontext, BaseContextSummary context)
{
var str = JsonSerializer.Serialize(context);
return str;
}
protected BaseContextSummary GetContext(AiContextType uicontext, Dictionary<TableID, long[]> bewoobjects)
{
switch (uicontext)
{
case AiContextType.SupportConcept:
return GetNavigationContext<SupportConceptNavigationContextEntry, SupportConcept>(bewoobjects);
case AiContextType.Customer:
return GetNavigationContext<CustomerNavigationContextEntry, Customer>(bewoobjects);
case AiContextType.Person:
return GetNavigationContext<PersonNavigationContextEntry, Person>(bewoobjects);
case AiContextType.Employee:
return GetNavigationContext<EmployeeNavigationContextEntry, Employee>(bewoobjects);
case AiContextType.Organisation:
return GetNavigationContext<OrganisationNavigationContextEntry, Organisation>(bewoobjects);
case AiContextType.ServiceRecord:
return GetServiceRecordsContext(bewoobjects);
case AiContextType.CustomerSingle:
return GetDetailContext<CustomerDetailContextEntry, Customer>(bewoobjects);
case AiContextType.PersonSingle:
return GetDetailContext<PersonDetailContextEntry, Person>(bewoobjects);
case AiContextType.EmployeeSingle:
return GetDetailContext<EmployeeDetailContextEntry, Employee>(bewoobjects);
default:
throw BeWoNotImplementedException.CreateFromEnum(uicontext);
}
}
private DetailContextSummary<TEntry, TEntity> GetDetailContext<TEntry, TEntity>(Dictionary<TableID, long[]> bewoobjects)
where TEntry : DetailContextEntry<TEntity>
where TEntity : BeWoEntityBase, new()
{
var entity = LoadEntity<TEntity>(bewoobjects);
var context = ContextSummaryFactory.CreateDetailContext<TEntry, TEntity>(entity);
return context;
}
private NavigationContextSummary<TEntry, TEntity> GetNavigationContext<TEntry, TEntity>(Dictionary<TableID, long[]> bewoobjects)
where TEntry : NavigationContextEntry<TEntity>
where TEntity : BeWoEntityBase, new()
{
var entities = LoadEntities<TEntity>(bewoobjects);
var context = ContextSummaryFactory.CreateNavigationContext<TEntry, TEntity>(entities);
return context;
}
private ServiceRecordNavigationContextSummary GetServiceRecordsContext(Dictionary<TableID, long[]> bewoobjects)
{
var customer = LoadEntity<Customer>(bewoobjects);
var costbearer = LoadProperty<Organisation, string>(bewoobjects, dc => dc.Name);
var supportconcept = LoadProperty<SupportConcept, string>(bewoobjects, dc => $"{dc.StartDate?.Date} - {dc.EndDate?.Date}");
var records = LoadEntities<ServiceRecord>(bewoobjects);
var context = ContextSummaryFactory.CreateServiceRecordNavigationContextSummary(records, customer, costbearer, supportconcept);
return context;
}
private TRet LoadProperty<TEntity, TRet>
(Dictionary<TableID, long[]> bewoobjects, Func<TEntity, TRet> getPropertyFunc)
where TEntity : BeWoEntityBase, new()
{
var tid = GetTableId<TEntity>();
if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0)
return default;
var entity = DAOFactory.GenericDAO.GetByID<TEntity>(oids[0]);
var property = getPropertyFunc(entity);
return property;
}
private TEntity LoadEntity<TEntity>
(Dictionary<TableID, long[]> bewoobjects)
where TEntity : BeWoEntityBase, new()
{
var tid = GetTableId<TEntity>();
if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0)
return null;
var entity = DAOFactory.GenericDAO.GetByID<TEntity>(oids[0]);
return entity;
}
private List<TEntity> LoadEntities<TEntity>
(Dictionary<TableID, long[]> bewoobjects)
where TEntity : BeWoEntityBase, new()
{
var instance = new TEntity();
var tid = GetTableId<TEntity>();
if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0)
return null;
var entities = DAOFactory.GenericDAO.GetByIDs<TEntity>(oids);
//if(afterLoad != null)
//{
// foreach( var entity in entities)
// {
// afterLoad(entity);
// }
//}
return entities;
}
private TableID GetTableId<TEntity>(TEntity entity = null) where TEntity : BeWoEntityBase, new()
{
if (entity == null)
entity = new TEntity();
return entity.Tid;
}
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);
}
}
}