BotSharp/src/Plugins/BotSharp.Plugin.AudioHandler/Functions/HandleAudioRequestFn.cs

120 lines
4.1 KiB
C#
Raw Normal View History

2024-08-17 03:39:32 +00:00
using BotSharp.Core.Infrastructures;
using Microsoft.AspNetCore.StaticFiles;
namespace BotSharp.Plugin.AudioHandler.Functions;
public class HandleAudioRequestFn : IFunctionCallback
{
2024-12-04 22:12:02 +00:00
public string Name => "util-audio-handle_audio_request";
2024-08-17 03:39:32 +00:00
public string Indication => "Handling audio request";
private readonly IServiceProvider _serviceProvider;
2024-08-28 16:08:12 +00:00
private readonly IFileStorageService _fileStorage;
2024-08-17 03:39:32 +00:00
private readonly ILogger<HandleAudioRequestFn> _logger;
private readonly BotSharpOptions _options;
private readonly IEnumerable<string> _audioContentType = new List<string>
{
AudioType.mp3.ToFileType(),
AudioType.wav.ToFileType(),
};
public HandleAudioRequestFn(
2024-08-28 16:08:12 +00:00
IFileStorageService fileStorage,
2024-08-17 03:39:32 +00:00
IServiceProvider serviceProvider,
ILogger<HandleAudioRequestFn> logger,
2024-08-26 22:24:07 +00:00
BotSharpOptions options)
2024-08-17 03:39:32 +00:00
{
2024-08-28 16:08:12 +00:00
_fileStorage = fileStorage;
2024-08-17 03:39:32 +00:00
_serviceProvider = serviceProvider;
_logger = logger;
_options = options;
}
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<LlmContextIn>(message.FunctionArgs, _options.JsonSerializerOptions);
var conv = _serviceProvider.GetRequiredService<IConversationService>();
var wholeDialogs = conv.GetDialogHistory();
2024-08-26 22:24:07 +00:00
var dialogs = AssembleFiles(conv.ConversationId, wholeDialogs);
2024-08-17 03:39:32 +00:00
2024-08-26 22:24:07 +00:00
var response = await GetResponeFromDialogs(dialogs);
2024-08-17 03:39:32 +00:00
message.Content = response;
return true;
}
2024-08-26 22:24:07 +00:00
private List<RoleDialogModel> AssembleFiles(string convId, List<RoleDialogModel> dialogs)
2024-08-17 03:39:32 +00:00
{
2024-08-28 16:08:12 +00:00
if (dialogs.IsNullOrEmpty())
{
return new List<RoleDialogModel>();
}
2024-08-17 03:39:32 +00:00
var messageId = dialogs.Select(x => x.MessageId).Distinct().ToList();
2024-08-28 16:08:12 +00:00
var audioMessageFiles = _fileStorage.GetMessageFiles(convId, messageId, FileSourceType.User, _audioContentType);
2024-08-17 03:39:32 +00:00
audioMessageFiles = audioMessageFiles.Where(x => x.ContentType.Contains("audio")).ToList();
foreach (var dialog in dialogs)
{
var found = audioMessageFiles.Where(x => x.MessageId == dialog.MessageId).ToList();
2024-08-26 22:24:07 +00:00
if (found.IsNullOrEmpty()) continue;
2024-08-17 03:39:32 +00:00
dialog.Files = found.Select(x => new BotSharpFile
{
ContentType = x.ContentType,
FileUrl = x.FileUrl,
FileStorageUrl = x.FileStorageUrl
}).ToList();
}
return dialogs;
}
private async Task<string> GetResponeFromDialogs(List<RoleDialogModel> dialogs)
{
2024-08-28 16:08:12 +00:00
var audioCompletion = PrepareModel();
2024-08-17 03:39:32 +00:00
var dialog = dialogs.Where(x => !x.Files.IsNullOrEmpty()).Last();
2024-08-28 16:08:12 +00:00
var transcripts = new List<string>();
2024-08-26 22:24:07 +00:00
2024-08-17 03:39:32 +00:00
foreach (var file in dialog.Files)
{
2024-08-28 16:08:12 +00:00
if (file == null || string.IsNullOrWhiteSpace(file.FileStorageUrl)) continue;
2024-08-17 03:39:32 +00:00
2024-08-28 16:08:12 +00:00
var extension = Path.GetExtension(file.FileStorageUrl);
var fileName = Path.GetFileName(file.FileStorageUrl);
if (!ParseAudioFileType(fileName)) continue;
var bytes = _fileStorage.GetFileBytes(file.FileStorageUrl);
using var stream = new MemoryStream(bytes);
stream.Position = 0;
var result = await audioCompletion.GenerateTextFromAudioAsync(stream, fileName);
transcripts.Add(result);
stream.Close();
2024-08-17 03:39:32 +00:00
}
2024-08-28 16:08:12 +00:00
if (transcripts.IsNullOrEmpty())
2024-08-17 03:39:32 +00:00
{
throw new FileNotFoundException($"No audio files found in the dialog. MessageId: {dialog.MessageId}");
}
2024-08-26 22:24:07 +00:00
2024-08-28 16:08:12 +00:00
return string.Join("\r\n\r\n", transcripts);
2024-08-17 03:39:32 +00:00
}
2024-08-28 16:08:12 +00:00
private IAudioCompletion PrepareModel()
2024-08-17 03:39:32 +00:00
{
2024-08-28 16:08:12 +00:00
return CompletionProvider.GetAudioCompletion(_serviceProvider, provider: "openai", model: "whisper-1");
2024-08-26 22:24:07 +00:00
}
2024-08-28 16:08:12 +00:00
private bool ParseAudioFileType(string fileName)
2024-08-26 22:24:07 +00:00
{
2024-08-28 16:08:12 +00:00
var extension = Path.GetExtension(fileName).TrimStart('.').ToLower();
2024-08-26 22:24:07 +00:00
var provider = new FileExtensionContentTypeProvider();
2024-08-28 16:08:12 +00:00
bool canParse = Enum.TryParse<AudioType>(extension, out _) || provider.TryGetContentType(fileName, out _);
2024-08-26 22:24:07 +00:00
return canParse;
2024-08-17 03:39:32 +00:00
}
}