'
assert chat_history.messages[0].role == AuthorRole.USER
async def test_handwritten_xml_as_arg_safe():
template = "{{$input}}"
rendered = await KernelPromptTemplate(
prompt_template_config=PromptTemplateConfig(
name="test",
description="test",
template=template,
),
).render(
kernel=Kernel(),
arguments=KernelArguments(input='test content'),
)
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert chat_history.messages[0].content == 'test content'
assert chat_history.messages[0].role == AuthorRole.USER
async def test_handwritten_xml_as_arg_unsafe_template():
template = "{{$input}}"
rendered = await KernelPromptTemplate(
prompt_template_config=PromptTemplateConfig(name="test", description="test", template=template),
allow_dangerously_set_content=True,
).render(
kernel=Kernel(),
arguments=KernelArguments(input='test content'),
)
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert chat_history.messages[0].content == "test content"
assert chat_history.messages[0].role == AuthorRole.USER
async def test_handwritten_xml_as_arg_unsafe_variable():
template = "{{$input}}"
rendered = await KernelPromptTemplate(
prompt_template_config=PromptTemplateConfig(
name="test",
description="test",
template=template,
input_variables=[InputVariable(name="input", allow_dangerously_set_content=True)],
),
).render(
kernel=Kernel(),
arguments=KernelArguments(input='test content'),
)
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert chat_history.messages[0].content == "test content"
assert chat_history.messages[0].role == AuthorRole.USER
async def test_template_empty_history(chat_history: ChatHistory):
template = "system stuff{{$chat_history}}{{$input}}"
rendered = await KernelPromptTemplate(
prompt_template_config=PromptTemplateConfig(name="test", description="test", template=template),
allow_dangerously_set_content=True,
).render(
kernel=Kernel(),
arguments=KernelArguments(chat_history=chat_history, input="What can you do?"),
)
chat_history_2 = ChatHistory.from_rendered_prompt(rendered)
assert chat_history_2.messages[0].content == "system stuff"
assert chat_history_2.messages[0].role == AuthorRole.SYSTEM
assert chat_history_2.messages[1].content == "What can you do?"
assert chat_history_2.messages[1].role == AuthorRole.USER
def test_to_from_file(chat_history: ChatHistory, tmp_path):
chat_history.add_system_message("You are an AI assistant")
chat_history.add_user_message("What is the weather in Seattle?")
chat_history.add_assistant_message([
FunctionCallContent(id="test1", name="WeatherPlugin-GetWeather", arguments='{{ "location": "Seattle" }}')
])
chat_history.add_tool_message([FunctionResultContent(id="test1", result="It is raining")])
chat_history.add_assistant_message("It is raining in Seattle, what else can I help you with?")
file_path = tmp_path / "chat_history.json"
chat_history.store_chat_history_to_file(file_path)
chat_history_2 = ChatHistory.load_chat_history_from_file(file_path)
assert len(chat_history_2.messages) == len(chat_history.messages)
assert chat_history_2.messages[0] == chat_history.messages[0]
assert chat_history_2.messages[1] == chat_history.messages[1]
assert chat_history_2.messages[2] == chat_history.messages[2]
assert chat_history_2.messages[3] == chat_history.messages[3]
assert chat_history_2.messages[4] == chat_history.messages[4]
def test_from_rendered_prompt_preserves_html_p_tag():
"""HTML tags in prompts should be preserved as text, not treated as template tags.
Regression test for https://github.com/microsoft/semantic-kernel/issues/13632
"""
rendered = (
'Translate following message from English language into the Spanish language - "
What is your name?
"'
)
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert len(chat_history.messages) == 1
assert chat_history.messages[0].role == AuthorRole.USER
assert "What is your name?
" in chat_history.messages[0].content
def test_from_rendered_prompt_preserves_multiple_html_tags():
"""Multiple HTML tags in prompts should be preserved as text."""
rendered = "First paragraph
A div
"
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert len(chat_history.messages) == 1
assert "First paragraph
" in chat_history.messages[0].content
assert "A div
" in chat_history.messages[0].content
def test_from_rendered_prompt_preserves_html_with_text_around():
"""HTML tags surrounded by plain text should preserve all content."""
rendered = "Hello world today"
chat_history = ChatHistory.from_rendered_prompt(rendered)
assert len(chat_history.messages) == 1
assert "Hello" in chat_history.messages[0].content
assert "world" in chat_history.messages[0].content
assert "today" in chat_history.messages[0].content
def test_from_rendered_prompt_sk_tags_still_work_with_html():
"""SK template tags should still be parsed correctly even when HTML tags are present."""
rendered = 'Tell me about bold text'
chat_history = ChatHistory.from_rendered_prompt(rendered)
# The tag inside a is handled by ChatMessageContent.from_element
assert len(chat_history.messages) == 1
assert chat_history.messages[0].role == AuthorRole.USER
def test_chat_history_serialize(chat_history: ChatHistory):
class CustomResultClass:
def __init__(self, result):
self.result = result
def __str__(self) -> str:
return self.result
custom_result = CustomResultClass(result="CustomResultTestValue")
chat_history.add_system_message("You are an AI assistant")
chat_history.add_user_message("What is the weather in Seattle?")
chat_history.add_assistant_message([
FunctionCallContent(id="test1", name="WeatherPlugin-GetWeather", arguments='{{ "location": "Seattle" }}')
])
chat_history.add_tool_message([FunctionResultContent(id="test1", result=custom_result)])
assert "CustomResultTestValue" in chat_history.serialize()