using System; using OpenAI; using System.Linq; using OllamaSharp; using System.Threading; using xAiApi.Constants; using xAiModels.Models; using xAiApi.Extensions; using xAiApi.Interfaces; using xAiService.Helpers; using System.ClientModel; using xCommons.Extensions; using xAiModels.Constants; using xAiModels.Extensions; using xAiModels.Interfaces; using xAiApi.Configurations; using xExceptions.Constants; using System.Threading.Tasks; using Microsoft.Extensions.AI; using System.Collections.Generic; using Microsoft.Extensions.Logging; using System.ClientModel.Primitives; namespace xAiApi.Providers { /// /// Base Embedding Provider Service ... /// public abstract class XAiEmbeddingServiceBase : XAIServiceBase, IXAiEmbeddingServiceBase { private readonly XAiModelDescriptor descriptor; private readonly ILogger logger; protected XAiEmbeddingServiceBase( IXAiDataProvider dataProvider, XAiApiConfiguration configuration, ILogger logger, string embeddingModelName = XAiApiConstants.XAiEmbeddingModelName ) : base(dataProvider, logger, configuration, null) { // // Prepare Embedding Model Descriptor ... descriptor = configuration.GetModel(embeddingModelName); if (!descriptor.IsValid()) { XException.InvalidConfiguration.Throw(); } // this.logger = logger; } /// /// Embedding Specified String ... /// /// /// /// public virtual async Task Embedding( string content, CancellationToken cancellationToken = default ) { // // Validate ... if (content.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // using var generator = GetEmbeddingGenerator(); // GeneratedEmbeddings> response = null; response = await generator.GenerateAsync( values: [content], cancellationToken: cancellationToken ); // if (response.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // // Generae Result ... var result = response .First()? .Vector .ToArray() ?? []; if (result.Length == 0) { XException.ActionFailed.Throw(); } // // Normalize ... VectorHelper.Normalize(result); // return result; } /// /// Embedding Specified Batch ... /// /// /// /// public virtual async Task> Embeddings( string[] batch, CancellationToken cancellationToken = default ) { // // Validate ... if (!batch.HasChild() || !batch.All(x => !x.IsNullOrEmpty()) ) { XException.InvalidArgs.Throw(); } // using var generator = GetEmbeddingGenerator(); // GeneratedEmbeddings> response = null; response = await generator.GenerateAsync( values: [.. batch], cancellationToken: cancellationToken ); // if (response.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // var result = response .Select(e => e.Vector.ToArray()) .ToList(); // // Normalize ... foreach (var vector in result) { VectorHelper.Normalize(vector); } // return result; } /// /// Embedding Generator ... /// /// 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; } } }