Custom runtime defined Enums #289
-
Hi @StephenHodgson , This doesn't seem to a restriction for OpenAI though, and especially with Tools being possible to set/defined at each Run, it would be very useful to be able to provide a non-defined enum as possible string value options for GPT to choose from. E.g. instead of: enum PossibleEnumValues { a, b, c }
PossibleEnumValues myEnum; Do you see a way for us to define it as something like: string[] possibleEnumValues = { "a", "b", "c" };
string myEnum;
... magic here ... :) Alternatively, are you aware of other ways to restrict the possible values of a field/string? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 33 replies
-
You could pass json string directly. var mathSchema = new JsonSchema("math_response", @"
{
""type"": ""object"",
""properties"": {
""steps"": {
""type"": ""array"",
""items"": {
""type"": ""object"",
""properties"": {
""explanation"": {
""type"": ""string""
},
""output"": {
""type"": ""string""
}
},
""required"": [
""explanation"",
""output""
],
""additionalProperties"": false
}
},
""final_answer"": {
""type"": ""string""
}
},
""required"": [
""steps"",
""final_answer""
],
""additionalProperties"": false
}");
var assistant = await OpenAIClient.AssistantsEndpoint.CreateAssistantAsync(
new CreateAssistantRequest(
name: "Math Tutor",
instructions: "You are a helpful math tutor. Guide the user through the solution step by step.",
model: "gpt-4o-2024-08-06",
jsonSchema: mathSchema));
ThreadResponse thread = null;
try
{
var run = await assistant.CreateThreadAndRunAsync("how can I solve 8x + 7 = -23",
async @event =>
{
Debug.Log(@event.ToJsonString());
await Task.CompletedTask;
});
thread = await run.GetThreadAsync();
run = await run.WaitForStatusChangeAsync();
Debug.Log($"Created thread and run: {run.ThreadId} -> {run.Id} -> {run.CreatedAt}");
var messages = await thread.ListMessagesAsync();
foreach (var response in messages.Items)
{
Debug.Log($"{response.Role}: {response.PrintContent()}");
}
}
finally
{
await assistant.DeleteAsync(deleteToolResources: thread == null);
if (thread != null)
{
var isDeleted = await thread.DeleteAsync(deleteToolResources: true);
Assert.IsTrue(isDeleted);
}
} |
Beta Was this translation helpful? Give feedback.
-
@StephenHodgson I found a cumbersome way to make this possible. I'm not really happy with the complicated code, and I wonder if you can think of a cleaner/simpler solution? I basically just add this public static class TypeExtensions
{
public class RuntimeEnum<T>
{
private static Dictionary<Type, string[]> _possibleValues = new Dictionary<Type, string[]>();
public string Value { get; set; }
public static string[] PossibleValues
{
get => _possibleValues[typeof(T)];
set => _possibleValues[typeof(T)] = value;
}
public static implicit operator RuntimeEnum<T>(string x)
{
return new RuntimeEnum<T>() { Value = x };
}
}
public static JObject GenerateJsonSchema(this Type type, JObject rootSchema, JsonSerializer serializer = null)
{
...
else if (type.IsGenericType == true && type.GetGenericTypeDefinition() == typeof(RuntimeEnum<>))
{
schema["type"] = "string";
schema["enum"] = new JArray();
var possibleValuesProperty = type.GetProperty("PossibleValues", BindingFlags.Public | BindingFlags.Static);
var possibleValues = possibleValuesProperty.GetValue(null) as string[];
foreach (var value in possibleValues ?? new string[0])
{
((JArray)schema["enum"]).Add(JToken.FromObject(value, serializer));
}
}
else
{
...
}
}
} And then I can at runtime define custom enum values: public class SomeClass
{
RuntimeEnum<AnyClass> MyEnum = new RuntimeEnum<AnyClass>();
public SomeClass()
{
RuntimeEnum<AnyClass>.PossibleValues = new string[] { "Value 1", "Value 2", "Value 3" };
}
} It all works fine. Just feels like there should be a simpler solution :) |
Beta Was this translation helpful? Give feedback.
-
Yes that would be much cleaner. Good idea.
Can you share example of how to change a method parameter attribute at runtime?
That's the only thing I'm not sure how to do.
…On Sat, Sep 14 2024 at 16:35, Stephen Hodgson < ***@***.*** > wrote:
I think the best thing to do is probably add attribute for this and then
have it check in TypeExtensions similar to what we do for functions.
Most likely you can use the same attributes.
—
Reply to this email directly, view it on GitHub (
#289 (reply in thread)
) , or unsubscribe (
https://github.com/notifications/unsubscribe-auth/AACJE4GUECOJLMARQ5BXDCDZWTB4HAVCNFSM6AAAAABNEPBGNKVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRUHEZTOOA
).
You are receiving this because you modified the open/close state. Message
ID: <RageAgainstThePixel/com. openai. unity/repo-discussions/289/comments/10649378
@ github. com>
|
Beta Was this translation helpful? Give feedback.
-
Hi @StephenHodgson, |
Beta Was this translation helpful? Give feedback.
You could pass json string directly.