using BS.Shared.Exceptions; using BS.Shared.Interface.Feature.AICore; using System; using System.Collections.Generic; using System.Linq; namespace BS.Shared.Core { public static class AiUtils { private const double MAX_TOKENS_SYSTEM_PERCENTAGE = 40.0d; private const double MAX_TOKENS_USER_PERCENTAGE = 10.0d; private const double MAX_TOKENS_CONVERSATION_PERCENTAGE = 80.0d; public static bool CheckSystemMessageContextSize(IEnumerable messages, string modelName, int max_context_size, out string error) { return CheckContextSize(messages, modelName, max_context_size, MAX_TOKENS_SYSTEM_PERCENTAGE, out error); } public static bool CheckUserFirstMessageContextSize(IEnumerable messages, string modelName, int max_context_size, out string error) { return CheckContextSize(messages, modelName, max_context_size, MAX_TOKENS_SYSTEM_PERCENTAGE + MAX_TOKENS_USER_PERCENTAGE, out error); } public static bool CheckUserAllMessageContextSize(IEnumerable messages, string modelName, int max_context_size, out string error) { return CheckContextSize(messages, modelName, max_context_size, MAX_TOKENS_CONVERSATION_PERCENTAGE, out error); } private static bool CheckContextSize(IEnumerable messages, string modelName, int max_context_size, double maximum, out string error) { error = null; if (max_context_size < 0) throw new ArgumentOutOfRangeException(nameof(max_context_size)); if (max_context_size == 0) return false; var tokens_count = CalculateTokensByModel(messages, modelName); var percentage = (double)tokens_count * 100 / max_context_size; var success = percentage <= maximum; if (!success) { error = $"Windowsize exceeded: {tokens_count}/{max_context_size} ({percentage}%>{maximum}%)"; } return success; } private static int CalculateTokensByModel(IEnumerable messages, string modelName) { var count = 0; foreach (var message in messages) { count += 4; count += message.Length / 2; } return count; } } }