diff --git a/Interfaces/IXAiEmbeddingServiceBase.cs b/Interfaces/IXAiEmbeddingServiceBase.cs index 00d5644..1c2037f 100644 --- a/Interfaces/IXAiEmbeddingServiceBase.cs +++ b/Interfaces/IXAiEmbeddingServiceBase.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.AI; using OllamaSharp; namespace xAiApi.Interfaces @@ -37,5 +38,7 @@ namespace xAiApi.Interfaces /// /// OllamaApiClient GetEmbeddingClient(); + + IEmbeddingGenerator> GetEmbeddingGenerator(); } } \ No newline at end of file diff --git a/Providers/XAIServiceBase.cs b/Providers/XAIServiceBase.cs index 3397865..ce3739c 100644 --- a/Providers/XAIServiceBase.cs +++ b/Providers/XAIServiceBase.cs @@ -179,7 +179,7 @@ namespace xAiApi.Providers case XAiModelProviderType.OpenAI: // // Instance Ollama Client using Custom HttpCLient ... - var llamaClient = new OpenAIClient( + var openAiClient = new OpenAIClient( new ApiKeyCredential(apiKey.IsNullOrEmpty() ? XAiApiConstants.XOpenAINoKey : apiKey), new OpenAIClientOptions { @@ -188,7 +188,7 @@ namespace xAiApi.Providers } ); result = - llamaClient + openAiClient .GetChatClient(model) .AsIChatClient(); break; diff --git a/Providers/XAiEmbeddingServiceBase.cs b/Providers/XAiEmbeddingServiceBase.cs index 7056e8b..8925cf7 100644 --- a/Providers/XAiEmbeddingServiceBase.cs +++ b/Providers/XAiEmbeddingServiceBase.cs @@ -16,6 +16,11 @@ using xExceptions.Constants; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.AI; +using xAiModels.Constants; +using OpenAI; +using System.ClientModel; +using System.ClientModel.Primitives; namespace xAiApi.Providers { @@ -25,6 +30,7 @@ namespace xAiApi.Providers public abstract class XAiEmbeddingServiceBase : XAIServiceBase, IXAiEmbeddingServiceBase { private readonly XAiModelDescriptor descriptor; + private readonly ILogger logger; protected XAiEmbeddingServiceBase( IXAiDataProvider dataProvider, @@ -44,6 +50,9 @@ namespace xAiApi.Providers { XException.InvalidConfiguration.Throw(); } + + // + this.logger = logger; } /// @@ -65,23 +74,18 @@ namespace xAiApi.Providers } // - // Retrieve Ollama Client ... - using var client = GetEmbeddingClient(); - - // - // Create Embedding Request .... - var request = new EmbedRequest + using var generator = GetEmbeddingGenerator(); + GeneratedEmbeddings> response = null; + try { - Input = [content], - Model = descriptor.LLM, - }; + response = await generator.GenerateAsync([content]); + } + catch (Exception ex) + { + logger.LogError(ex.Message); + } // - // Make Request and Recieve Response ... - var response = await client.EmbedAsync( - request: request, - cancellationToken: cancellationToken - ); if (response.IsNullOrDefault()) { XException.ActionFailed.Throw(); @@ -89,15 +93,50 @@ namespace xAiApi.Providers // // Generae Result ... - var result = response? - .Embeddings? - .FirstOrDefault() - ?? []; + var result = response + .First()? + .Vector + .ToArray() + ?? []; if (result.Length == 0) { XException.ActionFailed.Throw(); } + // + // Retrieve Ollama Client ... + // using var client = GetEmbeddingClient(); + + // // + // // Create Embedding Request .... + // var request = new EmbedRequest + // { + // Input = [content], + // Model = descriptor.LLM, + // }; + + // // + // // Make Request and Recieve Response ... + // var response = await client.EmbedAsync( + // request: request, + // cancellationToken: cancellationToken + // ); + // if (response.IsNullOrDefault()) + // { + // XException.ActionFailed.Throw(); + // } + + // // + // // Generae Result ... + // var result = response? + // .Embeddings? + // .FirstOrDefault() + // ?? []; + // if (result.Length == 0) + // { + // XException.ActionFailed.Throw(); + // } + // // Normalize ... VectorHelper.Normalize(result); @@ -186,5 +225,53 @@ namespace xAiApi.Providers // return result; } + + public IEmbeddingGenerator> GetEmbeddingGenerator() + { + // + IEmbeddingGenerator> result = null; + + // + if (!descriptor.IsValid()) + { + XException.InvalidData.Throw("Invalid Embedding Model ..."); + } + + // + switch (descriptor.Provider) + { + // + case XAiModelProviderType.OpenAI: + // + var openAiClient = new OpenAIClient( + new ApiKeyCredential(descriptor.ApiKey.IsNullOrEmpty() ? XAiApiConstants.XOpenAINoKey : descriptor.ApiKey), + new OpenAIClientOptions + { + Endpoint = new Uri(descriptor.Url), + Transport = new HttpClientPipelineTransport(GetHttpClient(descriptor.Url)) + } + ); + result = openAiClient + .GetEmbeddingClient(descriptor.LLM) + .AsIEmbeddingGenerator(); + break; + + // + case XAiModelProviderType.Ollama: + // + var ollamaClient = new OllamaApiClient(new Uri(descriptor.Url)); + result = ollamaClient; + break; + } + + // + if (result.IsNull()) + { + XException.InvalidData.Throw("Invalid Embedding Model ..."); + } + + // + return result; + } } } \ No newline at end of file diff --git a/appsettings.Development.json b/appsettings.Development.json index 29f045f..8387618 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -42,14 +42,14 @@ "Name": "Gemma", "LLM": "gemma3:1b", "Provider": "OpenAI", - "Url": "http://178.131.88.93:1112" + "Url": "http://178.131.88.93:1112/v1" }, { "ApiKey": "", "Name": "Embed", "LLM": "bge-m3", "Provider": "OpenAI", - "Url": "http://178.131.88.93:1113" + "Url": "http://178.131.88.93:1113/v1" } ], "Prompts": [