Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions libs/core/langchain_core/prompts/few_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ def is_lc_serializable(cls) -> bool:
prefix: str = ""
"""A prompt template string to put before the examples."""

template_format: Literal["f-string", "jinja2"] = "f-string"
"""The format of the prompt template. Options are: 'f-string', 'jinja2'."""
template_format: Literal["f-string", "jinja2", "jinja2_unrestricted"] = "f-string"
"""The format of the prompt template. Options are: 'f-string', 'jinja2',
'jinja2_unrestricted'."""

def __init__(self, **kwargs: Any) -> None:
"""Initialize the few shot prompt template."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FewShotPromptWithTemplates(StringPromptTemplate):

template_format: PromptTemplateFormat = "f-string"
"""The format of the prompt template.
Options are: 'f-string', 'jinja2', 'mustache'."""
Options are: 'f-string', 'jinja2', 'jinja2_unrestricted', 'mustache'."""

validate_template: bool = False
"""Whether or not to try validating the template."""
Expand Down
2 changes: 1 addition & 1 deletion libs/core/langchain_core/prompts/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
"""Template for the prompt."""
template_format: PromptTemplateFormat = "f-string"
"""The format of the prompt template.
Options are: 'f-string', 'mustache', 'jinja2'."""
Options are: 'f-string', 'mustache', 'jinja2', 'jinja2_unrestricted'."""

def __init__(self, **kwargs: Any) -> None:
"""Create an image prompt template.
Expand Down
2 changes: 1 addition & 1 deletion libs/core/langchain_core/prompts/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def get_lc_namespace(cls) -> list[str]:

template_format: PromptTemplateFormat = "f-string"
"""The format of the prompt template.
Options are: 'f-string', 'mustache', 'jinja2'."""
Options are: 'f-string', 'mustache', 'jinja2', 'jinja2_unrestricted'."""

validate_template: bool = False
"""Whether or not to try validating the template."""
Expand Down
37 changes: 35 additions & 2 deletions libs/core/langchain_core/prompts/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,38 @@ def getattr(self, obj: Any, attribute: str) -> Any:
except ImportError:
_HAS_JINJA2 = False

PromptTemplateFormat = Literal["f-string", "mustache", "jinja2"]
PromptTemplateFormat = Literal["f-string", "mustache", "jinja2", "jinja2_unrestricted"]


def jinja2_formatter_unrestricted(template: str, /, **kwargs: Any) -> str:
"""Format a template using jinja2.

*Security warning*:
This method uses Jinja2's unrestricted sandbox.
This is not recommended as it is not secure.

Args:
template: The template string.
**kwargs: The variables to format the template with.

Returns:
The formatted string.

Raises:
ImportError: If jinja2 is not installed.
"""
if not _HAS_JINJA2:
msg = (
"jinja2 not installed, which is needed to use the\
jinja2_formatter_unrestricted. "
"Please install it with `pip install jinja2`."
"Please be cautious when using jinja2 templates. "
"Do not expand jinja2 templates using unverified or user-controlled "
"inputs as that can result in arbitrary Python code execution."
)
raise ImportError(msg)

return SandboxedEnvironment().from_string(template).render(**kwargs)


def jinja2_formatter(template: str, /, **kwargs: Any) -> str:
Expand Down Expand Up @@ -260,11 +291,13 @@ def _create_model_recursive(name: str, defs: Defs) -> type:
"f-string": formatter.format,
"mustache": mustache_formatter,
"jinja2": jinja2_formatter,
"jinja2_unrestricted": jinja2_formatter_unrestricted,
}

DEFAULT_VALIDATOR_MAPPING: dict[str, Callable] = {
"f-string": formatter.validate_input_variables,
"jinja2": validate_jinja2,
"jinja2_unrestricted": validate_jinja2,
}


Expand Down Expand Up @@ -313,7 +346,7 @@ def get_template_variables(template: str, template_format: str) -> list[str]:
Raises:
ValueError: If the template format is not supported.
"""
if template_format == "jinja2":
if template_format in ["jinja2", "jinja2_unrestricted"]:
# Get the variables for the template
input_variables = _get_jinja2_variables_from_template(template)
elif template_format == "f-string":
Expand Down
Loading