diff --git a/examples/pydantic-models-to-grammar-examples.py b/examples/pydantic-models-to-grammar-examples.py new file mode 100644 index 000000000..a2a0908d2 --- /dev/null +++ b/examples/pydantic-models-to-grammar-examples.py @@ -0,0 +1,100 @@ +# Function calling example using pydantic models. + +import json +from enum import Enum +from typing import Union + +import requests +from pydantic import BaseModel, Field + +from pydantic_models_to_grammar import generate_gbnf_grammar_and_documentation + + +# Function to get completion on the llama.cpp server with grammar. +def create_completion(prompt, grammar): + headers = {"Content-Type": "application/json"} + data = {"prompt": prompt, "grammar": grammar} + + response = requests.post("http://127.0.0.1:8080/completion", headers=headers, json=data) + data = response.json() + + print(data["content"]) + return data["content"] + + +# A function for the agent to send a message to the user. +class SendMessageToUser(BaseModel): + """ + Send a message to the User. + """ + chain_of_thought: str = Field(..., description="Your chain of thought while sending the message.") + message: str = Field(..., description="Message you want to send to the user.") + + def run(self): + print(self.message) + + +# Enum for the calculator function. +class MathOperation(Enum): + ADD = "add" + SUBTRACT = "subtract" + MULTIPLY = "multiply" + DIVIDE = "divide" + + +# Very simple calculator tool for the agent. +class Calculator(BaseModel): + """ + Perform a math operation on two numbers. + """ + number_one: Union[int, float] = Field(..., description="First number.") + operation: MathOperation = Field(..., description="Math operation to perform.") + number_two: Union[int, float] = Field(..., description="Second number.") + + def run(self): + if self.operation == MathOperation.ADD: + return self.number_one + self.number_two + elif self.operation == MathOperation.SUBTRACT: + return self.number_one - self.number_two + elif self.operation == MathOperation.MULTIPLY: + return self.number_one * self.number_two + elif self.operation == MathOperation.DIVIDE: + return self.number_one / self.number_two + else: + raise ValueError("Unknown operation.") + + +# Here the grammar gets generated by passing the available function models to generate_gbnf_grammar_and_documentation function. This also generates a documentation usable by the LLM. +# pydantic_model_list is the list of pydanitc models +# outer_object_name is an optional name for an outer object around the actual model object. Like a "function" object with "function_parameters" which contains the actual model object. If None, no outer object will be generated +# outer_object_content is the name of outer object content. +# model_prefix is the optional prefix for models in the documentation. (Default="Output Model") +# fields_prefix is the prefix for the model fields in the documentation. (Default="Output Fields") +gbnf_grammar, documentation = generate_gbnf_grammar_and_documentation( + pydantic_model_list=[SendMessageToUser, Calculator], outer_object_name="function", + outer_object_content="function_parameters", model_prefix="Function", fields_prefix="Parameters") + +print(gbnf_grammar) +print(documentation) + +system_message = "You are an advanced AI, tasked to assist the user by calling functions in JSON format. The following are the available functions and their parameters and types:\n\n" + documentation + +user_message = "What is 42 * 42?" +prompt = f"<|im_start|>system\n{system_message}<|im_end|>\n<|im_start|>user\n{user_message}<|im_end|>\n<|im_start|>assistant" + +text = create_completion(prompt=prompt, grammar=gbnf_grammar) +# This should output something like this: +# { +# "function": "calculator", +# "function_parameters": { +# "number_one": 42, +# "operation": "multiply", +# "number_two": 42 +# } +# } +function_dictionary = json.loads(text) +if function_dictionary["function"] == "calculator": + function_parameters = {**function_dictionary["function_parameters"]} + + print(Calculator(**function_parameters).run()) + # This should output: 1764 diff --git a/examples/pydantic-models-to-grammar.py b/examples/pydantic_models_to_grammar.py similarity index 84% rename from examples/pydantic-models-to-grammar.py rename to examples/pydantic_models_to_grammar.py index acd183835..1bdd79198 100644 --- a/examples/pydantic-models-to-grammar.py +++ b/examples/pydantic_models_to_grammar.py @@ -26,6 +26,8 @@ class PydanticDataType(Enum): CUSTOM_CLASS (str): Represents a custom class data type. """ STRING = "string" + TRIPLE_QUOTED_STRING = "triple_quoted_string" + MARKDOWN_STRING = "markdown_string" BOOLEAN = "boolean" INTEGER = "integer" FLOAT = "float" @@ -156,12 +158,12 @@ def generate_gbnf_integer_rules(max_digit=None, min_digit=None): Generates GBNF (Generalized Backus-Naur Form) rules for integers based on the given maximum and minimum digits. Parameters: - - max_digit (int): The maximum number of digits for the integer. Default is None. - - min_digit (int): The minimum number of digits for the integer. Default is None. + max_digit (int): The maximum number of digits for the integer. Default is None. + min_digit (int): The minimum number of digits for the integer. Default is None. Returns: - - integer_rule (str): The identifier for the integer rule generated. - - additional_rules (list): A list of additional rules generated based on the given maximum and minimum digits. + integer_rule (str): The identifier for the integer rule generated. + additional_rules (list): A list of additional rules generated based on the given maximum and minimum digits. """ additional_rules = [] @@ -362,7 +364,15 @@ def generate_gbnf_rule_for_type(model_name, look_for_markdown_code_block, look_f else: gbnf_type = f"{model_name}-{field_name}-union" elif isclass(field_type) and issubclass(field_type, str): - if field_info and hasattr(field_info, 'pattern'): + if field_info and hasattr(field_info, 'json_schema_extra') and field_info.json_schema_extra is not None: + + triple_quoted_string = field_info.json_schema_extra.get('triple_quoted_string', False) + markdown_string = field_info.json_schema_extra.get('markdown_string', False) + + gbnf_type = PydanticDataType.TRIPLE_QUOTED_STRING.value if triple_quoted_string else PydanticDataType.STRING.value + gbnf_type = PydanticDataType.MARKDOWN_STRING.value if markdown_string else gbnf_type + + elif field_info and hasattr(field_info, 'pattern'): # Convert regex pattern to grammar rule regex_pattern = field_info.regex.pattern gbnf_type = f"pattern-{field_name} ::= {regex_to_gbnf(regex_pattern)}" @@ -396,7 +406,6 @@ def generate_gbnf_rule_for_type(model_name, look_for_markdown_code_block, look_f # Generate GBNF rule for integer with given attributes gbnf_type, rules = generate_gbnf_integer_rules(max_digit=max_digits, min_digit=min_digits) - else: gbnf_type, rules = gbnf_type, [] @@ -407,8 +416,7 @@ def generate_gbnf_rule_for_type(model_name, look_for_markdown_code_block, look_f return gbnf_type, rules -def generate_gbnf_grammar(model: Type[BaseModel], look_for_markdown_code_block, look_for_triple_quoted_string, - processed_models: set, created_rules: dict) -> list: +def generate_gbnf_grammar(model: Type[BaseModel], processed_models: set, created_rules: dict) -> (list, bool, bool): """ Generate GBnF Grammar @@ -420,8 +428,7 @@ def generate_gbnf_grammar(model: Type[BaseModel], look_for_markdown_code_block, :param look_for_triple_quoted_string :param processed_models: A set of already processed models to prevent infinite recursion. :param created_rules: A dict containing already created rules to prevent duplicates. - :return: A list of GBnF grammar rules in string format. - + :return: A list of GBnF grammar rules in string format. And two booleans indicating if an extra markdown or triple quoted string is in the grammar. Example Usage: ``` model = MyModel @@ -454,6 +461,8 @@ def generate_gbnf_grammar(model: Type[BaseModel], look_for_markdown_code_block, nested_rules = [] has_markdown_code_block = False has_triple_quoted_string = False + look_for_markdown_code_block = False + look_for_triple_quoted_string = False for field_name, field_info in model_fields.items(): if not issubclass(model, BaseModel): field_type, default_value = field_info @@ -468,17 +477,16 @@ def generate_gbnf_grammar(model: Type[BaseModel], look_for_markdown_code_block, format_model_and_field_name(field_name), field_type, is_optional, processed_models, created_rules, field_info) - if ((look_for_markdown_code_block and field_name != "markdown_code_block") or ( - not look_for_markdown_code_block)) and ( - (look_for_triple_quoted_string and field_name != "triple_quoted_string") or ( - not look_for_triple_quoted_string)): + look_for_markdown_code_block = True if rule_name == "markdown_string" else False + look_for_triple_quoted_string = True if rule_name == "triple_quoted_string" else False + if not look_for_markdown_code_block and not look_for_triple_quoted_string: if rule_name not in created_rules: created_rules[rule_name] = additional_rules model_rule_parts.append(f' ws \"\\\"{field_name}\\\"\" ": " {rule_name}') # Adding escaped quotes nested_rules.extend(additional_rules) else: - has_triple_quoted_string = look_for_triple_quoted_string and field_name == "triple_quoted_string" and look_for_triple_quoted_string - has_markdown_code_block = look_for_markdown_code_block and field_name == "markdown_code_block" and look_for_markdown_code_block + has_triple_quoted_string = look_for_markdown_code_block + has_markdown_code_block = look_for_triple_quoted_string fields_joined = r' "," "\n" '.join(model_rule_parts) model_rule = fr'{model_name} ::= "{{" "\n" {fields_joined} "\n" ws "}}"' @@ -492,12 +500,11 @@ def generate_gbnf_grammar(model: Type[BaseModel], look_for_markdown_code_block, model_rule += '"\\n" markdown-code-block' all_rules = [model_rule] + nested_rules - return all_rules + return all_rules, has_markdown_code_block, has_triple_quoted_string -def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], look_for_markdown_code_block=False, - look_for_triple_quoted_string=False, root_rule_class: str = None, - root_rule_content: str = None, list_of_outputs: bool = False) -> str: +def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], outer_object_name: str = None, + outer_object_content: str = None, list_of_outputs: bool = False) -> str: """ Generate GBNF Grammar from Pydantic Models. @@ -505,14 +512,12 @@ def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], lo * grammar. Parameters: - - models (List[Type[BaseModel]]): A list of Pydantic models to generate the grammar from. - - look_for_markdown_code_block (bool, optional): Whether to look for Markdown code blocks in the models. If set to True, the generated grammar will have a rule for Markdown code blocks. - - look_for_triple_quoted_string - - root_rule_class (str, optional): The name of the root model class. If provided, the generated grammar will have a root rule that matches the specified class. Default is None. - - root_rule_content (str, optional): The content of the root model rule. This can be used to specify additional constraints or transformations for the root model. Default is None. - + models (List[Type[BaseModel]]): A list of Pydantic models to generate the grammar from. + outer_object_name (str): Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. + outer_object_content (str): Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. + list_of_outputs (str, optional): Allows a list of output objects Returns: - - str: The generated GBNF grammar string. + str: The generated GBNF grammar string. Examples: models = [UserModel, PostModel] @@ -525,11 +530,11 @@ def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], lo processed_models = set() all_rules = [] created_rules = {} - if root_rule_class is None: + if outer_object_name is None: for model in models: - model_rules = generate_gbnf_grammar(model, look_for_markdown_code_block, look_for_triple_quoted_string, - processed_models, created_rules) + model_rules, _, _ = generate_gbnf_grammar(model, + processed_models, created_rules) all_rules.extend(model_rules) if list_of_outputs: @@ -540,12 +545,14 @@ def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], lo [format_model_and_field_name(model.__name__) for model in models]) all_rules.insert(0, root_rule) return "\n".join(all_rules) - elif root_rule_class is not None: - root_rule = f"root ::= {format_model_and_field_name(root_rule_class)}\n" + elif outer_object_name is not None: + if list_of_outputs: + root_rule = fr'root ::= ws "[" {format_model_and_field_name(outer_object_name)} ("," {format_model_and_field_name(outer_object_name)})* "]"' + "\n" + else: + root_rule = f"root ::= {format_model_and_field_name(outer_object_name)}\n" + + model_rule = fr'{format_model_and_field_name(outer_object_name)} ::= ws "{{" ws "\"{outer_object_name}\"" ": " grammar-models' - model_rule = fr'{format_model_and_field_name(root_rule_class)} ::= ws "{{" ws "\"{root_rule_class}\"" ": " grammar-models' - if not look_for_markdown_code_block and not look_for_triple_quoted_string: - model_rule += ' ws "}"' fields_joined = " | ".join( [fr'{format_model_and_field_name(model.__name__)}-grammar-model' for model in models]) @@ -553,13 +560,23 @@ def generate_gbnf_grammar_from_pydantic_models(models: List[Type[BaseModel]], lo mod_rules = [] for model in models: mod_rule = fr'{format_model_and_field_name(model.__name__)}-grammar-model ::= ws' - mod_rule += fr'"\"{format_model_and_field_name(model.__name__)}\"" "," ws "\"{root_rule_content}\"" ws ":" ws {format_model_and_field_name(model.__name__)}' + '\n' + mod_rule += fr'"\"{format_model_and_field_name(model.__name__)}\"" "," ws "\"{outer_object_content}\"" ws ":" ws {format_model_and_field_name(model.__name__)}' + '\n' mod_rules.append(mod_rule) grammar_model_rules += "\n" + "\n".join(mod_rules) + look_for_markdown_code_block = False + look_for_triple_quoted_string = False for model in models: - model_rules = generate_gbnf_grammar(model, look_for_markdown_code_block, look_for_triple_quoted_string, - processed_models, created_rules) + model_rules, markdown_block, triple_quoted_string = generate_gbnf_grammar(model, + processed_models, created_rules) all_rules.extend(model_rules) + if markdown_block: + look_for_markdown_code_block = True + + if triple_quoted_string: + look_for_triple_quoted_string = True + + if not look_for_markdown_code_block and not look_for_triple_quoted_string: + model_rule += ' ws "}"' all_rules.insert(0, root_rule + model_rule + grammar_model_rules) return "\n".join(all_rules) @@ -569,10 +586,10 @@ def get_primitive_grammar(grammar): Returns the needed GBNF primitive grammar for a given GBNF grammar string. Args: - - grammar (str): The string containing the GBNF grammar. + grammar (str): The string containing the GBNF grammar. Returns: - - str: GBNF primitive grammar string. + str: GBNF primitive grammar string. """ type_list = [] if "string-list" in grammar: @@ -676,11 +693,11 @@ def format_json_example(example: dict, depth: int) -> str: Format a JSON example into a readable string with indentation. Args: - - example (dict): JSON example to be formatted. - - depth (int): Indentation depth. + example (dict): JSON example to be formatted. + depth (int): Indentation depth. Returns: - - str: Formatted JSON example string. + str: Formatted JSON example string. """ indent = ' ' * depth formatted_example = '{\n' @@ -697,13 +714,13 @@ def generate_text_documentation(pydantic_models: List[Type[BaseModel]], model_pr Generate text documentation for a list of Pydantic models. Args: - - pydantic_models (List[Type[BaseModel]]): List of Pydantic model classes. - - model_prefix (str): Prefix for the model section. - - fields_prefix (str): Prefix for the fields section. - - documentation_with_field_description (bool): Include field descriptions in the documentation. + pydantic_models (List[Type[BaseModel]]): List of Pydantic model classes. + model_prefix (str): Prefix for the model section. + fields_prefix (str): Prefix for the fields section. + documentation_with_field_description (bool): Include field descriptions in the documentation. Returns: - - str: Generated text documentation. + str: Generated text documentation. """ documentation = "" pyd_models = [(model, True) for model in pydantic_models] @@ -759,14 +776,14 @@ def generate_field_text(field_name: str, field_type: Type[Any], model: Type[Base Generate text documentation for a Pydantic model field. Args: - - field_name (str): Name of the field. - - field_type (Type[Any]): Type of the field. - - model (Type[BaseModel]): Pydantic model class. - - depth (int): Indentation depth in the documentation. - - documentation_with_field_description (bool): Include field descriptions in the documentation. + field_name (str): Name of the field. + field_type (Type[Any]): Type of the field. + model (Type[BaseModel]): Pydantic model class. + depth (int): Indentation depth in the documentation. + documentation_with_field_description (bool): Include field descriptions in the documentation. Returns: - - str: Generated text documentation for the field. + str: Generated text documentation for the field. """ indent = ' ' * depth @@ -824,11 +841,11 @@ def format_multiline_description(description: str, indent_level: int) -> str: Format a multiline description with proper indentation. Args: - - description (str): Multiline description. - - indent_level (int): Indentation level. + description (str): Multiline description. + indent_level (int): Indentation level. Returns: - - str: Formatted multiline description. + str: Formatted multiline description. """ indent = ' ' * indent_level return indent + description.replace('\n', '\n' + indent) @@ -840,13 +857,13 @@ def save_gbnf_grammar_and_documentation(grammar, documentation, grammar_file_pat Save GBNF grammar and documentation to specified files. Args: - - grammar (str): GBNF grammar string. - - documentation (str): Documentation string. - - grammar_file_path (str): File path to save the GBNF grammar. - - documentation_file_path (str): File path to save the documentation. + grammar (str): GBNF grammar string. + documentation (str): Documentation string. + grammar_file_path (str): File path to save the GBNF grammar. + documentation_file_path (str): File path to save the documentation. Returns: - - None + None """ try: with open(grammar_file_path, 'w') as file: @@ -868,10 +885,10 @@ def remove_empty_lines(string): Remove empty lines from a string. Args: - - string (str): Input string. + string (str): Input string. Returns: - - str: String with empty lines removed. + str: String with empty lines removed. """ lines = string.splitlines() non_empty_lines = [line for line in lines if line.strip() != ""] @@ -879,11 +896,11 @@ def remove_empty_lines(string): return string_no_empty_lines -def generate_and_save_gbnf_grammar_and_documentation(pydantic_model_list, look_for_markdown_code_block=False, - look_for_triple_quoted_string=False, +def generate_and_save_gbnf_grammar_and_documentation(pydantic_model_list, grammar_file_path="./generated_grammar.gbnf", documentation_file_path="./generated_grammar_documentation.md", - root_rule_class: str = None, root_rule_content: str = None, + outer_object_name: str = None, + outer_object_content: str = None, model_prefix: str = "Output Model", fields_prefix: str = "Output Fields", list_of_outputs: bool = False, @@ -892,33 +909,29 @@ def generate_and_save_gbnf_grammar_and_documentation(pydantic_model_list, look_f Generate GBNF grammar and documentation, and save them to specified files. Args: - - pydantic_model_list: List of Pydantic model classes. - - look_for_markdown_code_block (bool): Whether to look for markdown code blocks in field descriptions. - - look_for_triple_quoted_string (bool): Whether to look for triple-quoted strings in field descriptions. - - grammar_file_path (str): File path to save the generated GBNF grammar. - - documentation_file_path (str): File path to save the generated documentation. - - root_rule_class (str): Root rule class for the GBNF grammar. - - root_rule_content (str): Content for the root rule in the GBNF grammar. - - model_prefix (str): Prefix for the model section in the documentation. - - fields_prefix (str): Prefix for the fields section in the documentation. - - list_of_outputs (bool): Whether the output is a list of items. - - documentation_with_field_description (bool): Include field descriptions in the documentation. + pydantic_model_list: List of Pydantic model classes. + grammar_file_path (str): File path to save the generated GBNF grammar. + documentation_file_path (str): File path to save the generated documentation. + outer_object_name (str): Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. + outer_object_content (str): Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. + model_prefix (str): Prefix for the model section in the documentation. + fields_prefix (str): Prefix for the fields section in the documentation. + list_of_outputs (bool): Whether the output is a list of items. + documentation_with_field_description (bool): Include field descriptions in the documentation. Returns: - - None + None """ documentation = generate_text_documentation(pydantic_model_list, model_prefix, fields_prefix, documentation_with_field_description=documentation_with_field_description) - grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, look_for_markdown_code_block, - look_for_triple_quoted_string, root_rule_class, - root_rule_content, list_of_outputs) + grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, outer_object_name, + outer_object_content, list_of_outputs) grammar = remove_empty_lines(grammar) save_gbnf_grammar_and_documentation(grammar, documentation, grammar_file_path, documentation_file_path) -def generate_gbnf_grammar_and_documentation(pydantic_model_list, look_for_markdown_code_block=False, - look_for_triple_quoted_string=False, root_rule_class: str = None, - root_rule_content: str = None, +def generate_gbnf_grammar_and_documentation(pydantic_model_list, outer_object_name: str = None, + outer_object_content: str = None, model_prefix: str = "Output Model", fields_prefix: str = "Output Fields", list_of_outputs: bool = False, documentation_with_field_description=True): @@ -926,33 +939,28 @@ def generate_gbnf_grammar_and_documentation(pydantic_model_list, look_for_markdo Generate GBNF grammar and documentation for a list of Pydantic models. Args: - - pydantic_model_list: List of Pydantic model classes. - - look_for_markdown_code_block (bool): Whether to look for markdown code blocks in field descriptions. - - look_for_triple_quoted_string (bool): Whether to look for triple-quoted strings in field descriptions. - - root_rule_class (str): Root rule class for the GBNF grammar. - - root_rule_content (str): Content for the root rule in the GBNF grammar. - - model_prefix (str): Prefix for the model section in the documentation. - - fields_prefix (str): Prefix for the fields section in the documentation. - - list_of_outputs (bool): Whether the output is a list of items. - - documentation_with_field_description (bool): Include field descriptions in the documentation. + pydantic_model_list: List of Pydantic model classes. + outer_object_name (str): Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. + outer_object_content (str): Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. + model_prefix (str): Prefix for the model section in the documentation. + fields_prefix (str): Prefix for the fields section in the documentation. + list_of_outputs (bool): Whether the output is a list of items. + documentation_with_field_description (bool): Include field descriptions in the documentation. Returns: - - tuple: GBNF grammar string, documentation string. + tuple: GBNF grammar string, documentation string. """ documentation = generate_text_documentation(copy(pydantic_model_list), model_prefix, fields_prefix, documentation_with_field_description=documentation_with_field_description) - grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, look_for_markdown_code_block, - look_for_triple_quoted_string, root_rule_class, - root_rule_content, list_of_outputs) + grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, outer_object_name, + outer_object_content, list_of_outputs) grammar = remove_empty_lines(grammar + get_primitive_grammar(grammar)) return grammar, documentation def generate_gbnf_grammar_and_documentation_from_dictionaries(dictionaries: List[dict], - look_for_markdown_code_block=False, - look_for_triple_quoted_string=False, - root_rule_class: str = None, - root_rule_content: str = None, + outer_object_name: str = None, + outer_object_content: str = None, model_prefix: str = "Output Model", fields_prefix: str = "Output Fields", list_of_outputs: bool = False, @@ -961,25 +969,22 @@ def generate_gbnf_grammar_and_documentation_from_dictionaries(dictionaries: List Generate GBNF grammar and documentation from a list of dictionaries. Args: - - dictionaries (List[dict]): List of dictionaries representing Pydantic models. - - look_for_markdown_code_block (bool): Whether to look for markdown code blocks in field descriptions. - - look_for_triple_quoted_string (bool): Whether to look for triple-quoted strings in field descriptions. - - root_rule_class (str): Root rule class for the GBNF grammar. - - root_rule_content (str): Content for the root rule in the GBNF grammar. - - model_prefix (str): Prefix for the model section in the documentation. - - fields_prefix (str): Prefix for the fields section in the documentation. - - list_of_outputs (bool): Whether the output is a list of items. - - documentation_with_field_description (bool): Include field descriptions in the documentation. + dictionaries (List[dict]): List of dictionaries representing Pydantic models. + outer_object_name (str): Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. + outer_object_content (str): Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. + model_prefix (str): Prefix for the model section in the documentation. + fields_prefix (str): Prefix for the fields section in the documentation. + list_of_outputs (bool): Whether the output is a list of items. + documentation_with_field_description (bool): Include field descriptions in the documentation. Returns: - - tuple: GBNF grammar string, documentation string. + tuple: GBNF grammar string, documentation string. """ pydantic_model_list = create_dynamic_models_from_dictionaries(dictionaries) documentation = generate_text_documentation(copy(pydantic_model_list), model_prefix, fields_prefix, documentation_with_field_description=documentation_with_field_description) - grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, look_for_markdown_code_block, - look_for_triple_quoted_string, root_rule_class, - root_rule_content, list_of_outputs) + grammar = generate_gbnf_grammar_from_pydantic_models(pydantic_model_list, outer_object_name, + outer_object_content, list_of_outputs) grammar = remove_empty_lines(grammar + get_primitive_grammar(grammar)) return grammar, documentation @@ -1145,3 +1150,6 @@ def convert_dictionary_to_to_pydantic_model(dictionary: dict, model_name: str = custom_model = create_model(model_name, **fields) return custom_model + + +