2023-09-09 15:37:38 +00:00
|
|
|
using BotSharp.Abstraction.MLTasks;
|
2023-12-15 16:31:11 +00:00
|
|
|
using BotSharp.Abstraction.MLTasks.Settings;
|
2023-09-09 15:37:38 +00:00
|
|
|
|
|
|
|
|
namespace BotSharp.Core.Infrastructures;
|
|
|
|
|
|
|
|
|
|
public class CompletionProvider
|
|
|
|
|
{
|
2024-07-19 03:28:24 +00:00
|
|
|
public static object GetCompletion(IServiceProvider services,
|
2023-12-15 17:54:44 +00:00
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null,
|
|
|
|
|
AgentLlmConfig? agentConfig = null)
|
2023-12-15 16:31:11 +00:00
|
|
|
{
|
2024-03-25 16:22:43 +00:00
|
|
|
var settingsService = services.GetRequiredService<ILlmProviderService>();
|
2023-12-15 16:31:11 +00:00
|
|
|
|
2024-03-25 16:22:43 +00:00
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider, model: model, agentConfig: agentConfig);
|
2023-12-15 16:31:11 +00:00
|
|
|
|
|
|
|
|
var settings = settingsService.GetSetting(provider, model);
|
|
|
|
|
|
2023-12-15 17:54:44 +00:00
|
|
|
if (settings.Type == LlmModelType.Text)
|
2023-12-15 16:31:11 +00:00
|
|
|
{
|
2024-07-19 03:28:24 +00:00
|
|
|
return GetTextCompletion(services, provider: provider, model: model, agentConfig: agentConfig);
|
2023-12-15 16:31:11 +00:00
|
|
|
}
|
2024-07-18 20:17:40 +00:00
|
|
|
else if (settings.Type == LlmModelType.Embedding)
|
2023-12-15 16:31:11 +00:00
|
|
|
{
|
2024-07-19 03:28:24 +00:00
|
|
|
return GetTextEmbedding(services, provider: provider, model: model);
|
2024-07-18 20:17:40 +00:00
|
|
|
}
|
2024-07-19 03:28:24 +00:00
|
|
|
else if (settings.Type == LlmModelType.Image)
|
2024-07-18 20:17:40 +00:00
|
|
|
{
|
2024-07-19 03:28:24 +00:00
|
|
|
return GetImageCompletion(services, provider: provider, model: model);
|
|
|
|
|
}
|
2024-08-28 16:08:12 +00:00
|
|
|
else if (settings.Type == LlmModelType.Audio)
|
|
|
|
|
{
|
2025-03-22 00:28:22 +00:00
|
|
|
return GetAudioTranscriber(services, provider: provider, model: model);
|
2024-08-28 16:08:12 +00:00
|
|
|
}
|
2025-04-02 17:02:02 +00:00
|
|
|
else if (settings.Type == LlmModelType.Realtime)
|
|
|
|
|
{
|
|
|
|
|
return GetRealTimeCompletion(services, provider: provider, model: model);
|
|
|
|
|
}
|
2024-07-19 03:28:24 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return GetChatCompletion(services, provider: provider, model: model, agentConfig: agentConfig);
|
2023-12-15 16:31:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-15 17:54:44 +00:00
|
|
|
public static IChatCompletion GetChatCompletion(IServiceProvider services,
|
|
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null,
|
2024-05-14 18:34:10 +00:00
|
|
|
string? modelId = null,
|
2024-05-16 21:32:58 +00:00
|
|
|
bool? multiModal = null,
|
2025-02-03 04:02:36 +00:00
|
|
|
bool? realTime = null,
|
2023-12-15 17:54:44 +00:00
|
|
|
AgentLlmConfig? agentConfig = null)
|
2023-09-09 15:37:38 +00:00
|
|
|
{
|
|
|
|
|
var completions = services.GetServices<IChatCompletion>();
|
2024-05-14 18:34:10 +00:00
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider, model: model, modelId: modelId,
|
2025-02-03 04:02:36 +00:00
|
|
|
multiModal: multiModal,
|
|
|
|
|
agentConfig: agentConfig);
|
2023-09-19 16:29:25 +00:00
|
|
|
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
|
|
|
|
logger.LogError($"Can't resolve completion provider by {provider}");
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-14 16:51:39 +00:00
|
|
|
completer?.SetModelName(model);
|
2023-09-19 16:29:25 +00:00
|
|
|
return completer;
|
2023-09-09 15:37:38 +00:00
|
|
|
}
|
2023-10-09 22:28:17 +00:00
|
|
|
|
2024-06-24 19:32:52 +00:00
|
|
|
public static ITextCompletion GetTextCompletion(IServiceProvider services,
|
|
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null,
|
|
|
|
|
AgentLlmConfig? agentConfig = null)
|
|
|
|
|
{
|
|
|
|
|
var completions = services.GetServices<ITextCompletion>();
|
|
|
|
|
|
|
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider, model: model, agentConfig: agentConfig);
|
|
|
|
|
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
|
|
|
|
logger.LogError($"Can't resolve completion provider by {provider}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
completer.SetModelName(model);
|
|
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-19 03:28:24 +00:00
|
|
|
public static IImageCompletion GetImageCompletion(IServiceProvider services,
|
2024-07-18 20:17:40 +00:00
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null,
|
|
|
|
|
string? modelId = null,
|
|
|
|
|
bool imageGenerate = false)
|
|
|
|
|
{
|
2024-07-19 03:28:24 +00:00
|
|
|
var completions = services.GetServices<IImageCompletion>();
|
|
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider,
|
|
|
|
|
model: model, modelId: modelId, imageGenerate: imageGenerate);
|
2024-07-18 20:17:40 +00:00
|
|
|
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
|
|
|
|
logger.LogError($"Can't resolve completion provider by {provider}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
completer?.SetModelName(model);
|
2024-06-24 19:32:52 +00:00
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-01 02:14:02 +00:00
|
|
|
public static ITextEmbedding GetTextEmbedding(IServiceProvider services,
|
|
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null)
|
|
|
|
|
{
|
|
|
|
|
var completions = services.GetServices<ITextEmbedding>();
|
|
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider, model: model);
|
|
|
|
|
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
2024-08-28 16:08:12 +00:00
|
|
|
logger.LogError($"Can't resolve text-embedding provider by {provider}");
|
2024-07-01 02:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-22 20:23:22 +00:00
|
|
|
|
|
|
|
|
var llmProviderService = services.GetRequiredService<ILlmProviderService>();
|
|
|
|
|
var found = llmProviderService.GetSetting(provider, model);
|
|
|
|
|
|
2024-07-01 02:14:02 +00:00
|
|
|
completer.SetModelName(model);
|
2025-08-20 14:58:45 +00:00
|
|
|
completer.SetDimension(found.Embedding?.Dimension ?? 0);
|
2024-07-01 02:14:02 +00:00
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-22 00:28:22 +00:00
|
|
|
public static IAudioTranscription GetAudioTranscriber(
|
2024-08-08 19:54:32 +00:00
|
|
|
IServiceProvider services,
|
2025-03-22 00:28:22 +00:00
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null)
|
2024-08-08 19:54:32 +00:00
|
|
|
{
|
2025-03-22 00:28:22 +00:00
|
|
|
var completions = services.GetServices<IAudioTranscription>();
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == (provider ?? "openai"));
|
2024-08-08 19:54:32 +00:00
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
2025-03-22 00:28:22 +00:00
|
|
|
logger.LogError($"Can't resolve audio-transcriber provider by {provider}");
|
|
|
|
|
return default!;
|
2024-08-08 19:54:32 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-22 00:28:22 +00:00
|
|
|
completer.SetModelName(model ?? "gpt-4o-mini-transcribe");
|
|
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IAudioSynthesis GetAudioSynthesizer(
|
|
|
|
|
IServiceProvider services,
|
|
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null)
|
|
|
|
|
{
|
|
|
|
|
var completions = services.GetServices<IAudioSynthesis>();
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == (provider ?? "openai"));
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
|
|
|
|
logger.LogError($"Can't resolve audio-synthesizer provider by {provider}");
|
|
|
|
|
return default!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
completer.SetModelName(model ?? "gpt-4o-mini-tts");
|
2024-08-17 03:39:32 +00:00
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-03 04:02:36 +00:00
|
|
|
public static IRealTimeCompletion GetRealTimeCompletion(IServiceProvider services,
|
|
|
|
|
string? provider = null,
|
|
|
|
|
string? model = null,
|
|
|
|
|
string? modelId = null,
|
|
|
|
|
bool? multiModal = null,
|
|
|
|
|
AgentLlmConfig? agentConfig = null)
|
|
|
|
|
{
|
|
|
|
|
var completions = services.GetServices<IRealTimeCompletion>();
|
|
|
|
|
(provider, model) = GetProviderAndModel(services, provider: provider, model: model, modelId: modelId,
|
|
|
|
|
multiModal: multiModal,
|
2025-04-02 17:02:02 +00:00
|
|
|
modelType: LlmModelType.Realtime,
|
2025-02-03 04:02:36 +00:00
|
|
|
agentConfig: agentConfig);
|
|
|
|
|
|
|
|
|
|
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
|
|
|
|
if (completer == null)
|
|
|
|
|
{
|
|
|
|
|
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
|
|
|
|
logger.LogError($"Can't resolve completion provider by {provider}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
completer?.SetModelName(model);
|
|
|
|
|
return completer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-24 19:32:52 +00:00
|
|
|
private static (string, string) GetProviderAndModel(IServiceProvider services,
|
2024-03-25 16:22:43 +00:00
|
|
|
string? provider = null,
|
2023-12-15 17:54:44 +00:00
|
|
|
string? model = null,
|
2024-05-14 18:34:10 +00:00
|
|
|
string? modelId = null,
|
2024-05-16 21:32:58 +00:00
|
|
|
bool? multiModal = null,
|
2025-04-02 17:02:02 +00:00
|
|
|
LlmModelType? modelType = null,
|
2024-06-24 19:32:52 +00:00
|
|
|
bool imageGenerate = false,
|
2023-12-15 17:54:44 +00:00
|
|
|
AgentLlmConfig? agentConfig = null)
|
2023-10-09 22:28:17 +00:00
|
|
|
{
|
2023-12-15 17:54:44 +00:00
|
|
|
var agentSetting = services.GetRequiredService<AgentSettings>();
|
2023-10-09 22:28:17 +00:00
|
|
|
var state = services.GetRequiredService<IConversationStateService>();
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(provider))
|
|
|
|
|
{
|
2023-12-15 17:54:44 +00:00
|
|
|
provider = agentConfig?.Provider ?? agentSetting.LlmConfig?.Provider;
|
|
|
|
|
provider = state.GetState("provider", provider ?? "azure-openai");
|
2023-10-09 22:28:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(model))
|
|
|
|
|
{
|
2023-12-15 17:54:44 +00:00
|
|
|
model = agentConfig?.Model ?? agentSetting.LlmConfig?.Model;
|
2024-03-25 16:22:43 +00:00
|
|
|
if (state.ContainsState("model"))
|
|
|
|
|
{
|
2025-10-09 22:23:51 +00:00
|
|
|
model = state.GetState("model", model ?? "gpt-image-1-mini");
|
2024-03-25 16:22:43 +00:00
|
|
|
}
|
2024-05-14 18:34:10 +00:00
|
|
|
else if (state.ContainsState("model_id") || !string.IsNullOrEmpty(modelId))
|
2024-03-25 16:22:43 +00:00
|
|
|
{
|
2024-05-14 18:34:10 +00:00
|
|
|
var modelIdentity = state.ContainsState("model_id") ? state.GetState("model_id") : modelId;
|
2024-03-25 16:22:43 +00:00
|
|
|
var llmProviderService = services.GetRequiredService<ILlmProviderService>();
|
2024-06-24 19:32:52 +00:00
|
|
|
model = llmProviderService.GetProviderModel(provider, modelIdentity,
|
2025-02-03 04:02:36 +00:00
|
|
|
multiModal: multiModal,
|
2025-04-02 17:02:02 +00:00
|
|
|
modelType: modelType,
|
2025-02-03 04:02:36 +00:00
|
|
|
imageGenerate: imageGenerate)?.Name;
|
2024-03-25 16:22:43 +00:00
|
|
|
}
|
2023-10-09 22:28:17 +00:00
|
|
|
}
|
|
|
|
|
|
2024-03-25 16:22:43 +00:00
|
|
|
state.SetState("provider", provider);
|
|
|
|
|
state.SetState("model", model);
|
|
|
|
|
return (provider, model);
|
|
|
|
|
}
|
2023-09-09 15:37:38 +00:00
|
|
|
}
|