Personen Navigation funktioniert - doppelte oid

Beide OpenWebUi + ollama support
This commit is contained in:
2025-08-07 16:40:07 +02:00
parent 9efb36e1ee
commit 78fc6b3d29
21 changed files with 893 additions and 383 deletions

View File

@@ -14,8 +14,8 @@ namespace AICore.Context.EntryMapper
//pContext.CustomerOid = "---";
//pContext.EmployeeOid = "---";
pContext.FullName = pObject.FirstNameLastName;
pContext.Geschlecht = pObject.Sex.ToString();
pContext.Function = pObject.Function.Value;
pContext.Geschlecht = pObject.Sex?.ToString();
pContext.Function = pObject.Function?.Value;
}
}
}

View File

@@ -55,7 +55,7 @@ namespace AICore.Facade.LLM
throw new NotImplementedException();
}
var data = response.Data.models.Select(x => new AiModelDC(x.name, x.details.max_context_size));
var data = response.Data.models.Select(x => new AiModelDC(BS.Shared.AiModelSource.ollama, x.name, x.details.max_context_size));
return ApiResponse<IEnumerable<AiModelDC>>.SuccessResponse(data);
}

View File

@@ -55,7 +55,7 @@ namespace AICore.Facade.LLM
throw new NotImplementedException();
}
var data = response.Data.data.Select(x => new AiModelDC(x.name, x.details.max_context_size));
var data = response.Data.data.Select(x => new AiModelDC(BS.Shared.AiModelSource.openwebui, x.name, x.details?.max_context_size ?? -2));
return ApiResponse<IEnumerable<AiModelDC>>.SuccessResponse(data);
}

View File

@@ -59,7 +59,7 @@ namespace BeWo
public static string ShortVersion = "3.26";
public static string Version = "Version 3.26 - 1.2.1 Test";
public static string Version = "Version 3.26 - 1.3 AI Test";
public static int RenderTier = 0;
public static bool IsInDesignMode = DesignerProperties.GetIsInDesignMode(new DependencyObject());

View File

@@ -70,7 +70,7 @@
Grid.Row="1"
Grid.Column="2"
IsEnabled="False"
Value="{Binding Config.Temperature}" />
Value="{Binding Config.Temperature}"/>
<Label Grid.Row="2" IsEnabled="False">
top__p

File diff suppressed because it is too large Load Diff

View File

@@ -197,7 +197,7 @@ namespace BeWo.View.Navigation
}
var dict = new Dictionary<TableID, long[]>() {
{ TableID.Customer, oids.ToArray()}
{ TableID.Customer, oids.Distinct().ToArray()}
};
return dict;

View File

@@ -103,7 +103,7 @@ namespace BeWo.View.Navigation
}
var dict = new Dictionary<TableID, long[]>() {
{ TableID.Employee, oids.ToArray()}
{ TableID.Employee, oids.Distinct().ToArray()}
};
return dict;

View File

@@ -69,7 +69,7 @@ namespace BeWo.View.Navigation
var dict = new Dictionary<TableID, long[]>() {
{
TableID.Organisation, oids.ToArray()}
TableID.Organisation, oids.Distinct().ToArray()}
};
return dict;

View File

@@ -21,6 +21,7 @@ using System.Collections;
using System.Windows.Input;
using BeWo.Core.Commands;
using BeWo.ViewModel.View;
using DevExpress.XtraBars.Docking;
namespace BeWo.View.Navigation
{
@@ -106,7 +107,7 @@ namespace BeWo.View.Navigation
var dict = new Dictionary<TableID, long[]>() {
{
TableID.Person, oids.ToArray()}
TableID.Person, oids.Distinct().ToArray()}
};
return dict;

View File

@@ -220,7 +220,7 @@ namespace BeWo.View.Navigation
var dict = new Dictionary<TableID, long[]>() {
{
TableID.SupportConcept, oids.ToArray()}
TableID.SupportConcept, oids.Distinct().ToArray()}
};
return dict;

View File

@@ -14,18 +14,18 @@
<binding name="BeWoBasicEndpoint" closeTimeout="00:05:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" messageEncoding="Text">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<!--<security mode="None" />-->
<security mode="None" />
<security mode="Transport" />
<!-- mode="Transport" für https und "None" sonst-->
</binding>
<binding name="BeWoStreamingEndpoint" receiveTimeout="10:10:00" sendTimeout="10:01:00" maxBufferSize="65536" maxReceivedMessageSize="67108864" transferMode="StreamedRequest" useDefaultWebProxy="true" messageEncoding="Text">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<!--<security mode="None" />-->
<security mode="None" />
<security mode="Transport" />
<!-- mode="Transport" für https und "None" sonst-->
</binding>
<binding name="QueryServiceEndpoint" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" messageEncoding="Text">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

View File

@@ -14,12 +14,7 @@ namespace BeWo.Data.Entities
_Tid = TableID.AiModel;
}
public AiModel(string modelName, int value) : this()
{
ModelName = modelName;
Value = value;
}
public virtual AiModelSource ModelSource { get; set; }
public virtual string ModelName { get; set; }
public virtual int Value { get; set; }
@@ -29,10 +24,14 @@ namespace BeWo.Data.Entities
{
if (other == null) return 1;
var comp = ModelName.CompareTo(other.ModelName);
var comp = ModelSource.CompareTo(other.ModelSource);
if (comp != 0) return comp;
var comp1 = ModelName.CompareTo(other.ModelName);
if (comp1 != 0) return comp;
var comp2 = Value.CompareTo(other.Value);
return comp2;
@@ -41,6 +40,7 @@ namespace BeWo.Data.Entities
public override bool Equals(object obj)
{
return obj is AiModel ent &&
ModelSource == ent.ModelSource &&
ModelName == ent.ModelName &&
Value == ent.Value;
}

View File

@@ -13,6 +13,7 @@
<property name="IsActive" type="BS.Shared.ActivationTypeId, BS.Shared" />
<property name="SystemEntryID" type="BS.Shared.SystemEntryID, BS.Shared" />
<property name="Notice"/>
<property name="ModelSource" type="BS.Shared.AiModelSource, BS.Shared"/>
<property name="ModelName"/>
<property name="Value"/>
</class>

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<NameOfLastUsedPublishProfile>C:\Projects\Bewo\BeWo - Main\Host\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<UseIISExpress>true</UseIISExpress>
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
<LastActiveSolutionConfig>Release|Any CPU</LastActiveSolutionConfig>
<Use64BitIISExpress>false</Use64BitIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />

View File

@@ -7,4 +7,10 @@
<appSettings>
<add key="OpenWebUIKey" value=""/>
<add key="OllamaKey" value=""/>
<add key="GetGkvSumApiKey" value=""/>
<add key="DownloadReportApiKey" value=""/>
<add key="OpenrouteServiceApiKey" value="" />
<add key="GoogleDistanceMatrixApiKey" value="" />
<add key="GkvSecretKey" value="" />
</appSettings>

View File

@@ -0,0 +1,2 @@
ALTER TABLE `aimodel`
ADD COLUMN `ModelSource` INT NULL DEFAULT NULL AFTER `SystemEntryID`;

View File

@@ -18,6 +18,7 @@ namespace BeWo.Service.DCEntityMapper
pDataContract.Oid = pEntity.Oid;
pDataContract.Version = pEntity.Version;
pDataContract.Notice = pEntity.Notice;
pDataContract.ModelSource = pEntity.ModelSource;
pDataContract.ModelName = pEntity.ModelName;
pDataContract.Value = pEntity.Value;
@@ -31,6 +32,7 @@ namespace BeWo.Service.DCEntityMapper
pEntity.Oid = pDataContract.Oid;
pEntity.Version = pDataContract.Version;
pEntity.Notice = pDataContract.Notice;
pEntity.ModelSource = pDataContract.ModelSource;
pEntity.ModelName = pDataContract.ModelName;
pEntity.Value = pDataContract.Value;

View File

@@ -35,7 +35,7 @@ namespace BeWo.Service.Plugins
// - DBs
// ======================[ Config ]======================
public AiConfigDC GetAiConfig()
public virtual AiConfigDC GetAiConfig()
{
var configs = DAOFactory.GenericDAO.GetAllActive<AiConfig>();
@@ -48,11 +48,16 @@ namespace BeWo.Service.Plugins
DAOFactory.GenericDAO.Insert(config);
}
if (config.SelectedModel is null)
{
config.SelectedModel = getDefaultAiModel();
}
var config_dc = MapperFactory.AiConfig.MapToNewDC(config);
return config_dc;
}
public AiConfigDC UpdateAiConfig(AiConfigDC toUpdate)
public virtual AiConfigDC UpdateAiConfig(AiConfigDC toUpdate)
{
if (toUpdate?.Oid is null)
throw new InvalidOperationException();
@@ -69,7 +74,7 @@ namespace BeWo.Service.Plugins
}
// ======================[ Models ]======================
public IEnumerable<AiModelDC> GetAiModels()
public virtual IEnumerable<AiModelDC> GetAiModels()
{
var models = getAiModels();
@@ -78,7 +83,7 @@ namespace BeWo.Service.Plugins
// ======================[ Conversations ]======================
public IEnumerable<AiConversationDC> GetAiConversations(AiContextType uicontext, long? oid)
public virtual IEnumerable<AiConversationDC> GetAiConversations(AiContextType uicontext, long? oid)
{
// SearchDAO
var current_user = UserRightHelper.GetLoggedInUserWithOid();
@@ -113,7 +118,7 @@ namespace BeWo.Service.Plugins
return dcs;
}
public AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid)
public virtual AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid)
{
var config = GetAiConfig();
@@ -123,7 +128,7 @@ namespace BeWo.Service.Plugins
return conv_dc;
}
public AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message)
public virtual AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message)
{
var config = GetAiConfig();
@@ -135,7 +140,7 @@ namespace BeWo.Service.Plugins
return conv_dc;
}
public AiConversationDC CloneAiConversation(long conversation_oid, long? last_message_oid)
public virtual AiConversationDC CloneAiConversation(long conversation_oid, long? last_message_oid)
{
var parent_conv = DAOFactory.GenericDAO.GetByID<AiConversation>(conversation_oid);
@@ -180,7 +185,7 @@ namespace BeWo.Service.Plugins
return dc;
}
public long UpdateAiConversationDisplayname(long oid, long version, string displayname)
public virtual long UpdateAiConversationDisplayname(long oid, long version, string displayname)
{
var conv = DAOFactory.GenericDAO.GetByID<AiConversation>(oid);
@@ -193,7 +198,7 @@ namespace BeWo.Service.Plugins
return conv.Version.Value;
}
public void DeleteAiConversation(long conversation_oid)
public virtual void DeleteAiConversation(long conversation_oid)
{
var conversation = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation_oid);
@@ -201,7 +206,7 @@ namespace BeWo.Service.Plugins
}
// ======================[ Conversationmessages ]======================
public AiConversationMessageDC[] SendNewMessage(long conversation, string message)
public virtual AiConversationMessageDC[] SendNewMessage(long conversation, string message)
{
var conv = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation);
@@ -210,7 +215,7 @@ namespace BeWo.Service.Plugins
// ======================[ private ]======================
private AiConfig getDefaultAiConfig()
protected virtual AiConfig getDefaultAiConfig()
{
var config = new AiConfig();
@@ -221,26 +226,31 @@ namespace BeWo.Service.Plugins
return config;
}
private AiModel getDefaultAiModel()
protected virtual AiModel getDefaultAiModel()
{
var models = getAiModels();
var model = models.FirstOrDefault(x => x.ModelName.Contains("llama3.2"))
var model = models.FirstOrDefault(x => x.ModelName.Contains("gemma3") && x.ModelName.Contains("12b") && x.ModelName.Contains("max-context"))
?? models.FirstOrDefault(x => x.ModelName.Contains("gemma3") && x.ModelName.Contains("12b"))
?? models.FirstOrDefault(x => x.ModelName.Contains("gemma3"))
?? models.FirstOrDefault(x => x.ModelName.Contains("llama"))
?? models.FirstOrDefault();
return model;
}
private IEnumerable<AiModel> getAiModels()
protected virtual IEnumerable<AiModel> getAiModels()
{
var current_models = DAOFactory.GenericDAO.GetAll<AiModel>();
var current_models_actives = current_models.Where(x => x.IsActive == ActivationTypeId.Active);
var current_models_deactives = current_models.Where(x => x.IsActive != ActivationTypeId.Active);
var request_models_dc = ServiceFacade.ActiveAiClient.GetAiModelle().GetResponseData();
var request_models_dc_ollama = ServiceFacade.OllamaApiClient.GetAiModelle().GetResponseData();
var request_models_dc_owui = ServiceFacade.OpenWebApiClient.GetAiModelle().GetResponseData();
var request_models_dc = request_models_dc_ollama.Union(request_models_dc_owui);
var request_models = MapperFactory.AiModel.MapToNewEntities(request_models_dc);
var toadd = request_models.Except(current_models);
var toremove = current_models.Except(request_models);
var toreadd = current_models_deactives.Intersect(toadd);
var toremove = current_models_actives.Except(request_models);
var toreadd = current_models_deactives.Intersect(request_models);
DAOFactory.GenericDAO.Insert(toadd);
DAOFactory.GenericDAO.Deactivate(toremove);
@@ -251,7 +261,7 @@ namespace BeWo.Service.Plugins
return models;
}
private AiConversation createAiConversation(AiContextType uicontext, Dictionary<TableID, long[]> context, long modell_oid, AiDataContextType context_Type)
protected virtual AiConversation createAiConversation(AiContextType uicontext, Dictionary<TableID, long[]> context, long modell_oid, AiDataContextType context_Type)
{
var current_user = UserRightHelper.GetLoggedInUserWithOid();
var factory = new AiPromptFactory();
@@ -282,7 +292,7 @@ namespace BeWo.Service.Plugins
return conv;
}
private AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message, AiConfigDC config = null)
protected virtual AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message, AiConfigDC config = null)
{
// Hole Config
if (config == null)
@@ -324,7 +334,16 @@ namespace BeWo.Service.Plugins
// Send Request, wait for Response
var dt_before_request = DateTime.Now;
var response = ServiceFacade.ActiveAiClient.SendAiMessageRequest(payload, out var message2, out var model, out var duration);
ApiResponse<string> response;
string message2, model;
int? duration;
if (config.SelectedModel.ModelSource == AiModelSource.openwebui)
response = ServiceFacade.OpenWebApiClient.SendAiMessageRequest(payload, out message2, out model, out duration);
else if (config.SelectedModel.ModelSource == AiModelSource.ollama)
response = ServiceFacade.OllamaApiClient.SendAiMessageRequest(payload, out message2, out model, out duration);
else
throw new NotImplementedException();
if (!response.Success)
{

View File

@@ -1411,4 +1411,10 @@ namespace BS.Shared
OrganisationSingle = 23,
SupportConceptSingle = 24,
}
public enum AiModelSource
{
openwebui,
ollama
}
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
@@ -14,22 +15,28 @@ namespace BS.Shared.DataContracts.Feature.AI
}
public AiModelDC(string name, int value)
public AiModelDC(AiModelSource modelSource, string name, int value)
{
ModelSource = modelSource;
ModelName = name;
Value = value;
}
public string ModelName { get; set; }
public int Value { get; set; }
public AiModelSource ModelSource { get; set; }
public int CompareTo(AiModelDC other)
public virtual int CompareTo(AiModelDC other)
{
if(other == null) return 1;
if (other == null) return 1;
var comp = ModelName.CompareTo(other.ModelName);
var comp = ModelSource.CompareTo(other.ModelSource);
if(comp != 0) return comp;
if (comp != 0) return comp;
var comp1 = ModelName.CompareTo(other.ModelName);
if (comp1 != 0) return comp;
var comp2 = Value.CompareTo(other.Value);
@@ -38,10 +45,10 @@ namespace BS.Shared.DataContracts.Feature.AI
public override bool Equals(object obj)
{
return obj is AiModelDC dc &&
Oid == dc.Oid &&
ModelName == dc.ModelName &&
Value == dc.Value;
return obj is AiModelDC ent &&
ModelSource == ent.ModelSource &&
ModelName == ent.ModelName &&
Value == ent.Value;
}
public override int GetHashCode()
@@ -49,6 +56,7 @@ namespace BS.Shared.DataContracts.Feature.AI
unchecked
{
var result = 0;
result = (result * 397) ^ ModelSource.GetHashCode();
result = (result * 397) ^ ModelName.GetHashCode();
result = (result * 397) ^ Value.GetHashCode();
return result;
@@ -57,7 +65,7 @@ namespace BS.Shared.DataContracts.Feature.AI
public override string ToString()
{
return $"{ModelName}";
return $"{ModelName} ({ModelSource})";
}
}
}