using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OllamaSharp; using OllamaSharp.Models; using xAiApi.Configurations; using xAiApi.Constants; using xAiApi.Extensions; using xAiApi.Interfaces; using xAiApi.Models; using xAiModels.Interfaces; using xAiService.Helpers; using xCommons.Extensions; using xExceptions.Constants; namespace xAiApi.Providers { /// /// Base Embedding Provider Service ... /// public abstract class XAiEmbeddingServiceBase : XAIServiceBase, IXAiEmbeddingServiceBase { private readonly XAiModelDescriptor descriptor; protected XAiEmbeddingServiceBase( IXAiDataProvider dataProvider, XAiApiConfiguration configuration, ILogger logger, string embeddingModelName = XAiApiConstants.XAiEmbeddingModelName ) : base( dataProvider, logger, configuration ) { // // Prepare Embedding Model Descriptor ... descriptor = configuration.GetModel(embeddingModelName); if (!descriptor.IsValid()) { XException.InvalidConfiguration.Throw(); } } /// /// Embedding Specified String ... /// /// /// /// public virtual async Task Embeding( string content, CancellationToken cancellationToken = default ) { // // Validate ... if (content.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // // Retrieve Ollama Client ... using var client = GetEmbeddingClient(); // // Create Embeding 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); // return result; } /// /// Embedding Specified Batch ... /// /// /// /// public virtual async Task> Embedings( string[] batch, CancellationToken cancellationToken = default ) { // // Validate ... if (!batch.HasChild() || !batch.All(x => !x.IsNullOrEmpty()) ) { XException.InvalidArgs.Throw(); } // // Retrieve Ollama Client ... using var client = GetEmbeddingClient(); // // Create Embeding Request .... var request = new EmbedRequest { Input = [.. batch], 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 .ToArray() ?? []; // // Validate Result ... if (result.Length == 0) { XException.ActionFailed.Throw(); } // // Normalize ... foreach (var vector in result) { VectorHelper.Normalize(vector); } // return result; } /// /// Access Embedding Client ... /// /// public OllamaApiClient GetEmbeddingClient() { // var result = new OllamaApiClient(new Uri(descriptor.Url)); // return result; } } }