From 6d29df2fcd64249bc9955ecb4a135e522bdbf4e9 Mon Sep 17 00:00:00 2001 From: Agustin Torres Date: Tue, 27 Oct 2026 05:27:27 +0000 Subject: [PATCH] .Net: fix(huggingface): move off retired api-inference.huggingface.co to router.huggingface.co I moved the .NET HuggingFace connector off the retired api-inference.huggingface.co host. Text generation, image-to-text and embeddings now default to router.huggingface.co/hf-inference, and embeddings use the new path order: models/{model}/pipeline/feature-extraction. Chat completion now defaults to router.huggingface.co/v1/chat/completions, with the model id still sent in the request body. I updated the unit tests, the TelemetryWithAppInsights and F# samples, and the integration testsettings.json to match. Nothing was built or run. Notice huggingface-serverless-inference-api-retired about huggingface.co's API describes the change. It was read from a file and is not signed by the provider. --- .../Demos/FSharpScripts/huggingFaceChatCompletion.fsx | 2 +- dotnet/samples/Demos/TelemetryWithAppInsights/Program.cs | 2 +- .../Services/HuggingFaceChatCompletionTests.cs | 2 +- .../Services/HuggingFaceEmbeddingGenerationTests.cs | 2 +- .../Services/HuggingFaceEmbeddingGeneratorTests.cs | 2 +- .../Services/HuggingFaceImageToTextTests.cs | 2 +- .../Services/HuggingFaceTextGenerationTests.cs | 2 +- .../Connectors.HuggingFace/Core/HuggingFaceClient.cs | 7 ++++--- .../Core/HuggingFaceMessageApiClient.cs | 3 ++- dotnet/src/IntegrationTests/testsettings.json | 2 +- 10 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dotnet/samples/Demos/FSharpScripts/huggingFaceChatCompletion.fsx b/dotnet/samples/Demos/FSharpScripts/huggingFaceChatCompletion.fsx index 60c35ac38598..ebf08f7246b3 100644 --- a/dotnet/samples/Demos/FSharpScripts/huggingFaceChatCompletion.fsx +++ b/dotnet/samples/Demos/FSharpScripts/huggingFaceChatCompletion.fsx @@ -20,7 +20,7 @@ let builder = // TODO: request your API key in your 🤗 hugging face private settings let API_KEY = "TODO_REPLACE_ME" let MODEL_ID = "microsoft/Phi-3-mini-4k-instruct" // pick the model you prefer! - let API_URL = $"https://api-inference.huggingface.co/" + let API_URL = $"https://router.huggingface.co/" let b = Kernel.CreateBuilder().AddHuggingFaceChatCompletion( MODEL_ID, diff --git a/dotnet/samples/Demos/TelemetryWithAppInsights/Program.cs b/dotnet/samples/Demos/TelemetryWithAppInsights/Program.cs index 3126b136b2a6..10de1d11d3f5 100644 --- a/dotnet/samples/Demos/TelemetryWithAppInsights/Program.cs +++ b/dotnet/samples/Demos/TelemetryWithAppInsights/Program.cs @@ -392,7 +392,7 @@ private static Kernel GetKernel(ILoggerFactory loggerFactory) { builder.AddHuggingFaceChatCompletion( model: TestConfiguration.HuggingFace.ModelId, - endpoint: new Uri("https://api-inference.huggingface.co"), + endpoint: new Uri("https://router.huggingface.co"), apiKey: TestConfiguration.HuggingFace.ApiKey, serviceId: HuggingFaceServiceKey); } diff --git a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceChatCompletionTests.cs b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceChatCompletionTests.cs index 19f293a34a66..b621a71eb91c 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceChatCompletionTests.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceChatCompletionTests.cs @@ -141,7 +141,7 @@ public async Task DefaultAddressShouldBeUsedAsync() await sut.GetChatMessageContentAsync(chatHistory); //Assert - Assert.StartsWith("https://api-inference.huggingface.co/", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); + Assert.StartsWith("https://router.huggingface.co/v1/chat/completions", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); } [Fact] diff --git a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGenerationTests.cs b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGenerationTests.cs index 9d29ab3d056f..3d01b732b3fe 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGenerationTests.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGenerationTests.cs @@ -98,7 +98,7 @@ public async Task ModelUrlShouldBeBuiltSuccessfullyAsync() await sut.GenerateEmbeddingsAsync([]); //Assert - Assert.Equal("https://fake-random-test-host/fake-path/pipeline/feature-extraction/fake-model", this._messageHandlerStub.RequestUri?.AbsoluteUri); + Assert.Equal("https://fake-random-test-host/fake-path/models/fake-model/pipeline/feature-extraction", this._messageHandlerStub.RequestUri?.AbsoluteUri); } [Fact] diff --git a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGeneratorTests.cs b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGeneratorTests.cs index 5db71b979818..6f8bef730694 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGeneratorTests.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceEmbeddingGeneratorTests.cs @@ -98,7 +98,7 @@ public async Task ModelUrlShouldBeBuiltSuccessfullyAsync() await sut.GenerateAsync([]); //Assert - Assert.Equal("https://fake-random-test-host/fake-path/pipeline/feature-extraction/fake-model", this._messageHandlerStub.RequestUri?.AbsoluteUri); + Assert.Equal("https://fake-random-test-host/fake-path/models/fake-model/pipeline/feature-extraction", this._messageHandlerStub.RequestUri?.AbsoluteUri); } [Fact] diff --git a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceImageToTextTests.cs b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceImageToTextTests.cs index 2fe5b5b34d77..19751d514ce8 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceImageToTextTests.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceImageToTextTests.cs @@ -134,7 +134,7 @@ public async Task DefaultAddressShouldBeUsedAsync() await sut.GetTextContentsAsync(this._imageContentInput); //Assert - Assert.StartsWith("https://api-inference.huggingface.co/models", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); + Assert.StartsWith("https://router.huggingface.co/hf-inference/models", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); } [Fact] diff --git a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceTextGenerationTests.cs b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceTextGenerationTests.cs index 1e222adeec12..e96b0e587445 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceTextGenerationTests.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace.UnitTests/Services/HuggingFaceTextGenerationTests.cs @@ -129,7 +129,7 @@ public async Task DefaultAddressShouldBeUsedAsync() await sut.GetTextContentsAsync("fake-text"); //Assert - Assert.StartsWith("https://api-inference.huggingface.co/models", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); + Assert.StartsWith("https://router.huggingface.co/hf-inference/models", this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase); } [Fact] diff --git a/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceClient.cs b/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceClient.cs index 7aa847bcef90..9cb8b3198ae7 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceClient.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceClient.cs @@ -34,7 +34,8 @@ internal HuggingFaceClient( string? modelId = null, Uri? endpoint = null, string? apiKey = null, - ILogger? logger = null) + ILogger? logger = null, + Uri? defaultEndpoint = null) { Verify.NotNull(httpClient); @@ -44,7 +45,7 @@ internal HuggingFaceClient( throw new InvalidOperationException("A valid model id or endpoint must be provided."); } - endpoint ??= new Uri("https://api-inference.huggingface.co"); + endpoint ??= defaultEndpoint ?? new Uri("https://router.huggingface.co/hf-inference"); this.Separator = endpoint.AbsolutePath.EndsWith("/", StringComparison.InvariantCulture) ? string.Empty : "/"; this.Endpoint = endpoint; this.ModelId = modelId; @@ -300,7 +301,7 @@ public async Task>> GenerateEmbeddingsAsync( } private Uri GetEmbeddingGenerationEndpoint(string? modelId) - => string.IsNullOrWhiteSpace(modelId) ? this.Endpoint : new($"{this.Endpoint}{this.Separator}pipeline/feature-extraction/{modelId}"); + => string.IsNullOrWhiteSpace(modelId) ? this.Endpoint : new($"{this.Endpoint}{this.Separator}models/{modelId}/pipeline/feature-extraction"); #endregion diff --git a/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceMessageApiClient.cs b/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceMessageApiClient.cs index dcb149fefd83..042334c4f3ae 100644 --- a/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceMessageApiClient.cs +++ b/dotnet/src/Connectors/Connectors.HuggingFace/Core/HuggingFaceMessageApiClient.cs @@ -73,7 +73,8 @@ internal HuggingFaceMessageApiClient( modelId, endpoint, apiKey, - logger); + logger, + new Uri("https://router.huggingface.co")); } internal async IAsyncEnumerable StreamCompleteChatMessageAsync( diff --git a/dotnet/src/IntegrationTests/testsettings.json b/dotnet/src/IntegrationTests/testsettings.json index 34cf9d54be04..633247dc59c4 100644 --- a/dotnet/src/IntegrationTests/testsettings.json +++ b/dotnet/src/IntegrationTests/testsettings.json @@ -68,7 +68,7 @@ "ChatCompletionModelId": "tgi", "ApiKey": "", "TextGenerationEndpoint": "http://localhost:8080/", - "EmbeddingEndpoint": "https://api-inference.huggingface.co/", + "EmbeddingEndpoint": "https://router.huggingface.co/hf-inference/", "ChatCompletionEndpoint": "http://localhost:8080/" }, "GoogleAI": {