Skip to content

Commit

Permalink
Merge pull request #621 from betalgo/dev
Browse files Browse the repository at this point in the history
Utilities update 8.1.0
  • Loading branch information
kayhantolga committed Aug 28, 2024
2 parents 2112756 + acc5902 commit df3bee8
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 4 deletions.
91 changes: 91 additions & 0 deletions OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Reflection;
using System.Text.Json.Serialization;
using OpenAI.ObjectModels.SharedModels;

namespace OpenAI.Utilities.FunctionCalling;

public class PropertyDefinitionGenerator
{
public static PropertyDefinition GenerateFromType(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));

if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime))
{
return GeneratePrimitiveDefinition(type);
}
else if (type.IsEnum)
{
return GenerateEnumDefinition(type);
}
else if (type.IsArray || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)))
{
return GenerateArrayDefinition(type);
}
else
{
return GenerateObjectDefinition(type);
}
}

private static PropertyDefinition GeneratePrimitiveDefinition(Type type)
{
if (type == typeof(string))
return PropertyDefinition.DefineString();
else if (type == typeof(int) || type == typeof(long))
return PropertyDefinition.DefineInteger();
else if (type == typeof(float) || type == typeof(double) || type == typeof(decimal))
return PropertyDefinition.DefineNumber();
else if (type == typeof(bool))
return PropertyDefinition.DefineBoolean();
else if (type == typeof(DateTime))
return PropertyDefinition.DefineString("ISO 8601 date-time string");
else
throw new ArgumentException($"Unsupported primitive type: {type.Name}");
}

private static PropertyDefinition GenerateEnumDefinition(Type type)
{
var enumValues = Enum.GetNames(type);
return PropertyDefinition.DefineEnum(new List<string>(enumValues), $"Enum of type {type.Name}");
}

private static PropertyDefinition GenerateArrayDefinition(Type type)
{
Type elementType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];

Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Converting null literal or possible null value to non-nullable type.

Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.
return PropertyDefinition.DefineArray(GenerateFromType(elementType));

Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Possible null reference argument for parameter 'type' in 'PropertyDefinition PropertyDefinitionGenerator.GenerateFromType(Type type)'.

Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'type' in 'PropertyDefinition PropertyDefinitionGenerator.GenerateFromType(Type type)'.

Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'type' in 'PropertyDefinition PropertyDefinitionGenerator.GenerateFromType(Type type)'.

Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'type' in 'PropertyDefinition PropertyDefinitionGenerator.GenerateFromType(Type type)'.
}

private static PropertyDefinition GenerateObjectDefinition(Type type)
{
var properties = new Dictionary<string, PropertyDefinition>();
var required = new List<string>();

foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
string propertyName = GetJsonPropertyName(prop);
properties[propertyName] = GenerateFromType(prop.PropertyType);

// You might want to customize this logic based on your needs
if (!prop.PropertyType.IsValueType && Nullable.GetUnderlyingType(prop.PropertyType) == null)
{
required.Add(propertyName);
}
}

return PropertyDefinition.DefineObject(
properties,
required,
false, // Set additionalProperties to false by default
$"Object of type {type.Name}",
null
);
}

private static string GetJsonPropertyName(PropertyInfo prop)
{
var jsonPropertyNameAttribute = prop.GetCustomAttribute<JsonPropertyNameAttribute>();
return jsonPropertyNameAttribute != null ? jsonPropertyNameAttribute.Name : prop.Name;
}
}
6 changes: 3 additions & 3 deletions OpenAI.Utilities/OpenAI.Utilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageProjectUrl>https://openai.com/</PackageProjectUrl>
<PackageIcon>OpenAI-Betalgo.png</PackageIcon>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>8.0.1</Version>
<Version>8.1.0</Version>
<Authors>Tolga Kayhan, Betalgo</Authors>
<Company>Betalgo Up Ltd.</Company>
<Product>Utility tools for Betalgo.OpenAI</Product>
Expand Down Expand Up @@ -40,8 +40,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Betalgo.OpenAI" Version="*"/>
<PackageReference Include="CsvHelper" Version="31.0.3" />
<PackageReference Include="Betalgo.OpenAI" Version="8.6.2" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Microsoft.Data.Analysis" Version="0.21.1" />
</ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion OpenAI.UtilitiesPlayground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@


//await EmbeddingTestHelpers.ExerciseEmbeddingTools(sdk);
await FunctionCallingTestHelpers.ExerciseFunctionCalling(sdk);
//await FunctionCallingTestHelpers.ExerciseFunctionCalling(sdk);
await JsonSchemaResponseTypeTestHelpers.RunChatWithJsonSchemaResponseFormat2(sdk);

Console.WriteLine("Press any key to exit...");
Console.ReadKey();
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using OpenAI.Interfaces;
using OpenAI.ObjectModels;
using OpenAI.ObjectModels.RequestModels;
using OpenAI.Utilities.FunctionCalling;

namespace OpenAI.UtilitiesPlayground.TestHelpers;

public static class JsonSchemaResponseTypeTestHelpers
{
public static async Task RunChatWithJsonSchemaResponseFormat2(IOpenAIService sdk)
{
Console.WriteLine("Chat Completion Testing is starting:");
try
{
var completionResult = await sdk.ChatCompletion.CreateCompletion(new()
{
Messages = new List<ChatMessage>
{
ChatMessage.FromSystem("You are a helpful math tutor. Guide the user through the solution step by step."),
ChatMessage.FromUser("how can I solve 8x + 7 = -23")
},
Model = "gpt-4o-2024-08-06",
ResponseFormat = new()
{
Type = StaticValues.CompletionStatics.ResponseFormat.JsonSchema,
JsonSchema = new()
{
Name = "math_response",
Strict = true,
Schema = PropertyDefinitionGenerator.GenerateFromType(typeof(MathResponse))
}
}
});

if (completionResult.Successful)
{
var response =JsonSerializer.Deserialize<MathResponse>(completionResult.Choices.First().Message.Content!);
foreach (var responseStep in response?.Steps!)
{
Console.WriteLine(responseStep.Explanation);
Console.WriteLine(responseStep.Output);
}

Console.WriteLine("Final:" + response.FinalAnswer);

}
else
{
if (completionResult.Error == null)
{
throw new("Unknown Error");
}

Console.WriteLine($"{completionResult.Error.Code}: {completionResult.Error.Message}");
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

public class MathResponse
{
public MathResponse()
{
Steps = new();
}

[JsonPropertyName("steps")]
public List<Step> Steps { get; set; }

[JsonPropertyName("final_answer")]
public string FinalAnswer { get; set; }
}

public class Step
{
[JsonPropertyName("explanation")]
public string Explanation { get; set; }

[JsonPropertyName("output")]
public string Output { get; set; }
}
}

0 comments on commit df3bee8

Please sign in to comment.