2026-04-13 13:33:17 +02:00
using System.Runtime.CompilerServices ;
2025-04-11 14:31:10 +02:00
using AIStudio.Chat ;
using AIStudio.Provider.OpenAI ;
using AIStudio.Settings ;
namespace AIStudio.Provider.HuggingFace ;
public sealed class ProviderHuggingFace : BaseProvider
{
2025-09-03 21:25:17 +02:00
private static readonly ILogger < ProviderHuggingFace > LOGGER = Program . LOGGER_FACTORY . CreateLogger < ProviderHuggingFace >();
2026-05-31 18:46:54 +02:00
public ProviderHuggingFace ( HFInferenceProvider hfProvider , Model model ) : base ( LLMProviders . HUGGINGFACE , new Uri ( $"https://router.huggingface.co/{hfProvider.Endpoints(model)}" ), ExternalHttpTrustPolicy . SYSTEM_TRUST_ONLY , LOGGER )
2025-04-11 14:31:10 +02:00
{
2025-12-30 18:30:32 +01:00
LOGGER . LogInformation ( $"We use the inference provider '{hfProvider}'. Thus we use the base URL 'https://router.huggingface.co/{hfProvider.Endpoints(model)}'." );
2025-04-11 14:31:10 +02:00
}
#region Implementation of IProvider
/// <inheritdoc />
2026-06-20 15:55:09 +02:00
public override string Id => LLMProviders . HUGGINGFACE . ToSecretId ();
2025-04-11 14:31:10 +02:00
/// <inheritdoc />
public override string InstanceName { get ; set ; } = "HuggingFace" ;
2026-04-16 11:24:22 +02:00
/// <inheritdoc />
public override bool HasModelLoadingCapability => false ;
2025-04-11 14:31:10 +02:00
/// <inheritdoc />
2025-08-31 14:27:35 +02:00
public override async IAsyncEnumerable < ContentStreamChunk > StreamChatCompletion ( Model chatModel , ChatThread chatThread , SettingsManager settingsManager , [ EnumeratorCancellation ] CancellationToken token = default )
2025-04-11 14:31:10 +02:00
{
2026-04-13 13:33:17 +02:00
await foreach ( var content in this . StreamOpenAICompatibleChatCompletion < ChatCompletionAPIRequest , ChatCompletionDeltaStreamLine , ChatCompletionAnnotationStreamLine >(
"HuggingFace" ,
chatModel ,
chatThread ,
settingsManager ,
async ( systemPrompt , apiParameters ) =>
{
// Build the list of messages:
var messages = await chatThread . Blocks . BuildMessagesUsingNestedImageUrlAsync ( this . Provider , chatModel );
2025-04-11 14:31:10 +02:00
2026-04-13 13:33:17 +02:00
return new ChatCompletionAPIRequest
{
Model = chatModel . Id ,
2025-04-11 14:31:10 +02:00
2026-04-13 13:33:17 +02:00
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
Messages = [ systemPrompt , .. messages ],
2025-04-11 14:31:10 +02:00
2026-04-13 13:33:17 +02:00
Stream = true ,
AdditionalApiParameters = apiParameters
};
},
token : token ))
2025-04-11 14:31:10 +02:00
yield return content ;
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
/// <inheritdoc />
public override async IAsyncEnumerable < ImageURL > StreamImageCompletion ( Model imageModel , string promptPositive , string promptNegative = FilterOperator . String . Empty , ImageURL referenceImageURL = default , [ EnumeratorCancellation ] CancellationToken token = default )
{
yield break ;
}
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
2026-01-11 16:02:28 +01:00
/// <inheritdoc />
2026-05-23 11:25:18 +02:00
public override Task < TranscriptionResult > TranscribeAudioAsync ( Model transcriptionModel , string audioFilePath , SettingsManager settingsManager , CancellationToken token = default )
2026-01-11 16:02:28 +01:00
{
2026-05-23 11:25:18 +02:00
return Task . FromResult ( TranscriptionResult . Failure ());
2026-01-11 16:02:28 +01:00
}
2026-02-20 15:32:54 +01:00
/// <inhertidoc />
public override Task < IReadOnlyList < IReadOnlyList < float >>> EmbedTextAsync ( Model embeddingModel , SettingsManager settingsManager , CancellationToken token = default , params List < string > texts )
{
return Task . FromResult < IReadOnlyList < IReadOnlyList < float >>>([]);
}
2025-04-11 14:31:10 +02:00
/// <inheritdoc />
2026-04-14 13:39:11 +02:00
public override Task < ModelLoadResult > GetTextModels ( string? apiKeyProvisional = null , CancellationToken token = default )
2025-04-11 14:31:10 +02:00
{
2026-04-14 13:39:11 +02:00
return Task . FromResult ( ModelLoadResult . FromModels ([]));
2025-04-11 14:31:10 +02:00
}
/// <inheritdoc />
2026-04-14 13:39:11 +02:00
public override Task < ModelLoadResult > GetImageModels ( string? apiKeyProvisional = null , CancellationToken token = default )
2025-04-11 14:31:10 +02:00
{
2026-04-14 13:39:11 +02:00
return Task . FromResult ( ModelLoadResult . FromModels ([]));
2025-04-11 14:31:10 +02:00
}
/// <inheritdoc />
2026-04-14 13:39:11 +02:00
public override Task < ModelLoadResult > GetEmbeddingModels ( string? apiKeyProvisional = null , CancellationToken token = default )
2025-04-11 14:31:10 +02:00
{
2026-04-14 13:39:11 +02:00
return Task . FromResult ( ModelLoadResult . FromModels ([]));
2025-04-11 14:31:10 +02:00
}
2025-05-11 12:51:35 +02:00
2026-01-09 12:45:21 +01:00
/// <inheritdoc />
2026-04-14 13:39:11 +02:00
public override Task < ModelLoadResult > GetTranscriptionModels ( string? apiKeyProvisional = null , CancellationToken token = default )
2026-01-09 12:45:21 +01:00
{
2026-04-14 13:39:11 +02:00
return Task . FromResult ( ModelLoadResult . FromModels ([]));
2026-01-09 12:45:21 +01:00
}
2025-04-11 14:31:10 +02:00
#endregion
2026-04-13 13:33:17 +02:00
}