Skip to content

Commit

Permalink
core: allow passing message dicts into ChatPromptTemplate (#29363)
Browse files Browse the repository at this point in the history
Co-authored-by: Erick Friis <[email protected]>
  • Loading branch information
isahers1 and efriis authored Feb 5, 2025
1 parent 69595b0 commit 91ffd7c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
11 changes: 10 additions & 1 deletion libs/core/langchain_core/prompts/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ def pretty_print(self) -> None:
Union[str, list[dict], list[object]],
],
str,
dict,
]


Expand Down Expand Up @@ -1461,7 +1462,15 @@ def _convert_to_message(
_message = _create_template_from_message_type(
"human", message, template_format=template_format
)
elif isinstance(message, tuple):
elif isinstance(message, (tuple, dict)):
if isinstance(message, dict):
if set(message.keys()) != {"content", "role"}:
msg = (
"Expected dict to have exact keys 'role' and 'content'."
f" Got: {message}"
)
raise ValueError(msg)
message = (message["role"], message["content"])
if len(message) != 2:
msg = f"Expected 2-tuple of (role, template), got {message}"
raise ValueError(msg)
Expand Down
35 changes: 35 additions & 0 deletions libs/core/tests/unit_tests/prompts/test_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,41 @@ def test_chat_prompt_message_placeholder_tuple() -> None:
assert optional_prompt.format_messages() == []


def test_chat_prompt_message_placeholder_dict() -> None:
prompt = ChatPromptTemplate([{"role": "placeholder", "content": "{convo}"}])
assert prompt.format_messages(convo=[("user", "foo")]) == [
HumanMessage(content="foo")
]

assert prompt.format_messages() == []

# Is optional = True
optional_prompt = ChatPromptTemplate(
[{"role": "placeholder", "content": ["{convo}", False]}]
)
assert optional_prompt.format_messages(convo=[("user", "foo")]) == [
HumanMessage(content="foo")
]
with pytest.raises(KeyError):
assert optional_prompt.format_messages() == []


def test_chat_prompt_message_dict() -> None:
prompt = ChatPromptTemplate(
[{"role": "system", "content": "foo"}, {"role": "user", "content": "bar"}]
)
assert prompt.format_messages() == [
SystemMessage(content="foo"),
HumanMessage(content="bar"),
]

with pytest.raises(ValueError):
ChatPromptTemplate([{"role": "system", "content": False}])

with pytest.raises(ValueError):
ChatPromptTemplate([{"role": "foo", "content": "foo"}])


async def test_messages_prompt_accepts_list() -> None:
prompt = ChatPromptTemplate([MessagesPlaceholder("history")])
value = prompt.invoke([("user", "Hi there")]) # type: ignore
Expand Down

0 comments on commit 91ffd7c

Please sign in to comment.