Skip to content

Commit

Permalink
Make render messages dynamic and use hoisted_class_prefix instead o…
Browse files Browse the repository at this point in the history
…f `"schema"` (#1155)

<!-- ELLIPSIS_HIDDEN -->



> [!IMPORTANT]
> Add `hoisted_class_prefix` to `RenderOptions` for customizable hoisted
class prefixes in rendered messages.
> 
>   - **Behavior**:
> - `RenderOptions` in `types.rs` now supports `hoisted_class_prefix` to
customize prefix for hoisted classes.
> - Default prefix for hoisted classes changed from "schema" to
user-defined or "interface".
> - Updated rendering logic in `OutputFormatContent` to use
`hoisted_class_prefix`.
>   - **Documentation**:
> - Added `hoisted_class_prefix` parameter to `output-format.mdx` with
examples.
>   - **Tests**:
> - Added tests in `types.rs` to verify `hoisted_class_prefix`
functionality.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral)<sup>
for 6c7c38c. It will automatically
update as commits are pushed.</sup>

<!-- ELLIPSIS_HIDDEN -->
  • Loading branch information
antoniosarosi authored Nov 11, 2024
1 parent cf2298e commit 873751b
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions engine/baml-lib/jinja-runtime/src/output_format/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl Default for RenderOptions {

impl RenderOptions {
const DEFAULT_OR_SPLITTER: &'static str = " or ";
const DEFAULT_TYPE_PREFIX_IN_RENDER_MESSAGE: &'static str = "schema";

pub(crate) fn new(
prefix: Option<Option<String>>,
Expand Down Expand Up @@ -293,38 +294,51 @@ impl OutputFormatContent {
Builder::new(target)
}

fn prefix<'a>(&self, options: &'a RenderOptions) -> Option<&'a str> {
fn prefix<'a>(&self, options: &'a RenderOptions) -> Option<String> {
fn auto_prefix(
ft: &FieldType,
options: &RenderOptions,
output_format_content: &OutputFormatContent,
) -> Option<&'static str> {
) -> Option<String> {
match ft {
FieldType::Primitive(TypeValue::String) => None,
FieldType::Primitive(_) => Some("Answer as a: "),
FieldType::Literal(_) => Some("Answer using this specific value:\n"),
FieldType::Enum(_) => Some("Answer with any of the categories:\n"),
// TODO: Func returns &str we can't format!, do something to
// avoid duplicating the string.
FieldType::Primitive(_) => Some(String::from("Answer as a: ")),
FieldType::Literal(_) => Some(String::from("Answer using this specific value:\n")),
FieldType::Enum(_) => Some(String::from("Answer with any of the categories:\n")),
FieldType::Class(cls) => {
Some(if output_format_content.recursive_classes.contains(cls) {
"Answer in JSON using this schema: "
let type_prefix = match &options.hoisted_class_prefix {
RenderSetting::Always(prefix) if !prefix.is_empty() => prefix,
_ => RenderOptions::DEFAULT_TYPE_PREFIX_IN_RENDER_MESSAGE,
};

// Line break if schema else just inline the name.
let end = if output_format_content.recursive_classes.contains(cls) {
" "
} else {
"Answer in JSON using this schema:\n"
})
"\n"
};

Some(format!("Answer in JSON using this {type_prefix}:{end}"))
}
FieldType::List(_) => Some(String::from(
"Answer with a JSON Array using this schema:\n",
)),
FieldType::Union(_) => {
Some(String::from("Answer in JSON using any of these schemas:\n"))
}
FieldType::List(_) => Some("Answer with a JSON Array using this schema:\n"),
FieldType::Union(_) => Some("Answer in JSON using any of these schemas:\n"),
FieldType::Optional(_) => Some("Answer in JSON using this schema:\n"),
FieldType::Map(_, _) => Some("Answer in JSON using this schema:\n"),
FieldType::Optional(_) => Some(String::from("Answer in JSON using this schema:\n")),
FieldType::Map(_, _) => Some(String::from("Answer in JSON using this schema:\n")),
FieldType::Tuple(_) => None,
FieldType::Constrained { base, .. } => auto_prefix(base, output_format_content),
FieldType::Constrained { base, .. } => {
auto_prefix(base, options, output_format_content)
}
}
}

match &options.prefix {
RenderSetting::Always(prefix) => Some(prefix.as_str()),
RenderSetting::Always(prefix) => Some(prefix.to_owned()),
RenderSetting::Never => None,
RenderSetting::Auto => auto_prefix(&self.target, self),
RenderSetting::Auto => auto_prefix(&self.target, options, self),
}
}

Expand Down Expand Up @@ -587,7 +601,7 @@ impl OutputFormatContent {
}

if let Some(p) = prefix {
output.push_str(p);
output.push_str(&p);
}

if let Some(m) = message {
Expand Down Expand Up @@ -1662,7 +1676,7 @@ interface C {
pointer: A or null,
}
Answer in JSON using this schema:
Answer in JSON using this interface:
{
pointer: A,
data: int,
Expand Down

0 comments on commit 873751b

Please sign in to comment.