Skip to content

Commit

Permalink
Migrate from OpenAI-DotNet to OpenAI api.
Browse files Browse the repository at this point in the history
Initial version to support Agent/chat functionality.
  • Loading branch information
claudiamurialdo committed Nov 13, 2024
1 parent f730c1f commit ffd749a
Show file tree
Hide file tree
Showing 10 changed files with 303 additions and 75 deletions.
10 changes: 10 additions & 0 deletions dotnet/DotNetStandardClasses.sln
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogTest", "test\benchmarks\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccessTokenController_Test", "test\NativeAccessControllerTest\AccessTokenController_Test.csproj", "{A5589382-DB6F-4450-AE2B-6C6AA1643EF1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ai", "ai", "{D13691A9-04AE-4ABB-A694-8AD41D74CE23}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GxAI", "src\dotnetcore\Providers\AI\GxAI.csproj", "{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -641,6 +645,10 @@ Global
{A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5589382-DB6F-4450-AE2B-6C6AA1643EF1}.Release|Any CPU.Build.0 = Release|Any CPU
{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -767,6 +775,8 @@ Global
{46DAAFD1-FAF5-4904-8EC5-406BE04E5538} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC}
{A1DBDCE0-4F09-445F-A202-9B260CDD46CF} = {46DAAFD1-FAF5-4904-8EC5-406BE04E5538}
{A5589382-DB6F-4450-AE2B-6C6AA1643EF1} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC}
{D13691A9-04AE-4ABB-A694-8AD41D74CE23} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3}
{88FE3199-CFE3-42C4-AD6F-3EE49D7B5998} = {D13691A9-04AE-4ABB-A694-8AD41D74CE23}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C}
Expand Down
25 changes: 25 additions & 0 deletions dotnet/src/dotnetcore/GxClasses/Domain/CallResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using GeneXus.Application;

namespace GeneXus.Utils
{
public class CallResult
{
public CallResult() { }
public bool Success()
{
return true;
}
public bool Fail()
{
return false;
}
public msglist GetMessages()
{
return new msglist();
}
public string ToJson()
{
return "{}";
}
}
}
100 changes: 32 additions & 68 deletions dotnet/src/dotnetcore/GxClasses/Domain/GxEmbedding.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using GeneXus.Configuration;
using OpenAI;
using OpenAI.Embeddings;
using GxClasses.Helpers;
namespace GeneXus.Utils
{
public class GxEmbedding
Expand All @@ -21,9 +16,9 @@ public GxEmbedding(string model, int dimensions)
Dimensions = dimensions;
_embedding = new ReadOnlyMemory<float>(new float[dimensions]);
}
internal GxEmbedding(IReadOnlyList<double> embedding, string model, int dimensions): this(model, dimensions)
internal GxEmbedding(ReadOnlyMemory<float> embedding, string model, int dimensions) : this(model, dimensions)
{
_embedding = embedding.Select(f => (float)f).ToArray();
_embedding = embedding;
}
internal GxEmbedding(float[] embedding)
{
Expand All @@ -42,9 +37,10 @@ public static GxEmbedding GenerateEmbedding(GxEmbedding embeddingInfo, string te
{
try
{
IReadOnlyList<double> embedding = EmbeddingService.Instance.GenerateEmbeddingAsync(embeddingInfo.Model, embeddingInfo.Dimensions, text).GetAwaiter().GetResult();
ReadOnlyMemory<float> embedding = AIServiceFactory.Instance.GenerateEmbeddingAsync(embeddingInfo.Model, embeddingInfo.Dimensions, text).GetAwaiter().GetResult();
return new GxEmbedding(embedding, embeddingInfo.Model, embeddingInfo.Dimensions);
} catch (Exception ex)
}
catch (Exception ex)
{
GXUtil.ErrorToMessages("GenerateEmbedding Error", ex, Messages, false);
return embeddingInfo;
Expand All @@ -53,77 +49,45 @@ public static GxEmbedding GenerateEmbedding(GxEmbedding embeddingInfo, string te
public string Model { get; set; }
public int Dimensions { get; set; }

internal ReadOnlyMemory<float> Data => _embedding;
internal ReadOnlyMemory<float> Data => _embedding;
}
internal interface IEmbeddingService
internal interface IAIService
{
Task<IReadOnlyList<double>> GenerateEmbeddingAsync(string model, int dimensions, string input);
Task<ReadOnlyMemory<float>> GenerateEmbeddingAsync(string model, int dimensions, string input);
}

internal class EmbeddingService : IEmbeddingService
internal class AIServiceFactory
{
//static readonly IGXLogger log = GXLoggerFactory.GetLogger<EmbeddingService>();
private static volatile EmbeddingService m_Instance;
private static object m_SyncRoot = new Object();
private readonly HttpClient _httpClient;
private readonly OpenAIClient _openAIClient;
private string API_KEY = "apitokenfortest";
private const string DEFAULT_DOMAIN = "api.saia.ai";
private const string DEFAULT_VERSION = "chat";
private const string AI_PROVIDER = "AI_PROVIDER";
private const string AI_PROVIDER_API_KEY= "AI_PROVIDER_API_KEY";
EmbeddingService()
{
_httpClient = new HttpClient(new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15.0)
});

string val, domain= DEFAULT_DOMAIN;
string version = DEFAULT_VERSION;
if (Config.GetValueOf(AI_PROVIDER, out val))
{
Uri providerUri = new Uri(val);
domain = providerUri.GetLeftPart(UriPartial.Authority);
version = providerUri.AbsolutePath;
}
if (Config.GetValueOf(AI_PROVIDER_API_KEY, out val))
{
API_KEY = val;
}
OpenAIClientSettings openAIClientSettings = new OpenAIClientSettings(domain, version);
_httpClient.DefaultRequestHeaders.Add("X-Saia-Source", "Embedding");
OpenAIAuthentication openAIAuthentication = new OpenAIAuthentication(API_KEY);
_openAIClient = new OpenAIClient(openAIAuthentication, openAIClientSettings, _httpClient);

}
private static readonly IGXLogger log = GXLoggerFactory.GetLogger<AIServiceFactory>();

internal static EmbeddingService Instance
private static volatile IAIService instance;
private static object syncRoot = new object();
private const string AI_PROVIDER = "GeneXus.AI.Core, GxAI, Version=10.1.0.0, Culture=neutral, PublicKeyToken=null";
public static IAIService Instance
{
get
{
if (m_Instance == null)
if (instance == null)
{
lock (m_SyncRoot)
lock (syncRoot)
{
if (m_Instance == null)
m_Instance = new EmbeddingService();
if (instance == null)
{

try
{
Type type = AssemblyLoader.GetType(AI_PROVIDER);
instance = (IAIService)Activator.CreateInstance(type);
}
catch (Exception e)
{
GXLogging.Error(log, "Couldn't create AI Provider", e);
throw e;
}
}
}
}
return m_Instance;
return instance;
}
}

public async Task<IReadOnlyList<double>> GenerateEmbeddingAsync(string model, int dimensions, string input)
{
IReadOnlyList<Datum> data = await GenerateEmbeddingAsync(model, dimensions, new List<string> { input });
return data.First().Embedding;
}
public async Task<IReadOnlyList<Datum>> GenerateEmbeddingAsync(string model, int dimensions, IEnumerable<string> input)
{
EmbeddingsRequest embeddingRequest = new EmbeddingsRequest(input, model, null, dimensions);
EmbeddingsResponse embeddingResponse = await _openAIClient.EmbeddingsEndpoint.CreateEmbeddingAsync(embeddingRequest);
return embeddingResponse.Data;
}
}
}
1 change: 0 additions & 1 deletion dotnet/src/dotnetcore/GxClasses/GxClasses.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.22.0" PrivateAssets="ALL" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.1.0" PrivateAssets="All" />
<PackageReference Include="OpenAI-DotNet" Version="8.2.2"/>
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" PrivateAssets="All" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.7.0" PrivateAssets="All" />
<PackageReference Include="Pgvector" Version="0.3.0" />
Expand Down
3 changes: 3 additions & 0 deletions dotnet/src/dotnetcore/GxClasses/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@
[assembly: InternalsVisibleTo("DotNetCoreChunkedTest")]
[assembly: InternalsVisibleTo("DotNetCoreChunkedTest")]
[assembly: InternalsVisibleTo("GeneXus.OpenTelemetry.Diagnostics")]
[assembly: InternalsVisibleTo("ConsoleApp2")]
[assembly: InternalsVisibleTo("GxAI")]

15 changes: 15 additions & 0 deletions dotnet/src/dotnetcore/Providers/AI/GxAI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<PackageTags>Genexus AI</PackageTags>
<PackageId>GeneXus.AI.Core</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenAI" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\GxClasses\GxClasses.csproj" />
</ItemGroup>


</Project>
Loading

0 comments on commit ffd749a

Please sign in to comment.