-
-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
Utilities update 8.1.0
- Loading branch information
There are no files selected for viewing
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 GitHub Actions / Analyze (csharp)
Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs GitHub Actions / build
Check warning on line 56 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs GitHub Actions / build
|
||
return PropertyDefinition.DefineArray(GenerateFromType(elementType)); | ||
Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs GitHub Actions / Analyze (csharp)
Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs GitHub Actions / build
Check warning on line 57 in OpenAI.Utilities/FunctionCalling/PropertyDefinitionGenerator.cs GitHub Actions / build
|
||
} | ||
|
||
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; | ||
} | ||
} |
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; } | ||
} | ||
} |