Utilities API
Helpers for prompt construction, JSON-schema and grammar generation, LLM-facing documentation, chat persistence and logging.
Message Template
Fills {placeholder} fields in a prompt string. Used by pipeline steps to turn
a prompt_template into the actual prompt.
from ToolAgents.utilities.message_template import MessageTemplate
template = MessageTemplate.from_string("Hello {name}, welcome to {place}.")
template.generate_message_content(name="Max", place="Königswinter")
Placeholder paths
A placeholder may address a nested value with /:
template = MessageTemplate.from_string("Revise {outputs/draft} for {inputs/audience}")
template.generate_message_content(results)
This works against any nested mapping, and against a
PipelineResults object, which resolves the first
segment as a section name.
Pass the mapping; do not unpack it
Path resolution needs the structure intact.
generate_message_content(results) resolves {outputs/draft};
generate_message_content(**results) flattens the mapping first and the
path can no longer resolve. Mixing template_fields with keyword arguments
flattens too.
Unmatched placeholders
- A bare name with no matching field is blanked, and a line containing
nothing else is dropped (
remove_empty_template_field=True, the default). This is deliberate for optional sections of a prompt, but it means a typo in a bare placeholder fails silently. - A path that does not resolve is left verbatim, so text that was always
literal —
{a/b}— survives, and a mistyped path stays visible. - A field whose value is
Nonecounts as absent and is blanked, rather than rendering the literal string"None".
Set remove_empty_template_field=False to leave every unmatched placeholder in
the output.
Behaviour change in 0.3.3
Two things about placeholder handling changed in 0.3.3, when path support was added. Neither breaks a template that was previously working, but both are worth knowing before upgrading.
Placeholder names may now contain /. The pattern widened from
\{(\w+)\} to \{([\w/]+)\}. Text that was always literal is unaffected:
a placeholder containing / that does not resolve is left exactly as
written, so {a/b} in an existing prompt still renders as {a/b}.
A None value now counts as absent. Previously a field set to None
rendered the literal string "None" into the prompt; it is now blanked
like any other missing field. This is the one case where output changes for
an unmodified template. If you were relying on the old behaviour, pass the
string yourself:
MessageTemplate
A prompt template with {placeholder} fields.
Build one with :meth:from_string or :meth:from_file, then fill it with
:meth:generate_message_content. A placeholder may address a nested value
with /, as in {outputs/draft}.
Attributes:
| Name | Type | Description |
|---|---|---|
template |
str
|
The template string containing placeholders. |
Initialize a PromptTemplate instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template_file
|
str
|
The path to a file containing the template. |
None
|
template_string
|
str
|
The template string. |
None
|
from_string
classmethod
from_string(template_string) -> MessageTemplate
Create a PromptTemplate instance from a string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template_string
|
str
|
The template string. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
PromptTemplate |
MessageTemplate
|
Created PromptTemplate instance. |
from_file
classmethod
from_file(template_file) -> MessageTemplate
Create a PromptTemplate instance from a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template_file
|
str
|
The path to a file containing the template. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
PromptTemplate |
MessageTemplate
|
Created PromptTemplate instance. |
generate_message_content
generate_message_content(
template_fields: Dict[str, Any] = None,
remove_empty_template_field: bool = True,
**kwargs: Any
) -> str
Generate a prompt by replacing placeholders in the template with values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template_fields
|
Dict[str, Any]
|
The template fields as a dictionary. |
None
|
remove_empty_template_field
|
bool
|
If True, removes lines with empty placeholders. |
True
|
**kwargs
|
Any
|
Additional keyword arguments to be used as template fields. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The generated prompt. |
resolve_template_path
Resolve a possibly-sectioned path against a mapping.
Returns (found, value). A mapping that knows its own sections — such
as PipelineResults — resolves the path itself; anything else is walked
as nested mappings, so a plain dict of dicts works too.
Prompt Builder
A fluent builder for multi-part prompts.
PromptPart
Bases: ABC
JSON Schema Generation
custom_json_schema is the entry point: it produces a fully $ref-resolved
schema for a Pydantic model, which is what tool definitions are built from.
custom_json_schema
Generate a custom JSON schema for a given Pydantic model. All $refs are resolved inline for a fully expanded schema.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Type[BaseModel]
|
The Pydantic BaseModel class |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A fully resolved JSON schema dict |
get_tools_schema
Generate a combined schema for all tools in a tool registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_registry
|
Any
|
Object with a 'tools' dict attribute |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
Dict[str, Any]: Combined JSON schema for all tools as an array |
refine_schema
Refine the generated schema based on the model's annotations and field details. Recursively handles Enums, Unions, lists/sets, dictionaries, and nested Pydantic models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
dict
|
The base schema dict from model.model_json_schema() |
required |
model
|
Type[BaseModel]
|
The Pydantic model class |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Refined schema dict with all $refs resolved |
insert_additional_fields
insert_additional_fields(
schema: dict,
additional_fields: List[AdditionalSchemaField],
) -> dict
Insert additional fields into the schema's properties. Fields with position 'before' will be added at the start, and those with 'after' will be appended at the end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
dict
|
The schema dict to modify |
required |
additional_fields
|
List[AdditionalSchemaField]
|
List of additional fields to insert |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Modified schema dict |
AdditionalSchemaField
Bases: BaseModel
Represents an additional schema field.
AdditionalFieldPosition
Bases: Enum
GBNF Grammar Generation
Constrained-decoding grammars for local inference backends such as llama.cpp, generated from Pydantic models.
generate_gbnf_grammar_and_documentation
generate_gbnf_grammar_and_documentation(
pydantic_model_list: List[Type[BaseModel]],
outer_object_name: str | None = None,
outer_object_content: str | None = None,
model_prefix: str = "Output Model",
fields_prefix: str = "Output Fields",
list_of_outputs: bool = False,
documentation_with_field_description=True,
add_inner_thoughts: bool = False,
allow_only_inner_thoughts: bool = False,
inner_thoughts_field_name: str = "thoughts_and_reasoning",
add_request_heartbeat: bool = False,
request_heartbeat_field_name: str = "request_heartbeat",
request_heartbeat_models: List[str] = None,
) -> Tuple[str, str]
Generate GBNF grammar and documentation for a list of Pydantic models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pydantic_model_list
|
List[Type[BaseModel]]
|
List of Pydantic model classes. |
required |
outer_object_name
|
str
|
Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. |
None
|
outer_object_content
|
str
|
Content for the outer rule in the GBNF grammar. E.g., "function_parameters" or "params" for function calling. |
None
|
model_prefix
|
str
|
Prefix for the model section in the documentation. |
'Output Model'
|
fields_prefix
|
str
|
Prefix for the fields section in the documentation. |
'Output Fields'
|
list_of_outputs
|
bool
|
Whether the output is a list of items. |
False
|
documentation_with_field_description
|
bool
|
Include field descriptions in the documentation. |
True
|
add_inner_thoughts
|
bool
|
Add inner thoughts to the grammar. This is useful for adding comments or reasoning to the output. |
False
|
allow_only_inner_thoughts
|
bool
|
Allow only inner thoughts. If True, only inner thoughts will be allowed in the output. |
False
|
inner_thoughts_field_name
|
str
|
Field name for inner thoughts. Default is "thoughts_and_reasoning". |
'thoughts_and_reasoning'
|
add_request_heartbeat
|
bool
|
Add request heartbeat to the grammar. This allows the LLM to decide when to return control to the system. |
False
|
request_heartbeat_field_name
|
str
|
Field name for request heartbeat. Default is "request_heartbeat". |
'request_heartbeat'
|
request_heartbeat_models
|
List[str]
|
List of models that will have a request heartbeat field. |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[str, str]
|
Tuple[str, str]: GBNF grammar string, documentation string. |
generate_gbnf_grammar_from_pydantic_models
generate_gbnf_grammar_from_pydantic_models(
models: list[BaseModel],
outer_object_name: str | None = None,
outer_object_content: str | None = None,
list_of_outputs: bool = False,
add_inner_thoughts: bool = True,
allow_only_inner_thoughts: bool = True,
inner_thought_field_name: str = "chain_of_thought",
add_request_heartbeat: bool = True,
request_heartbeat_field_name: str = "request_heartbeat",
request_heartbeat_models: list[str] = None,
) -> str
Generate GBNF Grammar from Pydantic Models.
This method takes a list of Pydantic models and uses them to generate a GBNF grammar string. The generated grammar string can be used for parsing and validating data using the generated * grammar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
models
|
list[type[BaseModel]]
|
A list of Pydantic models to generate the grammar from. |
required |
outer_object_name
|
str
|
Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. |
None
|
outer_object_content
|
str
|
Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. |
None
|
list_of_outputs
|
str
|
Allows a list of output objects |
False
|
add_inner_thoughts
|
bool
|
Add inner thoughts to the grammar. Defaults to True. |
True
|
allow_only_inner_thoughts
|
bool
|
Allow only inner thoughts. Defaults to True. |
True
|
Returns: str: The generated GBNF grammar string.
Examples:
models = [UserModel, PostModel] grammar = generate_gbnf_grammar_from_pydantic(models) print(grammar)
Output:
root ::= UserModel | PostModel
...
generate_gbnf_grammar_and_documentation_from_dictionaries
generate_gbnf_grammar_and_documentation_from_dictionaries(
dictionaries: list[dict[str, Any]],
outer_object_name: str | None = None,
outer_object_content: str | None = None,
model_prefix: str = "Output Model",
fields_prefix: str = "Output Fields",
list_of_outputs: bool = False,
documentation_with_field_description=True,
add_inner_thoughts: bool = False,
allow_only_inner_thoughts: bool = False,
inner_thoughts_field_name: str = "thoughts_and_reasoning",
add_request_heartbeat: bool = False,
request_heartbeat_field_name: str = "request_heartbeat",
request_heartbeat_models: List[str] = None,
) -> Tuple[str, str]
Generate GBNF grammar and documentation from a list of dictionaries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dictionaries
|
list[dict]
|
List of dictionaries representing Pydantic models. |
required |
outer_object_name
|
str
|
Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. |
None
|
outer_object_content
|
str
|
Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. |
None
|
model_prefix
|
str
|
Prefix for the model section in the documentation. |
'Output Model'
|
fields_prefix
|
str
|
Prefix for the fields section in the documentation. |
'Output Fields'
|
list_of_outputs
|
bool
|
Whether the output is a list of items. |
False
|
documentation_with_field_description
|
bool
|
Include field descriptions in the documentation. |
True
|
add_inner_thoughts
|
bool
|
Add inner thoughts to the grammar. This is useful for adding comments or reasoning to the output. |
False
|
allow_only_inner_thoughts
|
bool
|
Allow only inner thoughts. If True, only inner thoughts will be allowed in the output. |
False
|
inner_thoughts_field_name
|
str
|
Field name for inner thoughts. Default is "thoughts_and_reasoning". |
'thoughts_and_reasoning'
|
add_request_heartbeat
|
bool
|
Add request heartbeat to the grammar. This allows the LLM to decide when to return control to the system. |
False
|
request_heartbeat_field_name
|
str
|
Field name for request heartbeat. Default is "request_heartbeat". |
'request_heartbeat'
|
request_heartbeat_models
|
List[str]
|
List of models that will have a request heartbeat field. |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[str, str]
|
Tuple[str, str]: GBNF grammar string, documentation string. |
generate_and_save_gbnf_grammar_and_documentation
generate_and_save_gbnf_grammar_and_documentation(
pydantic_model_list: List[Type[BaseModel]],
grammar_file_path="./generated_grammar.gbnf",
documentation_file_path="./generated_grammar_documentation.md",
outer_object_name: str | None = None,
outer_object_content: str | None = None,
model_prefix: str = "Output Model",
fields_prefix: str = "Output Fields",
list_of_outputs: bool = False,
documentation_with_field_description=True,
add_inner_thoughts: bool = False,
allow_only_inner_thoughts: bool = False,
inner_thoughts_field_name: str = "thoughts_and_reasoning",
add_request_heartbeat: bool = False,
request_heartbeat_field_name: str = "request_heartbeat",
request_heartbeat_models: List[str] = None,
)
Generate GBNF grammar and documentation, and save them to specified files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pydantic_model_list
|
List[Type[BaseModel]]
|
List of Pydantic model classes. |
required |
grammar_file_path
|
str
|
File path to save the generated GBNF grammar. |
'./generated_grammar.gbnf'
|
documentation_file_path
|
str
|
File path to save the generated documentation. |
'./generated_grammar_documentation.md'
|
outer_object_name
|
str
|
Outer object name for the GBNF grammar. If None, no outer object will be generated. Eg. "function" for function calling. |
None
|
outer_object_content
|
str
|
Content for the outer rule in the GBNF grammar. Eg. "function_parameters" or "params" for function calling. |
None
|
model_prefix
|
str
|
Prefix for the model section in the documentation. |
'Output Model'
|
fields_prefix
|
str
|
Prefix for the fields section in the documentation. |
'Output Fields'
|
list_of_outputs
|
bool
|
Whether the output is a list of items. |
False
|
documentation_with_field_description
|
bool
|
Include field descriptions in the documentation. |
True
|
add_inner_thoughts
|
bool
|
Add inner thoughts to the grammar. This is useful for adding comments or reasoning to the output. |
False
|
allow_only_inner_thoughts
|
bool
|
Allow only inner thoughts. If True, only inner thoughts will be allowed in the output. |
False
|
inner_thoughts_field_name
|
str
|
Field name for inner thoughts. Default is "thoughts_and_reasoning". |
'thoughts_and_reasoning'
|
add_request_heartbeat
|
bool
|
Add request heartbeat to the grammar. This allows the LLM to decide when to return control to the system. |
False
|
request_heartbeat_field_name
|
str
|
Field name for request heartbeat. Default is "request_heartbeat". |
'request_heartbeat'
|
request_heartbeat_models
|
List[str]
|
List of models that will have a request heartbeat field. |
None
|
Returns: None
PydanticDataType
Bases: Enum
Defines the data types supported by the grammar_generator.
Attributes:
| Name | Type | Description |
|---|---|---|
STRING |
str
|
Represents a string data type. |
BOOLEAN |
str
|
Represents a boolean data type. |
INTEGER |
str
|
Represents an integer data type. |
FLOAT |
str
|
Represents a float data type. |
OBJECT |
str
|
Represents an object data type. |
ARRAY |
str
|
Represents an array data type. |
ENUM |
str
|
Represents an enum data type. |
CUSTOM_CLASS |
str
|
Represents a custom class data type. |
LLM Documentation
Renders Pydantic models as documentation for the model to read, so a tool's shape can be explained inside a prompt.
generate_markdown_documentation
generate_markdown_documentation(
pydantic_models: list[type[BaseModel]],
model_prefix="Model",
fields_prefix="Fields",
documentation_with_field_description=True,
ordered_json_mode=False,
) -> str
Generate markdown documentation for a list of Pydantic models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pydantic_models
|
list[type[BaseModel]]
|
list of Pydantic model classes. |
required |
model_prefix
|
str
|
Prefix for the model section. |
'Model'
|
fields_prefix
|
str
|
Prefix for the fields section. |
'Fields'
|
documentation_with_field_description
|
bool
|
Include field descriptions in the documentation. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Generated text documentation. |
generate_text_documentation
generate_text_documentation(
pydantic_models: list[BaseModel],
model_prefix="Output Model",
fields_prefix="Fields",
documentation_with_field_description=True,
ordered_json_mode=False,
) -> str
Generate plain-text documentation for a list of Pydantic models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pydantic_models
|
list[type[BaseModel]]
|
list of Pydantic model classes. |
required |
model_prefix
|
str
|
Prefix for the model section. |
'Output Model'
|
fields_prefix
|
str
|
Prefix for the fields section. |
'Fields'
|
documentation_with_field_description
|
bool
|
Include field descriptions in the documentation. |
True
|
ordered_json_mode
|
bool
|
Add ordering prefix for JSON schemas |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Generated text documentation. |
Pydantic Helpers
Note the module name is pydantic_utilites (the spelling in the source).
create_dynamic_model_from_function
create_dynamic_model_from_function(
func: Callable[..., Any],
add_inner_thoughts: bool = False,
inner_thoughts_field_name: str = "inner_thoughts",
) -> type[BaseModel]
Creates a dynamic Pydantic model from a given function's type hints and adds the function as a 'run' method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
A function with type hints from which to create the model. |
required |
add_inner_thoughts
|
bool
|
Add an 'inner_thoughts' field at the params level to the model. Default is False. |
False
|
inner_thoughts_field_name
|
str
|
Field name for inner thoughts. Default is "inner_thoughts". |
'inner_thoughts'
|
Returns:
| Type | Description |
|---|---|
type[BaseModel]
|
type[BaseModel]: A dynamic Pydantic model class with the provided function as a 'run' method. |
pydantic_model_to_openai_function_definition
MCP Schema Conversion
Turns an MCP JSON schema into a Pydantic model, so an MCP tool becomes an
ordinary FunctionTool.
convert_json_schema
Main entry point to convert a JSON schema to a Pydantic model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
dict
|
The JSON schema dictionary |
required |
Returns:
| Type | Description |
|---|---|
type[Any]
|
A Pydantic model class |
convert_schema_to_pydantic_model
convert_schema_to_pydantic_model(
dictionary: dict[str, Any],
model_name: str = "CustomModel",
docs: dict[str, str] = None,
docs_function: dict[str, str] = None,
definitions: dict[str, Any] = None,
created_models: dict[str, Any] = None,
) -> type[Any]
Convert a JSON schema to a Pydantic model, handling complex schema features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dictionary
|
dict[str, Any]
|
The JSON schema dictionary |
required |
model_name
|
str
|
Name for the generated model |
'CustomModel'
|
docs
|
dict[str, str]
|
Documentation for fields |
None
|
docs_function
|
dict[str, str]
|
Function documentation |
None
|
definitions
|
dict[str, Any]
|
Dictionary of schema definitions |
None
|
created_models
|
dict[str, Any]
|
Dictionary of already created models to avoid duplicates |
None
|
Returns:
| Type | Description |
|---|---|
type[Any]
|
A Pydantic model class |
MCP clients moved
ToolAgents.utilities.mcp_session is a compatibility shim. Import MCP
client helpers from ToolAgents.tool_adapters.mcp_client instead.
Chat Persistence
SQLAlchemy-backed chat storage. Requires the storage extra.
ChatManager
add_message
add_message(
chat_id: int, message: ChatMessage
) -> dict[str, Any]
Add a message to a chat.
Chat
Bases: Base
ChatMessageDb
Bases: Base
Logging
EasyLogger
EasyLogger(
name: str = None,
level: int = INFO,
format_string: str = None,
log_to_console: bool = True,
log_to_file: Union[bool, str] = False,
file_mode: str = "a",
)
A simple wrapper around Python's logging library that provides an easy interface for configuration and usage.
Initialize a new EasyLogger instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the logger. If None, uses the root logger. |
None
|
level
|
int
|
The logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). |
INFO
|
format_string
|
str
|
Custom format string for log messages. If None, uses the standard format. |
None
|
log_to_console
|
bool
|
Whether to log to the console. |
True
|
log_to_file
|
Union[bool, str]
|
If True, logs to a file with the same name as the logger. If a string, uses that as the filename. |
False
|
file_mode
|
str
|
File mode for the log file ('a' for append, 'w' for overwrite). |
'a'
|
add_rotating_file_handler
add_rotating_file_handler(
filename: str,
max_bytes: int = 10 * 1024 * 1024,
backup_count: int = 5,
)
Add a size-based rotating file handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
Path to the log file. |
required |
max_bytes
|
int
|
Maximum size of the log file before rotating (default: 10MB). |
10 * 1024 * 1024
|
backup_count
|
int
|
Number of backup files to keep (default: 5). |
5
|
add_timed_rotating_file_handler
Add a time-based rotating file handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
Path to the log file. |
required |
when
|
str
|
When to rotate the log file ('S', 'M', 'H', 'D', 'W0'-'W6', 'midnight'). Default is 'midnight'. |
'midnight'
|
backup_count
|
int
|
Number of backup files to keep (default: 7). |
7
|