Max Context Size

This commit is contained in:
2025-08-05 15:57:30 +02:00
parent 55424ae4cd
commit 9efb36e1ee
8 changed files with 58 additions and 80 deletions

View File

@@ -113,7 +113,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Data\Data.csproj">
<Project>{B0D73E3D-4AE7-4024-93A6-DB1F46D7CCEE}</Project>
<Project>{b0d73e3d-4ae7-4024-93a6-db1f46d7ccee}</Project>
<Name>Data</Name>
</ProjectReference>
<ProjectReference Include="..\Server\ApiFacade\ApiFacade.csproj">

View File

@@ -1,5 +1,4 @@
using BeWo.Data.Entities;
using BeWo.ServiceUtils.Core;
using BeWo.ServiceUtils.Core;
using BS.Shared.DataContracts.Feature.AI;
using BS.Shared.DataContracts;
using BS.Shared.Interface;
@@ -15,7 +14,7 @@ namespace AICore.Facade.LLM
{
public abstract class BaseLLMApiClient
{
public abstract ApiResponse<IEnumerable<AiModel>> GetAiModelle();
public abstract ApiResponse<IEnumerable<AiModelDC>> GetAiModelle();
public abstract ApiResponse<string> SendAiMessageRequest(dynamic payload, out string message, out string model, out int? duration);
}
}

View File

@@ -1,5 +1,4 @@
using BeWo.Data.Entities;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Feature.AI;
using BS.Shared.Extensions;
using BS.Shared.Interface;
@@ -28,7 +27,7 @@ namespace AICore.Facade.LLM
_ErrorExtractor = new DefaultErrorExtractor();
}
public override ApiResponse<IEnumerable<AiModel>> GetAiModelle()
public override ApiResponse<IEnumerable<AiModelDC>> GetAiModelle()
{
var models = new List<AiModelDC>();
@@ -39,7 +38,11 @@ namespace AICore.Facade.LLM
new
{
name = "",
model = ""
model = "",
details = new
{
max_context_size = 0
}
}
}
@@ -52,9 +55,9 @@ namespace AICore.Facade.LLM
throw new NotImplementedException();
}
var data = response.Data.models.Select(x => new AiModel(x.name, 0));
var data = response.Data.models.Select(x => new AiModelDC(x.name, x.details.max_context_size));
return ApiResponse<IEnumerable<AiModel>>.SuccessResponse(data);
return ApiResponse<IEnumerable<AiModelDC>>.SuccessResponse(data);
}
public override ApiResponse<string> SendAiMessageRequest(dynamic payload, out string message, out string model, out int? duration)

View File

@@ -1,5 +1,4 @@
using BeWo.Data.Entities;
using BeWo.Server.ApiFacade.Core;
using BeWo.Server.ApiFacade.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Feature.AI;
using BS.Shared.Extensions;
@@ -28,7 +27,7 @@ namespace AICore.Facade.LLM
_ErrorExtractor = new DefaultErrorExtractor();
}
public override ApiResponse<IEnumerable<AiModel>> GetAiModelle()
public override ApiResponse<IEnumerable<AiModelDC>> GetAiModelle()
{
var models = new List<AiModelDC>();
@@ -39,7 +38,11 @@ namespace AICore.Facade.LLM
new
{
id = "",
name = ""
name = "",
details = new
{
max_context_size = 0
}
}
}
@@ -52,9 +55,9 @@ namespace AICore.Facade.LLM
throw new NotImplementedException();
}
var data = response.Data.data.Select(x => new AiModel(x.name, 0));
var data = response.Data.data.Select(x => new AiModelDC(x.name, x.details.max_context_size));
return ApiResponse<IEnumerable<AiModel>>.SuccessResponse(data);
return ApiResponse<IEnumerable<AiModelDC>>.SuccessResponse(data);
}
public override ApiResponse<string> SendAiMessageRequest(dynamic payload, out string message, out string model, out int? duration)

View File

@@ -1,17 +1,19 @@
using BeWo.Data.Entities;
using BS.Shared.Exceptions;
using System;
using System.Collections.Generic;
namespace AICore.Prompt.Core
{
public static class AiUtils
{
public static string CheckTokenSize(IList<AiConversationMessage> messages, string modelName)
public static void CheckTokenSize(IList<AiConversationMessage> messages, string modelName, int max_context_size)
{
var buffer = 500;
var max_tokens = GetMaxTokensByModel(modelName);
if (max_context_size < 0)
return;
var max_tokens = max_context_size;
var prev_tokens = CalculateTokensByModel(messages, modelName);
@@ -20,27 +22,10 @@ namespace AICore.Prompt.Core
var percentage = calc_tokens * 100 / max_tokens;
if (calc_tokens > max_tokens)
return $"Windowsize exceeded: ({prev_tokens}+{buffer})/{max_tokens} ({percentage}%)";
return null;
}
private static int GetMaxTokensByModel(string modelName)
{
switch (modelName)
{
case "llama3.2:latest": return 128000;
case "gemma3:12b": return 128000;
case "gemma3:4b": return 128000;
case "gemma3_12b-max-context:latest": return 128000;
case "gemma3_4b-max-context:latest": return 128000;
case "mistral:latest": return 32000;
case "phi4:latest": return 16000;
default:
break;
var msg = $"Windowsize exceeded: ({prev_tokens}+{buffer})/{max_tokens} ({percentage}%)";
throw new BeWoNotImplementedException(msg);
}
throw BeWoNotImplementedException.CreateFromInvalidObject(modelName);
}
private static int CalculateTokensByModel(IList<AiConversationMessage> messages, string modelName)

View File

@@ -10,6 +10,7 @@ using BS.Shared.DataContracts.Light;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Proxy;
using NHibernate.Linq;
namespace BeWo.Data.Access
{
@@ -250,7 +251,12 @@ namespace BeWo.Data.Access
this.Session.Lock(entity, LockMode.None);
}
public virtual void SetActivationType(BeWoEntityBase pEntity, ActivationTypeId activationType)
public virtual void SetActivationType(IEnumerable<BeWoEntityBase> pEntities, ActivationTypeId activationType)
{
pEntities.ForEach(x => SetActivationType(x, activationType));
}
public virtual void SetActivationType(BeWoEntityBase pEntity, ActivationTypeId activationType)
{
if (pEntity.SystemEntryID == null)
{

View File

@@ -1,9 +1,12 @@
using BS.Shared;
using BS.Shared.DataContracts.Feature.AI;
using System;
using System.Diagnostics;
using System.Xml.Linq;
namespace BeWo.Data.Entities
{
[DebuggerDisplay("{ModelName}:{Value}")]
public class AiModel : BeWoEntityBase
{
public AiModel()
@@ -20,6 +23,8 @@ namespace BeWo.Data.Entities
public virtual string ModelName { get; set; }
public virtual int Value { get; set; }
public override int GetHashCode() => (ModelName, Value).GetHashCode();
public virtual int CompareTo(AiModel other)
{
if (other == null) return 1;

View File

@@ -225,51 +225,26 @@ namespace BeWo.Service.Plugins
{
var models = getAiModels();
if (models == null || !models.Any())
return null;
var model = models.FirstOrDefault(x => x.ModelName.Contains("llama3.2"))
?? models.FirstOrDefault(x => x.ModelName.Contains("llama"))
?? models.FirstOrDefault();
var llama = models.Where(x => x.ModelName.Contains("llama3.2"));
if (llama.Any())
return llama.First();
return models.First();
return model;
}
private IEnumerable<AiModel> getAiModels()
{
var old_models = DAOFactory.GenericDAO.GetAll<AiModel>();
var new_models = ServiceFacade.ActiveAiClient.GetAiModelle().GetResponseData();
var unknown_models = new_models.ToList();
var current_models = DAOFactory.GenericDAO.GetAll<AiModel>();
var current_models_deactives = current_models.Where(x => x.IsActive != ActivationTypeId.Active);
var request_models_dc = ServiceFacade.ActiveAiClient.GetAiModelle().GetResponseData();
var request_models = MapperFactory.AiModel.MapToNewEntities(request_models_dc);
int i = 0;
foreach (var old_model in old_models)
{
bool found = false;
foreach (var new_model in new_models)
{
if (old_model.ModelName == new_model.ModelName)
{
if (old_model.IsActive != BS.Shared.ActivationTypeId.Active)
DAOFactory.GenericDAO.SetActivationType(old_model, BS.Shared.ActivationTypeId.Active);
var toadd = request_models.Except(current_models);
var toremove = current_models.Except(request_models);
var toreadd = current_models_deactives.Intersect(toadd);
found = true;
var index = unknown_models.IndexOf(model => model.Equals(new_model));
unknown_models.RemoveAt(index);
break;
}
}
if (!found && old_model.IsActive == BS.Shared.ActivationTypeId.Active)
DAOFactory.GenericDAO.Deactivate(old_model);
}
if (unknown_models.Count != 0)
{
foreach (var unknown_model in unknown_models)
{
DAOFactory.GenericDAO.Insert(unknown_model);
}
}
DAOFactory.GenericDAO.Insert(toadd);
DAOFactory.GenericDAO.Deactivate(toremove);
DAOFactory.GenericDAO.SetActivationType(toreadd, ActivationTypeId.Active);
var models = DAOFactory.GenericDAO.GetAllActive<AiModel>();
@@ -312,6 +287,8 @@ namespace BeWo.Service.Plugins
// Hole Config
if (config == null)
config = GetAiConfig();
var configModel = config.SelectedModel;
var configModelName = config.SelectedModel.ModelName;
// Build Payload
@@ -334,9 +311,9 @@ namespace BeWo.Service.Plugins
conv.Messages.Add(user_msg);
// Check Token Size
if (AiUtils.CheckTokenSize(conv.Messages, configModelName) is string error)
if (-1 < configModel.Value)
{
throw new BeWoNotImplementedException(error);
AiUtils.CheckTokenSize(conv.Messages, configModelName, configModel.Value);
}
// Update DB Entity