core[patch]: update dict prompt template (#30967)

Align with JS changes made in
https://github.com/langchain-ai/langchainjs/pull/8043
This commit is contained in:
Bagatur
2025-04-23 10:04:50 -07:00
committed by GitHub
parent 4bc70766b5
commit d4fc734250
11 changed files with 230 additions and 318 deletions

View File

@@ -3135,6 +3135,27 @@
'name': 'PromptTemplate',
'type': 'constructor',
}),
dict({
'id': list([
'langchain_core',
'prompts',
'dict',
'DictPromptTemplate',
]),
'kwargs': dict({
'template': dict({
'cache_control': dict({
'type': '{foo}',
}),
'text': "What's in this image?",
'type': 'text',
}),
'template_format': 'f-string',
}),
'lc': 1,
'name': 'DictPromptTemplate',
'type': 'constructor',
}),
dict({
'id': list([
'langchain',

View File

@@ -973,6 +973,11 @@ def test_chat_tmpl_serdes(snapshot: SnapshotAssertion) -> None:
"hello",
{"text": "What's in this image?"},
{"type": "text", "text": "What's in this image?"},
{
"type": "text",
"text": "What's in this image?",
"cache_control": {"type": "{foo}"},
},
{
"type": "image_url",
"image_url": "data:image/jpeg;base64,{my_image}",
@@ -1012,7 +1017,7 @@ def test_chat_tmpl_serdes(snapshot: SnapshotAssertion) -> None:
@pytest.mark.xfail(
reason=(
"In a breaking release, we can update `_convert_to_message_template` to use "
"_DictMessagePromptTemplate for all `dict` inputs, allowing for templatization "
"DictPromptTemplate for all `dict` inputs, allowing for templatization "
"of message attributes outside content blocks. That would enable the below "
"test to pass."
)

View File

@@ -0,0 +1,34 @@
from langchain_core.load import load
from langchain_core.prompts.dict import DictPromptTemplate
def test__dict_message_prompt_template_fstring() -> None:
template = {
"type": "text",
"text": "{text1}",
"cache_control": {"type": "{cache_type}"},
}
prompt = DictPromptTemplate(template=template, template_format="f-string")
expected = {
"type": "text",
"text": "important message",
"cache_control": {"type": "ephemeral"},
}
actual = prompt.format(text1="important message", cache_type="ephemeral")
assert actual == expected
def test_deserialize_legacy() -> None:
ser = {
"type": "constructor",
"lc": 1,
"id": ["langchain_core", "prompts", "message", "_DictMessagePromptTemplate"],
"kwargs": {
"template_format": "f-string",
"template": {"type": "audio", "audio": "{audio_data}"},
},
}
expected = DictPromptTemplate(
template={"type": "audio", "audio": "{audio_data}"}, template_format="f-string"
)
assert load(ser) == expected

View File

@@ -6,6 +6,7 @@ EXPECTED_ALL = [
"BasePromptTemplate",
"ChatMessagePromptTemplate",
"ChatPromptTemplate",
"DictPromptTemplate",
"FewShotPromptTemplate",
"FewShotPromptWithTemplates",
"FewShotChatMessagePromptTemplate",

View File

@@ -1,61 +0,0 @@
from pathlib import Path
from langchain_core.messages import AIMessage, BaseMessage, ToolMessage
from langchain_core.prompts.message import _DictMessagePromptTemplate
CUR_DIR = Path(__file__).parent.absolute().resolve()
def test__dict_message_prompt_template_fstring() -> None:
template = {
"role": "assistant",
"content": [
{"type": "text", "text": "{text1}", "cache_control": {"type": "ephemeral"}},
],
"name": "{name1}",
"tool_calls": [
{
"name": "{tool_name1}",
"args": {"arg1": "{tool_arg1}"},
"id": "1",
"type": "tool_call",
}
],
}
prompt = _DictMessagePromptTemplate(template=template, template_format="f-string")
expected: BaseMessage = AIMessage(
[
{
"type": "text",
"text": "important message",
"cache_control": {"type": "ephemeral"},
},
],
name="foo",
tool_calls=[
{
"name": "do_stuff",
"args": {"arg1": "important arg1"},
"id": "1",
"type": "tool_call",
}
],
)
actual = prompt.format_messages(
text1="important message",
name1="foo",
tool_arg1="important arg1",
tool_name1="do_stuff",
)[0]
assert actual == expected
template = {
"role": "tool",
"content": "{content1}",
"tool_call_id": "1",
"name": "{name1}",
}
prompt = _DictMessagePromptTemplate(template=template, template_format="f-string")
expected = ToolMessage("foo", name="bar", tool_call_id="1")
actual = prompt.format_messages(content1="foo", name1="bar")[0]
assert actual == expected