Skip to content

Commit

Permalink
Merge canary
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniosarosi committed Dec 25, 2024
2 parents 2a433cc + e9b4cb0 commit 855893f
Show file tree
Hide file tree
Showing 34 changed files with 664 additions and 85 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Share your creations and ask questions in our [Discord](https://discord.gg/BTNBe

- [BAML + NextJS 14](https://github.com/BoundaryML/baml-examples/tree/main/nextjs-starter)
- [BAML + FastAPI + Streaming](https://github.com/BoundaryML/baml-examples/tree/main/python-fastapi-starter)
- [All BAML Examples](https://github.com/BoundaryML/baml-examples)

## A BAML LLM Function

Expand Down
57 changes: 57 additions & 0 deletions engine/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 37 additions & 11 deletions engine/baml-lib/baml-core/src/ir/json_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,40 @@ impl WithJsonSchema for FieldType {
"required": ["url"],
}),
},
FieldType::List(item) => json!({
"type": "array",
"items": (*item).json_schema()
}),
FieldType::Map(_k, v) => json!({
"type": "object",
"additionalProperties": {
"type": v.json_schema(),
// Handle list types (arrays) with optional support
// For example: string[]? generates a schema that allows both array and null
FieldType::List(item) => {
let mut schema = json!({
"type": "array",
"items": (*item).json_schema()
});
// If the list itself is optional (marked with ?),
// modify the schema to accept either an array or null
if self.is_optional() {
schema["type"] = json!(["array", "null"]);
// Add default null value for optional arrays
schema["default"] = serde_json::Value::Null;
}
}),
schema
},
// Handle map types with optional support
// For example: map<string, int>? generates a schema that allows both object and null
FieldType::Map(_k, v) => {
let mut schema = json!({
"type": "object",
"additionalProperties": {
"type": v.json_schema(),
}
});
// If the map itself is optional (marked with ?),
// modify the schema to accept either an object or null
if self.is_optional() {
schema["type"] = json!(["object", "null"]);
// Add default null value for optional maps
schema["default"] = serde_json::Value::Null;
}
schema
},
FieldType::Union(options) => json!({
"anyOf": options.iter().map(|t| {
let mut res = t.json_schema();
Expand All @@ -214,18 +238,20 @@ impl WithJsonSchema for FieldType {
"type": "array",
"prefixItems": options.iter().map(|t| t.json_schema()).collect::<Vec<_>>(),
}),
// The caller object is responsible for adding the "null" type
// Handle optional types (marked with ?) that aren't lists or maps
FieldType::Optional(inner) => {
match **inner {
// For primitive types, we can simply add "null" to the allowed types
FieldType::Primitive(_) => {
let mut res = inner.json_schema();
res["type"] = json!([res["type"], "null"]);
res["default"] = serde_json::Value::Null;
res
}
// For complex types, we need to use anyOf to allow either the type or null
_ => {
let mut res = inner.json_schema();
// if res is a map, add a "title" field
// Add a title for better schema documentation
if let serde_json::Value::Object(r) = &mut res {
r.insert("title".to_string(), json!(inner.to_string()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ fn validate_type_exists(ctx: &mut Context<'_>, field_type: &FieldType) -> bool {
fn validate_type_allowed(ctx: &mut Context<'_>, field_type: &FieldType) {
match field_type {
FieldType::Map(arity, kv_types, ..) => {
if arity.is_optional() {
ctx.push_error(DatamodelError::new_validation_error(
"Maps are not allowed to be optional",
field_type.span().clone(),
));
}

match &kv_types.0 {
// String key.
FieldType::Primitive(FieldArity::Required, TypeValue::String, ..) => {}
Expand Down Expand Up @@ -118,15 +111,7 @@ fn validate_type_allowed(ctx: &mut Context<'_>, field_type: &FieldType) {
FieldType::Literal(..) => {}
FieldType::Symbol(..) => {}

FieldType::List(arity, field_type, ..) => {
if arity.is_optional() {
ctx.push_error(DatamodelError::new_validation_error(
"Lists are not allowed to be optional",
field_type.span().clone(),
));
}
validate_type_allowed(ctx, field_type)
}
FieldType::List(arity, field_type, ..) => validate_type_allowed(ctx, field_type),
FieldType::Tuple(_, field_types, ..) | FieldType::Union(_, field_types, ..) => {
for field_type in field_types {
validate_type_allowed(ctx, field_type);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class OptionalListAndMap {
p string[]?
q map<string, string>?
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,3 @@ class ComplexTypes {
// 16 | n map<complex_key_type[], map<another_key, (int | string[])>>
// 17 | o (((int | string) | bool[]), (float, double) | long_long_identifier_123)
// |
// error: Error validating: Lists are not allowed to be optional
// --> class/secure_types.baml:18
// |
// 17 | o (((int | string) | bool[]), (float, double) | long_long_identifier_123)
// 18 | p string[]?
// |
// error: Error validating: Maps are not allowed to be optional
// --> class/secure_types.baml:19
// |
// 18 | p string[]?
// 19 | q map<string, string>?
// |
4 changes: 2 additions & 2 deletions engine/baml-lib/schema-ast/src/parser/datamodel.pest
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ base_type_with_attr = { base_type ~ (NEWLINE? ~ field_attribute)* }
base_type = { array_notation | map | identifier | group | tuple | parenthesized_type | literal_type }

array_suffix = { "[]" }
array_notation = { base_type_without_array ~ array_suffix+ }
array_notation = { base_type_without_array ~ array_suffix+ ~ optional_token? }

map = { "map" ~ "<" ~ field_type ~ "," ~ field_type ~ ">" }
map = { "map" ~ "<" ~ field_type ~ "," ~ field_type ~ ">" ~ optional_token? }

openParan = { "(" }
closeParan = { ")" }
Expand Down
Loading

0 comments on commit 855893f

Please sign in to comment.