From e286cb4109f39c3b51d8cfeaa3a20fb9f0c2857d Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 25 Jul 2025 14:27:49 +0200 Subject: [PATCH] temp1 --- AICore/AICore.csproj | 90 +++++ .../Context/Core/ContextEntryMapperFactory.cs | 29 ++ AICore/Context/Core/ContextSummaryFactory.cs | 109 ++++++ AICore/Context/Entry/BaseContextEntry.cs | 131 ++++++++ .../EntryMapper/BaseContextEntryMapper.cs | 146 ++++++++ AICore/Context/Summary/BaseContextSummary.cs | 115 +++++++ AICore/Prompt/Core/AiUtils.cs | 16 + .../Prompt/Factories/BaseAiPromptFactory.cs | 306 +++++++++++++++++ .../Prompt/Factories/JsonAiPromptFactory.cs | 10 + AICore/Prompt/Models/AiConversationContext.cs | 19 ++ .../Prompt/SystemPrompts}/system_prompt1.txt | 0 .../Prompt/SystemPrompts}/system_prompt2.txt | 1 - .../Prompt/SystemPrompts}/system_prompt3.txt | 0 AICore/Properties/AssemblyInfo.cs | 33 ++ AICore/app.config | 71 ++++ AICore/packages.config | 42 +++ BeWo/MainControl.xaml.cs | 7 +- BeWo/ViewModel/AiConversationVM.cs | 22 +- .../ListViewModel/AiConversationListVM.cs | 4 +- BeWoAI.sln | 37 ++- Data/Entities/AiConversation.cs | 3 +- Data/Mappings/AiConversation.hbm.xml | 3 +- Host/ResetPassword.aspx.cs | 1 - Host/Web.config | 78 ++++- .../Changes_2025_07_16 AiDataContextType.txt | 3 + Report/app.config | 30 +- ReportService/app.config | 30 +- .../AiConversationDC_AiConversation.cs | 2 + .../CompactCustomerDC_Customer.cs | 16 - .../CompactEmployeeDC_Employee.cs | 12 - .../CompactOrganisationDC_Organisation.cs | 18 - .../DCEntityMapper/CompactPersonDC_Person.cs | 16 - .../CompactSupportConceptDC_SupportConcept.cs | 19 -- .../EmploymentTypeDC_EmploymentType.cs | 1 - .../ServiceRecordDC_ServiceRecord.cs | 25 -- .../Invoicing/SettlementInvoiceCreation.cs | 1 - Service/PivotTabelle/FlexibleReportManager.cs | 1 - Service/Plugins/AiService.cs | 1 - Service/Plugins/AiService2.cs | 35 +- Service/Plugins/FlexibleReportService.cs | 1 - .../Plugins/StundenuebersichtAuswertung.cs | 1 - Service/Plugins/UserService.cs | 2 - Service/Service.csproj | 14 +- .../AiEnhancedServiceImp.cs | 92 +----- Service/ai/AiPromptFactory.cs | 311 ------------------ Service/app.config | 28 ++ ServiceUtils/Core/MergedConfig.cs | 27 ++ ServiceUtils/Properties/AssemblyInfo.cs | 33 ++ ServiceUtils/ServiceUtils.csproj | 50 +++ Shared/BeWoEntityEnums.cs | 29 ++ Shared/Core/EnumTranslations.cs | 62 +++- .../Feature/AI/AiConversationDC.cs | 3 +- .../Exceptions/BeWoNotImplementedException.cs | 36 ++ Shared/Shared.csproj | 1 + 54 files changed, 1594 insertions(+), 579 deletions(-) create mode 100644 AICore/AICore.csproj create mode 100644 AICore/Context/Core/ContextEntryMapperFactory.cs create mode 100644 AICore/Context/Core/ContextSummaryFactory.cs create mode 100644 AICore/Context/Entry/BaseContextEntry.cs create mode 100644 AICore/Context/EntryMapper/BaseContextEntryMapper.cs create mode 100644 AICore/Context/Summary/BaseContextSummary.cs create mode 100644 AICore/Prompt/Core/AiUtils.cs create mode 100644 AICore/Prompt/Factories/BaseAiPromptFactory.cs create mode 100644 AICore/Prompt/Factories/JsonAiPromptFactory.cs create mode 100644 AICore/Prompt/Models/AiConversationContext.cs rename {Service/ai => AICore/Prompt/SystemPrompts}/system_prompt1.txt (100%) rename {Service/ai => AICore/Prompt/SystemPrompts}/system_prompt2.txt (96%) rename {Service/ai => AICore/Prompt/SystemPrompts}/system_prompt3.txt (100%) create mode 100644 AICore/Properties/AssemblyInfo.cs create mode 100644 AICore/app.config create mode 100644 AICore/packages.config delete mode 100644 Service/ai/AiPromptFactory.cs create mode 100644 ServiceUtils/Core/MergedConfig.cs create mode 100644 ServiceUtils/Properties/AssemblyInfo.cs create mode 100644 ServiceUtils/ServiceUtils.csproj create mode 100644 Shared/Exceptions/BeWoNotImplementedException.cs diff --git a/AICore/AICore.csproj b/AICore/AICore.csproj new file mode 100644 index 000000000..55da2ba35 --- /dev/null +++ b/AICore/AICore.csproj @@ -0,0 +1,90 @@ + + + + + Debug + AnyCPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9} + Library + Properties + AICore + BeWo.Features.AICore + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.2\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + + + ..\packages\System.IO.Pipelines.9.0.2\lib\net462\System.IO.Pipelines.dll + + + ..\packages\System.Text.Encodings.Web.9.0.2\lib\net462\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.9.0.2\lib\net462\System.Text.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + + + {B0D73E3D-4AE7-4024-93A6-DB1F46D7CCEE} + Data + + + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57} + ServiceUtils + + + {2f50b83d-a3f0-4ec4-979a-3f9b7e3d8ed4} + Shared + + + + + + + + + \ No newline at end of file diff --git a/AICore/Context/Core/ContextEntryMapperFactory.cs b/AICore/Context/Core/ContextEntryMapperFactory.cs new file mode 100644 index 000000000..5001d03d0 --- /dev/null +++ b/AICore/Context/Core/ContextEntryMapperFactory.cs @@ -0,0 +1,29 @@ +using AICore.Context.Entry; +using AICore.Context.EntryMapper; +using BeWo.Data.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AICore.Context.Core +{ + public static class ContextEntryMapperFactory + { + public static CustomerContextEntryMapper CustomerMapper { get; } = new CustomerContextEntryMapper(); + public static EmployeeContextEntryMapper EmployeeMapper { get; } = new EmployeeContextEntryMapper(); + public static PersonContextEntryMapper PersonMapper { get; } = new PersonContextEntryMapper(); + public static OrganisationContextEntryMapper OrganisationMapper { get; } = new OrganisationContextEntryMapper(); + public static SupportConceptContextEntryMapper SupportConceptMapper { get; } = new SupportConceptContextEntryMapper(); + + public static CustomerNavigationContextEntryMapper CustomerNavigationMapper { get; } = new CustomerNavigationContextEntryMapper(); + public static EmployeeNavigationContextEntryMapper EmployeeNavigationMapper { get; } = new EmployeeNavigationContextEntryMapper(); + public static PersonNavigationContextEntryMapper PersonNavigationMapper { get; } = new PersonNavigationContextEntryMapper(); + public static OrganisationNavigationContextEntryMapper OrganisationNavigationMapper { get; } = new OrganisationNavigationContextEntryMapper(); + public static SupportConceptNavigationContextEntryMapper SupportConceptNavigationMapper { get; } = new SupportConceptNavigationContextEntryMapper(); + + public static ServiceRecordContextEntryMapper ServiceRecordMapper { get; } = new ServiceRecordContextEntryMapper(); + public static BaseContextEntryMapper ServiceRecordCustomerMapper { get; } = new CustomerNavigationContextEntryMapper(); + } +} diff --git a/AICore/Context/Core/ContextSummaryFactory.cs b/AICore/Context/Core/ContextSummaryFactory.cs new file mode 100644 index 000000000..7b6a244df --- /dev/null +++ b/AICore/Context/Core/ContextSummaryFactory.cs @@ -0,0 +1,109 @@ +using AICore.Context.Core; +using AICore.Context.Entry; +using AICore.Context.EntryMapper; +using AICore.Context.Summary; +using BeWo.Data.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AICore.Context.SummaryMapper +{ + public static class ContextSummaryFactory + { + public static CustomerDetailContextSummary CreateCustomerDetailContextSummary(Customer customer) + { + var entry = ContextEntryMapperFactory.CustomerMapper.MapToNewContext(customer); + + return new CustomerDetailContextSummary(entry); + } + + public static EmployeeDetailContextSummary CreateEmployeeDetailContextSummary(Employee employee) + { + var entry = ContextEntryMapperFactory.EmployeeMapper.MapToNewContext(employee); + + return new EmployeeDetailContextSummary(entry); + } + + public static PersonDetailContextSummary CreatePersonDetailContextSummary(Person person) + { + var entry = ContextEntryMapperFactory.PersonMapper.MapToNewContext(person); + + return new PersonDetailContextSummary(entry); + } + + public static OrganisationDetailContextSummary CreateOrganisationDetailContextSummary(Organisation organisation) + { + var entry = ContextEntryMapperFactory.OrganisationMapper.MapToNewContext(organisation); + + return new OrganisationDetailContextSummary(entry); + } + + public static SupportConceptDetailContextSummary CreateSupportConceptDetailContextSummary(SupportConcept supportConcept) + { + var entry = ContextEntryMapperFactory.SupportConceptMapper.MapToNewContext(supportConcept); + + return new SupportConceptDetailContextSummary(entry); + } + + public static CustomerNavigationContextSummary CreateCustomerNavigationContextSummary(IEnumerable customer) + { + var entry = ContextEntryMapperFactory.CustomerNavigationMapper.MapToNewContexts(customer); + + return new CustomerNavigationContextSummary(entry); + } + + public static EmployeeNavigationContextSummary CreateEmployeeNavigationContextSummary(IEnumerable employee) + { + var entry = ContextEntryMapperFactory.EmployeeNavigationMapper.MapToNewContexts(employee); + + return new EmployeeNavigationContextSummary(entry); + } + + public static PersonNavigationContextSummary CreatePersonNavigationContextSummary(IEnumerableperson) + { + var entry = ContextEntryMapperFactory.PersonNavigationMapper.MapToNewContexts(person); + + return new PersonNavigationContextSummary(entry); + } + + public static OrganisationNavigationContextSummary CreateOrganisationNavigationContextSummary(IEnumerableorganisation) + { + var entry = ContextEntryMapperFactory.OrganisationNavigationMapper.MapToNewContexts(organisation); + + return new OrganisationNavigationContextSummary(entry); + } + + public static SupportConceptNavigationContextSummary CreateSupportConceptNavigationContextSummary(IEnumerable supportConcept) + { + var entry = ContextEntryMapperFactory.SupportConceptNavigationMapper.MapToNewContexts(supportConcept); + + return new SupportConceptNavigationContextSummary(entry); + } + + public static ServiceRecordNavigationContextSummary CreateServiceRecordNavigationContextSummary(IEnumerable serviceRecords, Customer customer, string costBearer, string supportConcept) + { + var entries = ContextEntryMapperFactory.ServiceRecordMapper.MapToNewContexts(serviceRecords); + var customer_entry = ContextEntryMapperFactory.ServiceRecordCustomerMapper.MapToNewContext(customer); + + return new ServiceRecordNavigationContextSummary(entries, customer_entry, costBearer, supportConcept); + } + + public class ServiceRecordNavigationContextSummary : NavigationContextSummary + { + public CustomerNavigationContextEntry Customer { get; set; } + public string CostBearer { get; set; } + public string SupportConcept { get; set; } + + public ServiceRecordNavigationContextSummary(IEnumerable serviceRecords, CustomerNavigationContextEntry customer, string costBearer, string supportConcept) + : base(serviceRecords) + { + Customer = customer; + CostBearer = costBearer; + SupportConcept = supportConcept; + } + } + } +} diff --git a/AICore/Context/Entry/BaseContextEntry.cs b/AICore/Context/Entry/BaseContextEntry.cs new file mode 100644 index 000000000..4c45e786a --- /dev/null +++ b/AICore/Context/Entry/BaseContextEntry.cs @@ -0,0 +1,131 @@ +using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace AICore.Context.Entry +{ + public abstract class BaseContextEntry + { + + } + + public abstract class DetailContextEntry : BaseContextEntry + { + + } + + public class CustomerDetailContextEntry : DetailContextEntry + { + + } + + public class EmployeeDetailContextEntry : DetailContextEntry + { + + } + + public class PersonDetailContextEntry : DetailContextEntry + { + + } + + public class OrganisationDetailContextEntry : DetailContextEntry + { + + } + + public class SupportConceptDetailContextEntry : DetailContextEntry + { + + } + + public abstract class NavigationContextEntry : BaseContextEntry + { + + } + + public class CustomerNavigationContextEntry : NavigationContextEntry + { + [JsonPropertyName("Adresse")] + public string AddressString { get; set; } + + [JsonPropertyName("Alias")] + public string CustomerAlias { get; set; } + + [JsonPropertyName("Klient-ID")] + public long CustomerOid { get; set; } + + [JsonPropertyName("Geburtstag")] + public string DateOfBirthString { get; set; } + + [JsonPropertyName("EigenkapitalBeitrag")] + public decimal EquityContribution { get; set; } + + [JsonPropertyName("Name")] + public string EquityConFullNametribution { get; set; } + + [JsonPropertyName("Rechnungsadresse")] + public string InvoiceAddressString { get; set; } + } + public class EmployeeNavigationContextEntry : NavigationContextEntry { + [JsonPropertyName("Mitarbeiter-ID")] + public long EmployeeOid { get; set; } + + [JsonPropertyName("Personalnummer")] + public string PersonnelNumber { get; set; } + + [JsonPropertyName("Name")] + public string FirstNameLastName { get; set; } + } + public class PersonNavigationContextEntry : NavigationContextEntry { + public string AddressString { get; set; } + public DateTime Birthday { get; set; } + public long CustomerOid { get; set; } + public long EmployeeOid { get; set; } + public string FullName { get; set; } + public string Geschlecht { get; set; } + public string Function { get; set; } + } + public class OrganisationNavigationContextEntry : NavigationContextEntry { + public long OrganisationOid { get; set; } + public string Name { get; set; } + public string Name2 { get; set; } + public string DebitorNumber { get; set; } + public string BusinessPartnerId { get; set; } + public string AddressString { get; set; } + public string IKDatenannahmestelle { get; set; } + public string IKKostentrager { get; set; } + public string IKKrankenkasse { get; set; } + } + public class SupportConceptNavigationContextEntry : NavigationContextEntry { + public long SupportConceptOid { get; set; } + public string AddressString { get; set; } + public string AllCostBearerNames { get; set; } + public object CostBearer { get; set; } + public string CostBearerDetailStrings { get; set; } + public long CustomerOid { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + } + + public class ServiceRecordContextEntry : NavigationContextEntry + { + public string ServiceRecordOid { get; set; } + public DateTime Start { get; set; } + public DateTime End { get; set; } + public decimal DurationInStunden { get; set; } + public string CategoryName { get; set; } + public string Name { get; set; } + public string Notice { get; set; } + public decimal DistanceInMeter { get; set; } + public DateTime InsertedOn { get; set; } + public decimal Betrag { get; set; } + public object InsUser { get; set; } + public object Employee { get; set; } + } +} diff --git a/AICore/Context/EntryMapper/BaseContextEntryMapper.cs b/AICore/Context/EntryMapper/BaseContextEntryMapper.cs new file mode 100644 index 000000000..5a2db03af --- /dev/null +++ b/AICore/Context/EntryMapper/BaseContextEntryMapper.cs @@ -0,0 +1,146 @@ +using AICore.Context.Entry; +using BeWo.Data.Entities; +using BS.Shared.DataContracts; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AICore.Context.EntryMapper +{ + public abstract class BaseContextEntryMapper + where TObject : class, new() where TContext : BaseContextEntry, new() + { + public virtual TContext MapToNewContext(TObject pObject) + { + return MergeWithObject(pObject, CreateNewContext()); + } + + public virtual TContext CreateNewContext() + { + return new TContext(); + } + + public virtual IEnumerable MapToNewContexts(IEnumerable pObjects) + { + if(pObjects is null || !pObjects.Any()) + return Enumerable.Empty(); + + return pObjects.Select(MapToNewContext); + } + + public abstract TContext MergeWithObject(TObject pDataContract, TContext pContext); + } + + public class CustomerContextEntryMapper : BaseContextEntryMapper + { + public override CustomerDetailContextEntry MergeWithObject(Customer pObject, CustomerDetailContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class EmployeeContextEntryMapper : BaseContextEntryMapper + { + public override EmployeeDetailContextEntry MergeWithObject(Employee pObject, EmployeeDetailContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class PersonContextEntryMapper : BaseContextEntryMapper + { + public override PersonDetailContextEntry MergeWithObject(Person pObject, PersonDetailContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class OrganisationContextEntryMapper : BaseContextEntryMapper + { + public override OrganisationDetailContextEntry MergeWithObject(Organisation pObject, OrganisationDetailContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class SupportConceptContextEntryMapper : BaseContextEntryMapper + { + public override SupportConceptDetailContextEntry MergeWithObject(SupportConcept pObject, SupportConceptDetailContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class CustomerNavigationContextEntryMapper : BaseContextEntryMapper + { + public override CustomerNavigationContextEntry MergeWithObject(Customer pObject, CustomerNavigationContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class EmployeeNavigationContextEntryMapper : BaseContextEntryMapper + { + public override EmployeeNavigationContextEntry MergeWithObject(Employee pObject, EmployeeNavigationContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class PersonNavigationContextEntryMapper : BaseContextEntryMapper + { + public override PersonNavigationContextEntry MergeWithObject(Person pObject, PersonNavigationContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class OrganisationNavigationContextEntryMapper : BaseContextEntryMapper + { + public override OrganisationNavigationContextEntry MergeWithObject(Organisation pObject, OrganisationNavigationContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class SupportConceptNavigationContextEntryMapper : BaseContextEntryMapper + { + public override SupportConceptNavigationContextEntry MergeWithObject(SupportConcept pObject, SupportConceptNavigationContextEntry pContext) + { + throw new NotImplementedException(); + } + } + + public class ServiceRecordContextEntryMapper : BaseContextEntryMapper + { + public override ServiceRecordContextEntry MergeWithObject(ServiceRecord pObject, ServiceRecordContextEntry pContext) + { + throw new NotImplementedException(); + } + + //public override Dictionary ToJsonDictionary(ServiceRecordDC service_record) + //{ + // var record_dict = new Dictionary + // { + // { "Zeiteintrag-ID", service_record.ServiceRecordOid}, + // { "Startdatum", service_record.Start }, + // { "Enddatum", service_record.End }, + // { "Dauer in Stunden", service_record.DurationInStunden }, + // { "Leistungskategorie", service_record.ServiceDescription.Category.Name }, + // { "Leistungsbeschreibung", service_record.ServiceDescription.Name }, + // { "Dokumentation", service_record.Notice + // + "\n" + service_record.Notice2 + // + "\n" + service_record.Notice3 + // + "\n" + service_record.Notice4 + // + "\n" + service_record.Notice5}, + // { "Distanze in Meter", service_record.DistanceInMeter ?? 0 }, + // { "Eingetragen am", service_record.InsertedOn }, + // { "Betrag", service_record.Betrag }, + // { "Eingetragen von", service_record.InsUser }, + // { "Mitarbeiter", service_record.Employee } + // }; + + // return record_dict; + //} + } +} diff --git a/AICore/Context/Summary/BaseContextSummary.cs b/AICore/Context/Summary/BaseContextSummary.cs new file mode 100644 index 000000000..571462568 --- /dev/null +++ b/AICore/Context/Summary/BaseContextSummary.cs @@ -0,0 +1,115 @@ +using AICore.Context.Entry; +using AICore.Context.EntryMapper; +using BeWo.Data.Entities; +using BS.Shared; +using BS.Shared.DataContracts; +using BS.Shared.DataContracts.Compact; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AICore.Context.Summary +{ + public abstract class BaseContextSummary + { + + } + + public abstract class DetailContext : BaseContextSummary where T : DetailContextEntry + { + public T DataContext { get; set; } + + protected DetailContext(T dataContext) + { + DataContext = dataContext; + } + } + + public abstract class NavigationContextSummary : BaseContextSummary where T : NavigationContextEntry + { + public IEnumerable DataContext { get; set; } + + protected NavigationContextSummary(IEnumerable dataContext) + { + DataContext = dataContext; + } + } + + public class CustomerDetailContextSummary : DetailContext + { + public CustomerDetailContextSummary(CustomerDetailContextEntry customer) : base(customer) { } + } + + public class EmployeeDetailContextSummary : DetailContext + { + public EmployeeDetailContextSummary(EmployeeDetailContextEntry employee) : base(employee) { } + } + + public class PersonDetailContextSummary : DetailContext + { + public PersonDetailContextSummary(PersonDetailContextEntry person) : base(person) { } + } + + public class OrganisationDetailContextSummary : DetailContext + { + public OrganisationDetailContextSummary(OrganisationDetailContextEntry organisation) : base(organisation) { } + } + + public class SupportConceptDetailContextSummary : DetailContext + { + public SupportConceptDetailContextSummary(SupportConceptDetailContextEntry supportConcept) : base(supportConcept) { } + } + + public class CustomerNavigationContextSummary : NavigationContextSummary + { + public CustomerNavigationContextSummary(IEnumerable customers) : base(customers) { } + } + public class EmployeeNavigationContextSummary : NavigationContextSummary + { + public EmployeeNavigationContextSummary(IEnumerable employee) : base(employee) { } + } + public class PersonNavigationContextSummary : NavigationContextSummary + { + public PersonNavigationContextSummary(IEnumerable person) : base(person) { } + } + public class OrganisationNavigationContextSummary : NavigationContextSummary + { + public OrganisationNavigationContextSummary(IEnumerable organisation) : base(organisation) { } + } + public class SupportConceptNavigationContextSummary : NavigationContextSummary + { + public SupportConceptNavigationContextSummary(IEnumerable supportConcept) : base(supportConcept) { } + } + + public class ServiceRecordNavigationContextSummary : NavigationContextSummary + { + public CustomerNavigationContextEntry Customer { get; set; } + public string CostBearer { get; set; } + public string SupportConcept { get; set; } + + public ServiceRecordNavigationContextSummary(List serviceRecords, CustomerNavigationContextEntry customer, string costBearer, string supportConcept) + : base(serviceRecords) + { + Customer = customer; + CostBearer = costBearer; + SupportConcept = supportConcept; + } + + //var customer = LoadEntity(bewoobjects, TableID.Customer, MapperFactory.CompactCustomerDC_Customer); + //var costbearer = LoadProperty(bewoobjects, TableID.CostBearer, MapperFactory.CompactOrganisationDC_Organisation, dc => dc.Name); + //var supportconcept = LoadProperty(bewoobjects, TableID.SupportConcept, MapperFactory.CompactSupportConceptDC_SupportConcept, dc => $"{dc.StartDate?.Date} - {dc.EndDate?.Date}"); + //var records = LoadEntities(bewoobjects, TableID.ServiceRecord, MapperFactory.ServiceRecordDC_ServiceRecord); + + //var result = new Dictionary + // { + // { TableID.ServiceRecord, records }, + // { TableID.Customer, customer }, + // { TableID.CostBearer, costbearer }, + // { TableID.SupportConcept, supportconcept } + // }; + + // return result; + } +} diff --git a/AICore/Prompt/Core/AiUtils.cs b/AICore/Prompt/Core/AiUtils.cs new file mode 100644 index 000000000..ab6241a8e --- /dev/null +++ b/AICore/Prompt/Core/AiUtils.cs @@ -0,0 +1,16 @@ +using BS.Shared; +using BS.Shared.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AICore.Prompt.Core +{ + public static class AiUtils + { + + + } +} diff --git a/AICore/Prompt/Factories/BaseAiPromptFactory.cs b/AICore/Prompt/Factories/BaseAiPromptFactory.cs new file mode 100644 index 000000000..55358a7c0 --- /dev/null +++ b/AICore/Prompt/Factories/BaseAiPromptFactory.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +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; + +namespace AICore.Prompt.Factories +{ + public abstract class BaseAiPromptFactory + { + public string CreateSystemInstructions(AiContextType uicontext, Dictionary 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 bewoobjects) + { + var context = GetContext(uicontext, bewoobjects); + + var parsed = Parse(uicontext, null); + + return parsed; + } + + protected virtual string Parse(AiContextType uicontext, Dictionary data) + { + throw new NotImplementedException(); + } + + protected BaseContextSummary GetContext(AiContextType uicontext, Dictionary bewoobjects) + { + switch (uicontext) + { + case AiContextType.SupportConcept: + case AiContextType.Customer: + case AiContextType.Person: + case AiContextType.Employee: + case AiContextType.Organisation: + return GetNavigationContext(uicontext, bewoobjects); + case AiContextType.ServiceRecord: + return GetServiceRecordsContext(bewoobjects); + case AiContextType.CustomerSingle: + case AiContextType.PersonSingle: + case AiContextType.EmployeeSingle: + return GetSingleContext(uicontext, bewoobjects); + default: + break; + } + + throw BeWoNotImplementedException.CreateFromEnum(uicontext); + } + + private BaseContextSummary GetNavigationContext(AiContextType uicontext, Dictionary bewoobjects) + { + switch (uicontext) + { + case AiContextType.SupportConcept: + + return new SupportConceptNavigationContextSummary(LoadEntities(bewoobjects, TableID.SupportConcept)); + case AiContextType.Customer: + return new CustomerNavigationContextSummary(LoadEntities(bewoobjects, TableID.Customer)); + case AiContextType.Person: + return new PersonNavigationContextSummary(LoadEntities(bewoobjects, TableID.Person)); + case AiContextType.Employee: + return new EmployeeNavigationContextSummary(LoadEntities(bewoobjects, TableID.Employee)); + case AiContextType.Organisation: + return new OrganisationNavigationContextSummary(LoadEntities(bewoobjects, TableID.Organisation)); + } + + throw BeWoNotImplementedException.CreateFromEnum(uicontext); + } + + private BaseContextSummary GetServiceRecordsContext(Dictionary bewoobjects) + { + + + var context = new ServiceRecordNavigationContext() + } + + private BaseContextSummary GetSingleContext(AiContextType uicontext, Dictionary bewoobjects) + { + switch (uicontext) + { + case AiContextType.CustomerSingle: + return new CustomerDetailContextSummary(LoadEntity(bewoobjects, TableID.Customer)); + case AiContextType.PersonSingle: + return new PersonDetailContextSummary(LoadEntity(bewoobjects, TableID.Person)); + case AiContextType.EmployeeSingle: + return new EmployeeDetailContextSummary(LoadEntity(bewoobjects, TableID.Employee)); + default: + break; + } + + throw BeWoNotImplementedException.CreateFromEnum(uicontext); + } + + public Dictionary LoadContext(int uicontext, Dictionary bewoobjects) + { + var result = new Dictionary(); + + switch (uicontext) + { + case 0: return LoadNavigationContext(TableID.SupportConcept, bewoobjects); + case 1: return LoadNavigationContext(TableID.Customer, bewoobjects); + case 2: return LoadNavigationContext(TableID.Person, bewoobjects); + case 3: return LoadNavigationContext(TableID.Employee, bewoobjects); + case 4: return LoadNavigationContext(TableID.Organisation, bewoobjects); + //case 5: return "Team Navigation"; + //case 6: return "Dokumente Navigation"; + //case 7: return "Benutzer Navigation"; + //case 8: return "Benutzergruppe Navigation"; + //case 9: return "Bericht Navigation"; + //case 10: return "Planer Navigation"; + //case 11: return "Wohnheim Navigation"; + //case 12: return "Vertretungen Navigation"; + //case 13: return "Kunden-Team Navigation"; + //case 14: return "Terminplanung Navigation"; + //case 15: return "Finanz Navigation"; + //case 16: return "Verwaltung Navigation"; + //case 17: return "KI-Gesprächs Navigation"; + //case 18: return "KI-Gesprächs Popup Navigation"; + case 19: return LoadServiceRecordsContext(bewoobjects); + case 20: return LoadSingleContext(TableID.Customer, bewoobjects); + //case 21: return "Person Einzelansicht Navigation"; + //case 22: return "Mitarbeiter Einzelansicht Navigation"; + default: + throw new NotImplementedException($"UI Kontext {uicontext} ist nicht implementiert."); + //Alternativ könnte man auch einen Standard-String zurückgeben, + //z.B. return "Unbekannter UI-Kontext"; + } + } + + private Dictionary LoadNavigationContext(TableID tableid, Dictionary bewoobjects) + { + IList> entities; + + switch (tableid) + { + case TableID.Person: + entities = LoadEntities(bewoobjects, tableid, MapperFactory.CompactPersonDC_Person); + break; + case TableID.Customer: + entities = LoadEntities(bewoobjects, tableid, MapperFactory.CompactCustomerDC_Customer); + break; + case TableID.Employee: + entities = LoadEntities(bewoobjects, tableid, MapperFactory.CompactEmployeeDC_Employee); + break; + case TableID.SupportConcept: + entities = LoadEntities(bewoobjects, tableid, MapperFactory.CompactSupportConceptDC_SupportConcept); + break; + case TableID.Organisation: + entities = LoadEntities(bewoobjects, tableid, MapperFactory.CompactOrganisationDC_Organisation, (entity, dc) => + { + if (entity.Address != null) + { + dc.AddressLine1 = entity.Address.AddressLine1; + dc.Street = entity.Address.Street; + dc.PostalCode = entity.Address.PostalCode; + dc.Town = entity.Address.Town; + } + }); + break; + default: + throw new NotImplementedException($"TableID {tableid} not implemented as navigation context"); + } + + var result = new Dictionary>> + { + { tableid, entities.ToList() } + }; + + return result; + } + + private Dictionary LoadSingleContext(TableID tableid, Dictionary bewoobjects) + { + var result = new Dictionary>(); + + Dictionary entity; + + switch (tableid) + { + case TableID.Person: + entity = LoadEntity(bewoobjects, tableid, MapperFactory.PersonDC_Person); + break; + case TableID.Customer: + entity = LoadEntity(bewoobjects, tableid, MapperFactory.CustomerDC_Customer); + break; + case TableID.Employee: + entity = LoadEntity(bewoobjects, tableid, MapperFactory.EmployeeDC_Employee); + break; + case TableID.SupportConcept: + entity = LoadEntity(bewoobjects, tableid, MapperFactory.SupportConceptDC_SupportConcept); + break; + //case TableID.Organisation: + // entity = LoadEntity(bewoobjects, tableid, MapperFactory.OrganisationDC_OrganisationMapper, (entity, dc) => + // { + // if (entity.Address != null) + // { + // dc.AddressLine1 = entity.Address.AddressLine1; + // dc.Street = entity.Address.Street; + // dc.PostalCode = entity.Address.PostalCode; + // dc.Town = entity.Address.Town; + // } + // }); + // break; + default: + throw new NotImplementedException($"TableID {tableid} not implemented as navigation context"); + } + + return result; + } + + private TRet LoadProperty + (Dictionary bewoobjects, TableID tid, Func getPropertyFunc) + where TEntity : BeWoEntityBase, new() + { + if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0) + return default; + + var entity = DAOFactory.GenericDAO.GetByID(oids[0]); + var property = getPropertyFunc(entity); + + return property; + } + + private TEntity LoadEntity + (Dictionary bewoobjects, TableID tid) + where TEntity : BeWoEntityBase, new() + { + if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0) + return null; + + var entity = DAOFactory.GenericDAO.GetByID(oids[0]); + + return entity; + } + + private List LoadEntities + (Dictionary bewoobjects, TableID tid) + where TEntity : BeWoEntityBase, new() + { + if (!bewoobjects.TryGetValue(tid, out long[] oids) || (oids?.Length ?? 0) == 0) + return null; + + var entities = DAOFactory.GenericDAO.GetByIDs(oids); + + //if(afterLoad != null) + //{ + // foreach( var entity in entities) + // { + // afterLoad(entity); + // } + //} + + return entities; + } + + 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); + } + } +} diff --git a/AICore/Prompt/Factories/JsonAiPromptFactory.cs b/AICore/Prompt/Factories/JsonAiPromptFactory.cs new file mode 100644 index 000000000..f4f82ab9f --- /dev/null +++ b/AICore/Prompt/Factories/JsonAiPromptFactory.cs @@ -0,0 +1,10 @@ +namespace AICore.Prompt.Factories +{ + public class JsonAiPromptFactory : BaseAiPromptFactory + { + //protected override string Parse(int uicontext, object data) + //{ + + //} + } +} diff --git a/AICore/Prompt/Models/AiConversationContext.cs b/AICore/Prompt/Models/AiConversationContext.cs new file mode 100644 index 000000000..54638ee97 --- /dev/null +++ b/AICore/Prompt/Models/AiConversationContext.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AICore.Prompt.Models +{ + public class AiConversationContext + { + public string Name { get; set; } + public Dictionary Filter { get; set; } + + public AiConversationContext() + { + + } + } +} diff --git a/Service/ai/system_prompt1.txt b/AICore/Prompt/SystemPrompts/system_prompt1.txt similarity index 100% rename from Service/ai/system_prompt1.txt rename to AICore/Prompt/SystemPrompts/system_prompt1.txt diff --git a/Service/ai/system_prompt2.txt b/AICore/Prompt/SystemPrompts/system_prompt2.txt similarity index 96% rename from Service/ai/system_prompt2.txt rename to AICore/Prompt/SystemPrompts/system_prompt2.txt index fc207704d..c5b9b74b4 100644 --- a/Service/ai/system_prompt2.txt +++ b/AICore/Prompt/SystemPrompts/system_prompt2.txt @@ -10,4 +10,3 @@ WICHTIG: --- ### **Daten** -Du erhälst folgendes: diff --git a/Service/ai/system_prompt3.txt b/AICore/Prompt/SystemPrompts/system_prompt3.txt similarity index 100% rename from Service/ai/system_prompt3.txt rename to AICore/Prompt/SystemPrompts/system_prompt3.txt diff --git a/AICore/Properties/AssemblyInfo.cs b/AICore/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..5c6bf3ef8 --- /dev/null +++ b/AICore/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("AICore")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AICore")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly +// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("69d70ca9-0df9-419e-bfaf-f4539f129bd9")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AICore/app.config b/AICore/app.config new file mode 100644 index 000000000..24b437281 --- /dev/null +++ b/AICore/app.config @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AICore/packages.config b/AICore/packages.config new file mode 100644 index 000000000..af8ab101b --- /dev/null +++ b/AICore/packages.config @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BeWo/MainControl.xaml.cs b/BeWo/MainControl.xaml.cs index 8434fb235..01ebaf940 100644 --- a/BeWo/MainControl.xaml.cs +++ b/BeWo/MainControl.xaml.cs @@ -61,12 +61,7 @@ namespace BeWo Finance = 15, Administration = 16, AiConversation = 17, - AiConversationPopup = 18, - // Nur für AI Conversation Zuweisung - ServiceRecord = 19, - CustomerSingle = 20, - PersonSingle = 21, - EmployeeSingle = 22, + AiConversationPopup = 18 } public partial class MainControl diff --git a/BeWo/ViewModel/AiConversationVM.cs b/BeWo/ViewModel/AiConversationVM.cs index e8dc0288d..786329e70 100644 --- a/BeWo/ViewModel/AiConversationVM.cs +++ b/BeWo/ViewModel/AiConversationVM.cs @@ -37,31 +37,14 @@ namespace BeWo.ViewModel public string Displayname { get { return _Displayname; } - set - { - if (!AreDifferent(_Displayname, value)) - return; - - _Displayname = value; - StoreDirtyInformation(AreDifferent(DataContract.Displayname, value), nameof(Displayname)); - FirePropertyChanged(nameof(Displayname)); - FirePropertyChanged(nameof(Json)); - } + set => SetProperty(ref _Displayname, value, nameof(Displayname), () => DataContract.Displayname); } [JsonProperty] public DateTime Updated { get { return _Updated; } - set - { - if (!AreDifferent(Updated, value)) - return; - - _Updated = value; - StoreDirtyInformation(AreDifferent(DataContract.Updated, value), nameof(Updated)); - FirePropertyChanged(nameof(Updated)); - } + set => SetProperty(ref _Updated, value, nameof(Updated), () => DataContract.Updated); } public AiConversationMessageListVM Messages @@ -90,6 +73,7 @@ namespace BeWo.ViewModel public AiModelDC Modell => DataContract.Modell; public string Context => DataContract.Context; public Dictionary ContextBeWoObjects => DataContract.ContextBeWoObjects; + public AiDataContextType Context_Type => DataContract.ContextType; public UIContext UIContext => (UIContext)DataContract.UIContext; protected override void InitByDataContract(AiConversationDC pDataContract) diff --git a/BeWo/ViewModel/ListViewModel/AiConversationListVM.cs b/BeWo/ViewModel/ListViewModel/AiConversationListVM.cs index 343191ccc..c7d52f542 100644 --- a/BeWo/ViewModel/ListViewModel/AiConversationListVM.cs +++ b/BeWo/ViewModel/ListViewModel/AiConversationListVM.cs @@ -91,7 +91,7 @@ namespace BeWo.ViewModel.ListViewModel Displayname = "Displayname Megamegalange Deluxe Op 3000", Messages = messages_dc, Modell = model, - UIContext = 19, + UIContext = AiContextType.ServiceRecord, Updated = DateTime.Now, }; @@ -117,7 +117,7 @@ namespace BeWo.ViewModel.ListViewModel Created = DateTime.Now, Displayname = "Dummy Num " + i.ToString(), Modell = model, - UIContext = 19, + UIContext = AiContextType.ServiceRecord, Updated = DateTime.Now, }; diff --git a/BeWoAI.sln b/BeWoAI.sln index f9a4282df..f52112b4d 100644 --- a/BeWoAI.sln +++ b/BeWoAI.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.33927.289 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 d17.12 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{E7543C39-A44C-40C9-82C9-E7FAA2D9A852}" EndProject @@ -43,6 +43,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Translation", "Translation" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TranslationUnitTest", "TranslationUnitTest\TranslationUnitTest.csproj", "{83C43FEC-233D-49EF-BD23-BF842A3EBDF5}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Features", "Features", "{830D2912-108B-4946-A3BE-CE4ECD50819F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AICore", "AICore\AICore.csproj", "{69D70CA9-0DF9-419E-BFAF-F4539F129BD9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceUtils", "ServiceUtils\ServiceUtils.csproj", "{EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|.NET = Debug|.NET @@ -189,6 +195,30 @@ Global {83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Any CPU.Build.0 = Release|Any CPU {83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {83C43FEC-233D-49EF-BD23-BF842A3EBDF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|.NET.ActiveCfg = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|.NET.Build.0 = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|.NET.ActiveCfg = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|.NET.Build.0 = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Any CPU.Build.0 = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|.NET.ActiveCfg = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|.NET.Build.0 = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|.NET.ActiveCfg = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|.NET.Build.0 = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Any CPU.Build.0 = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57}.Release|Mixed Platforms.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -207,6 +237,9 @@ Global {7630915F-DFE4-45A4-A7B1-B6D19B0126C1} = {2F7893AD-34FC-40A2-838A-3D2D8596E9AC} {B331128C-7E9F-4BDC-B509-A8DAE1B94E5C} = {CCD6B644-49E7-4A11-BD8F-607088A4AC83} {83C43FEC-233D-49EF-BD23-BF842A3EBDF5} = {B331128C-7E9F-4BDC-B509-A8DAE1B94E5C} + {830D2912-108B-4946-A3BE-CE4ECD50819F} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A} + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9} = {830D2912-108B-4946-A3BE-CE4ECD50819F} + {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5352BE53-F2FD-442F-85A8-4157599AA153} diff --git a/Data/Entities/AiConversation.cs b/Data/Entities/AiConversation.cs index 5a0e63a3b..93a974a6a 100644 --- a/Data/Entities/AiConversation.cs +++ b/Data/Entities/AiConversation.cs @@ -23,7 +23,8 @@ namespace BeWo.Data.Entities public virtual string Context { get; set; } public virtual long? ApplicationUserOid { get; set; } public virtual IList ContextBeWoObjects { get; set; } - public virtual int UIContext { get; set; } + public virtual AiContextType UIContext { get; set; } + public virtual AiDataContextType ContextType { get; set; } public virtual IList Messages { get; set; } } } diff --git a/Data/Mappings/AiConversation.hbm.xml b/Data/Mappings/AiConversation.hbm.xml index e541b4f98..3451a3930 100644 --- a/Data/Mappings/AiConversation.hbm.xml +++ b/Data/Mappings/AiConversation.hbm.xml @@ -17,8 +17,9 @@ - + + - + @@ -307,11 +307,11 @@ - - - - - + + + + + @@ -328,12 +328,76 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Model/Changes_2025_07_16 AiDataContextType.txt b/Model/Changes_2025_07_16 AiDataContextType.txt index 88ab6c891..355847607 100644 --- a/Model/Changes_2025_07_16 AiDataContextType.txt +++ b/Model/Changes_2025_07_16 AiDataContextType.txt @@ -1,2 +1,5 @@ ALTER TABLE `aiconfig` ADD COLUMN `Context_Type` INT NOT NULL DEFAULT 0 AFTER `Max_Gen_Len`; + +ALTER TABLE `aiconversation` +ADD COLUMN `ContextType` INT NOT NULL DEFAULT 0 AFTER `Model`; diff --git a/Report/app.config b/Report/app.config index 51edee2cc..912ada03c 100644 --- a/Report/app.config +++ b/Report/app.config @@ -12,7 +12,7 @@ - + @@ -58,6 +58,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ReportService/app.config b/ReportService/app.config index 51edee2cc..912ada03c 100644 --- a/ReportService/app.config +++ b/ReportService/app.config @@ -12,7 +12,7 @@ - + @@ -58,6 +58,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Service/DCEntityMapper/AiConversationDC_AiConversation.cs b/Service/DCEntityMapper/AiConversationDC_AiConversation.cs index 306002822..cca18136d 100644 --- a/Service/DCEntityMapper/AiConversationDC_AiConversation.cs +++ b/Service/DCEntityMapper/AiConversationDC_AiConversation.cs @@ -26,6 +26,7 @@ namespace BeWo.Service.DCEntityMapper pDataContract.Context = pEntity.Context; pDataContract.ContextBeWoObjects = Parse(pEntity.ContextBeWoObjects); pDataContract.UIContext = pEntity.UIContext; + pDataContract.ContextType = pEntity.ContextType; if (pEntity.Messages is IList list && list.Any()) pDataContract.Messages = MapperFactory.AiConversationMessage.MapToNewDCs(list); @@ -51,6 +52,7 @@ namespace BeWo.Service.DCEntityMapper pEntity.Context = pDataContract.Context; pEntity.UIContext = pDataContract.UIContext; pEntity.ContextBeWoObjects = Parse(pDataContract.ContextBeWoObjects); + pEntity.ContextType = pDataContract.ContextType; MapperFactory.AiConversationMessage.MergeWithEntitys(pDataContract.Messages, pEntity.Messages); diff --git a/Service/DCEntityMapper/CompactCustomerDC_Customer.cs b/Service/DCEntityMapper/CompactCustomerDC_Customer.cs index 16936e0ea..91bdefa3e 100644 --- a/Service/DCEntityMapper/CompactCustomerDC_Customer.cs +++ b/Service/DCEntityMapper/CompactCustomerDC_Customer.cs @@ -68,21 +68,5 @@ namespace BeWo.Service.DCEntityMapper { return pDC.CustomerOid == pEntity.Oid; } - - public override Dictionary ToJsonDictionary(CompactCustomerDC customer) - { - var record_dict = new Dictionary - { - {"Adresse", customer.AddressString}, - {"Alias", customer.CustomerAlias}, - {"Klient-ID", customer.CustomerOid}, - {"Geburtstag", customer.DateOfBirthString}, - {"EigenkapitalBeitrag", customer.EquityContribution}, - {"Name", customer.FullName}, - {"Rechnungsadresse", customer.InvoiceAddressString} - }; - - return record_dict; - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/CompactEmployeeDC_Employee.cs b/Service/DCEntityMapper/CompactEmployeeDC_Employee.cs index 35f30bcce..893b4ad94 100644 --- a/Service/DCEntityMapper/CompactEmployeeDC_Employee.cs +++ b/Service/DCEntityMapper/CompactEmployeeDC_Employee.cs @@ -35,17 +35,5 @@ namespace BeWo.Service.DCEntityMapper { return pDC.EmployeeOid == pEntity.Oid; } - - public override Dictionary ToJsonDictionary(CompactEmployeeDC pDC) - { - var dict = new Dictionary() - { - {"Mitarbeiter-ID", pDC.EmployeeOid }, - {"Personalnummer", pDC.PersonnelNumber }, - {"Name", pDC.FirstNameLastName }, - }; - - return dict; - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/CompactOrganisationDC_Organisation.cs b/Service/DCEntityMapper/CompactOrganisationDC_Organisation.cs index cfcd3da84..98629fb5d 100644 --- a/Service/DCEntityMapper/CompactOrganisationDC_Organisation.cs +++ b/Service/DCEntityMapper/CompactOrganisationDC_Organisation.cs @@ -63,23 +63,5 @@ namespace BeWo.Service.DCEntityMapper // dc.CostRatePeriods = new List(); // return dc; //} - - public override Dictionary ToJsonDictionary(CompactOrganisationDC pDC) - { - var jsonObject = new Dictionary() - { - {"Organisation-ID", pDC.OrganisationOid }, - {"Name", pDC.Name }, - {"Abteilung", pDC.Name2 }, - {"Kundennummer", pDC.DebitorNumber }, - {"Geschäftspartnernummer", pDC.BusinessPartnerId }, - {"Adress", pDC.AddressString }, - {"IKDatenannahmestelle", pDC.IKDatenannahmestelle }, - {"IKKostentrager", pDC.IKKostentrager }, - {"IKKrankenkasse", pDC.IKKrankenkasse}, - }; - - return jsonObject; - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/CompactPersonDC_Person.cs b/Service/DCEntityMapper/CompactPersonDC_Person.cs index 50c786c70..922806da4 100644 --- a/Service/DCEntityMapper/CompactPersonDC_Person.cs +++ b/Service/DCEntityMapper/CompactPersonDC_Person.cs @@ -60,21 +60,5 @@ namespace BeWo.Service.DCEntityMapper { return pDC.PersonOid == pEntity.Oid; } - - public override Dictionary ToJsonDictionary(CompactPersonDC pDC) - { - var jsonObject = new Dictionary() - { - {"Adresse", pDC.AddressString }, - {"Geburtstag", pDC.Birthday }, - {"Klient-ID", pDC.CustomerOid }, - {"Mitarbeiter-ID", pDC.EmployeeOid }, - {"Name", pDC.FullName }, - {"Geschlecht", pDC.Geschlecht.ToString() }, - {"Funktion", pDC.Function }, - }; - - return jsonObject; - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/CompactSupportConceptDC_SupportConcept.cs b/Service/DCEntityMapper/CompactSupportConceptDC_SupportConcept.cs index 3221b1343..88d6ebe5a 100644 --- a/Service/DCEntityMapper/CompactSupportConceptDC_SupportConcept.cs +++ b/Service/DCEntityMapper/CompactSupportConceptDC_SupportConcept.cs @@ -69,24 +69,5 @@ namespace BeWo.Service.DCEntityMapper { return pDC.SupportConceptOid == pEntity.Oid; } - - public override Dictionary ToJsonDictionary(CompactSupportConceptDC pDC) - { - var customer = MapperFactory.CompactCustomerDC_Customer.ToJsonDictionary(pDC.Customer); - - var jsonObject = new Dictionary() - { - {"Hilfeplan-ID", pDC.SupportConceptOid }, - {"Adresse", pDC.AddressString }, - {"Kostentraegernamen", pDC.AllCostBearerNames}, - {"Kostentraeger", pDC.CostBearer }, - {"Kostentraeger Details", pDC.CostBearerDetailStrings }, - {"Klient", customer }, - {"Startdatum", pDC.StartDate }, - {"Enddatum", pDC.EndDate } - }; - - return jsonObject; - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/EmploymentTypeDC_EmploymentType.cs b/Service/DCEntityMapper/EmploymentTypeDC_EmploymentType.cs index 3b1ceea60..815e8af05 100644 --- a/Service/DCEntityMapper/EmploymentTypeDC_EmploymentType.cs +++ b/Service/DCEntityMapper/EmploymentTypeDC_EmploymentType.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using BeWo.Data.Entities; -using BeWo.Service.Core; using BS.Shared.DataContracts; diff --git a/Service/DCEntityMapper/ServiceRecordDC_ServiceRecord.cs b/Service/DCEntityMapper/ServiceRecordDC_ServiceRecord.cs index b5a56db2c..cf652b5ce 100644 --- a/Service/DCEntityMapper/ServiceRecordDC_ServiceRecord.cs +++ b/Service/DCEntityMapper/ServiceRecordDC_ServiceRecord.cs @@ -266,30 +266,5 @@ namespace BeWo.Service.DCEntityMapper return pDC.ServiceRecordOid == pEntity.Oid; } - - public override Dictionary ToJsonDictionary(ServiceRecordDC service_record) - { - var record_dict = new Dictionary - { - { "Zeiteintrag-ID", service_record.ServiceRecordOid}, - { "Startdatum", service_record.Start }, - { "Enddatum", service_record.End }, - { "Dauer in Stunden", service_record.DurationInStunden }, - { "Leistungskategorie", service_record.ServiceDescription.Category.Name }, - { "Leistungsbeschreibung", service_record.ServiceDescription.Name }, - { "Dokumentation", service_record.Notice - + "\n" + service_record.Notice2 - + "\n" + service_record.Notice3 - + "\n" + service_record.Notice4 - + "\n" + service_record.Notice5}, - { "Distanze in Meter", service_record.DistanceInMeter ?? 0 }, - { "Eingetragen am", service_record.InsertedOn }, - { "Betrag", service_record.Betrag }, - { "Eingetragen von", service_record.InsUser }, - { "Mitarbeiter", service_record.Employee } - }; - - return record_dict; - } } } \ No newline at end of file diff --git a/Service/Invoicing/SettlementInvoiceCreation.cs b/Service/Invoicing/SettlementInvoiceCreation.cs index 6db68d65f..f2b07f6ea 100644 --- a/Service/Invoicing/SettlementInvoiceCreation.cs +++ b/Service/Invoicing/SettlementInvoiceCreation.cs @@ -12,7 +12,6 @@ using BS.Shared.Services; using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; namespace BeWo.Service.Invoicing diff --git a/Service/PivotTabelle/FlexibleReportManager.cs b/Service/PivotTabelle/FlexibleReportManager.cs index ba52d6daf..38f68d094 100644 --- a/Service/PivotTabelle/FlexibleReportManager.cs +++ b/Service/PivotTabelle/FlexibleReportManager.cs @@ -1,7 +1,6 @@ using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.Plugins; using BS.Shared.DataContracts; diff --git a/Service/Plugins/AiService.cs b/Service/Plugins/AiService.cs index b9da83942..637faa5f4 100644 --- a/Service/Plugins/AiService.cs +++ b/Service/Plugins/AiService.cs @@ -7,7 +7,6 @@ using System.ServiceModel; using System.Text; using BeWo.Data.Access; using BeWo.Data.Entities; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.Invoicing; using BeWo.Service.ServiceContracts; diff --git a/Service/Plugins/AiService2.cs b/Service/Plugins/AiService2.cs index 9839425b1..4a63b68e6 100644 --- a/Service/Plugins/AiService2.cs +++ b/Service/Plugins/AiService2.cs @@ -6,10 +6,10 @@ using System.Linq; using System.Net; using System.ServiceModel; using System.Text; +using AICore.Prompt.Factories; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Data.Security; -using BeWo.Service.AI; using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.Invoicing; @@ -112,15 +112,21 @@ namespace BeWo.Service.Plugins public AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid) { - var conv = createAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid); + var config = GetAiConfig(); + + var conv = createAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid, config.Context_Type); + var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv); + return conv_dc; } public AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message) { - var conv = createAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid); + var config = GetAiConfig(); - var new_messages = sendNewMessage(conv, message); + var conv = createAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid, config.Context_Type); + + var new_messages = sendNewMessage(conv, message, config); var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv); @@ -265,11 +271,12 @@ namespace BeWo.Service.Plugins return models; } - private AiConversation createAiConversation(int uicontext, Dictionary context, long modell_oid) + private AiConversation createAiConversation(int uicontext, Dictionary context, long modell_oid, AiDataContextType context_Type) { var current_user = UserRightHelper.GetLoggedInUserWithOid(); + var factory = getFactory(context_Type); - var system_prompt = AiPromptFactory.CreateSystemInstructions(uicontext, context); + var system_prompt = factory.CreateSystemInstructions(uicontext, context); var conv = new AiConversation(); conv.Created = DateTime.Now; @@ -278,6 +285,7 @@ namespace BeWo.Service.Plugins conv.Messages = new List(); conv.Modell = DAOFactory.GenericDAO.LoadByID(modell_oid); conv.UIContext = uicontext; + conv.ContextType = context_Type; conv.Updated = DateTime.Now; conv.ApplicationUserOid = current_user.Oid; @@ -294,10 +302,19 @@ namespace BeWo.Service.Plugins return conv; } - private AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message) + private BaseAiPromptFactory getFactory(AiDataContextType context_Type) + { + if (context_Type == AiDataContextType.json) + return new JsonAiPromptFactory(); + + throw new NotImplementedException($"AiDataContextType {context_Type} not implemented."); + } + + private AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message, AiConfigDC config = null) { // Hole Config - var config = GetAiConfig(); + if (config == null) + config = GetAiConfig(); var configModelName = config.SelectedModel.ModelName; // Build Payload @@ -308,7 +325,7 @@ namespace BeWo.Service.Plugins }; // Check Token Size - if(!checkTokenSize(conv.Messages, configModelName)) + if (!checkTokenSize(conv.Messages, configModelName)) { throw new Exception(); } diff --git a/Service/Plugins/FlexibleReportService.cs b/Service/Plugins/FlexibleReportService.cs index 4db046bb1..5ec94089e 100644 --- a/Service/Plugins/FlexibleReportService.cs +++ b/Service/Plugins/FlexibleReportService.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using BeWo.Data.Access; using BeWo.Data.Entities; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.MessageContracts; using BS.Shared; diff --git a/Service/Plugins/StundenuebersichtAuswertung.cs b/Service/Plugins/StundenuebersichtAuswertung.cs index ce98e870f..b9f5bba79 100644 --- a/Service/Plugins/StundenuebersichtAuswertung.cs +++ b/Service/Plugins/StundenuebersichtAuswertung.cs @@ -6,7 +6,6 @@ using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Configuration; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.MessageContracts; using BS.Shared; diff --git a/Service/Plugins/UserService.cs b/Service/Plugins/UserService.cs index cffba1582..d490514e2 100644 --- a/Service/Plugins/UserService.cs +++ b/Service/Plugins/UserService.cs @@ -6,7 +6,6 @@ using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Data.Security; -using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.MessageContracts; using BS.Shared; @@ -15,7 +14,6 @@ using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using BS.Shared.Services; -using Utils = BeWo.Service.Core.Utils; namespace BeWo.Service.Plugins diff --git a/Service/Service.csproj b/Service/Service.csproj index 592076b4a..f8a96c933 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -556,7 +556,6 @@ - @@ -576,6 +575,10 @@ + + {69D70CA9-0DF9-419E-BFAF-F4539F129BD9} + AICore + {47331732-dd96-4075-869f-83aa9f3f9937} Dakota @@ -620,15 +623,6 @@ - - - - - - - - -