-
-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[schemars(required)] special case for Option<T> #337
Comments
Skimming through the OpenAI docs, it looks like this schema would define how a type is serialized rather than how it's deserialized, is that correct? If so, since the latest schemars alpha version (1.0.0-alpha.15), you can specify that you want the "serialize" schema by constructing a let schema = SchemaSettings::default()
.for_serialize()
.into_generator()
.into_root_schema_for::<MyStruct>(); Then, all fields will be included in the "required" array, even if they're As for always setting RecursiveTransform(|schema: &mut Schema| {
if schema.get("properties").is_some() {
schema.insert("additionalProperties".to_owned(), false.into());
}
}) I see there are some other restrictions on OpenAI structured output schemas, e.g. the docs don't mention the None of the examples given in the OpenAI docs include a meta-schema ( Putting it all together, we get: let settings = SchemaSettings::default()
.for_serialize()
.with(|s| s.meta_schema = None)
.with_transform(ReplaceConstValue)
.with_transform(RecursiveTransform(|schema: &mut Schema| {
if schema.get("properties").is_some() {
schema.insert("additionalProperties".to_owned(), false.into());
}
if let Some(one_of) = schema.remove("oneOf") {
schema.insert("anyOf".to_owned(), one_of);
}
}));
let schema = settings.into_generator().into_root_schema_for::<MyStruct>();
println!("{}", serde_json::to_string_pretty(&schema).unwrap()); For the example {
"title": "MyStruct",
"type": "object",
"properties": {
"my_bool": {
"type": "boolean"
},
"my_int": {
"type": "integer",
"format": "int32"
},
"my_nullable_enum": {
"anyOf": [
{
"$ref": "#/$defs/MyEnum"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"required": [
"my_int",
"my_bool",
"my_nullable_enum"
],
"$defs": {
"MyEnum": {
"anyOf": [
{
"type": "object",
"properties": {
"StringNewType": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"StringNewType"
]
},
{
"type": "object",
"properties": {
"StructVariant": {
"type": "object",
"properties": {
"floats": {
"type": "array",
"items": {
"type": "number",
"format": "float"
}
}
},
"additionalProperties": false,
"required": [
"floats"
]
}
},
"additionalProperties": false,
"required": [
"StructVariant"
]
}
]
}
}
} ...which I think conforms to the OpenAI requirements |
First off, what an absolutely amazing and truly stellar reply. Very appreciated! I will try this out as soon as possible.
At this moment the "strict" option for structured output does not support At the moment OpenAI does not support Since I believe it might take some time before OpenAI starts expanding the JSON Schema feature set for "strict" mode; I'm interested in supporting the basic premise of |
Are you sure? I was going by https://platform.openai.com/docs/guides/structured-outputs/supported-schemas which says it does support |
Ah, yes you are right; which means your Which obviously makes things infinitely easier. In regard to |
I don't fully understand what you're trying to do - is it just that you'd like to generate a schema for an example value, but without the let mut schema = schema_for_value!(json!({
"i": 123,
"s": "hello world",
"o": {
"a": [true, false],
}
}));
schema.remove("examples"); This produces the schema {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"i": {
"type": "integer"
},
"s": {
"type": "string"
},
"o": {
"type": "object",
"properties": {
"a": {
"type": "array",
"items": {
"type": "boolean"
}
}
}
}
}
} |
It's more about producing a schema that expresses the exact values without relying on |
I'm still not sure I understand - you have a type that can only have one specific value? If so, there's not much point using schemars at all, you can "generate" a schema via something like |
Some consumers of JSON Schema such as OpenAI Structured Output require that all fields are required. They also require that
"additionalProperties": false
always be set (ensured by#[serde(deny_unknown_fields)]
).The special
#[schemars(required)
case forOption<T>
makes it complicated to correctly express a schema which includes optional values (in the sense we want null as output). If this special case was opt-in, or there was an opt-out this friction would go away.The text was updated successfully, but these errors were encountered: