Skip to content

fix: ensure Bedrock compliance by separating tool result and conversation blocks in chat history adapter #6522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -293,27 +293,27 @@ def __init__(
self._tools_plugin: KernelPlugin = KernelPlugin(name="autogen_tools")

def _convert_to_chat_history(self, messages: Sequence[LLMMessage]) -> ChatHistory:
"""Convert Autogen LLMMessages to SK ChatHistory"""
"""Convert Autogen LLMMessages to SK ChatHistory, ensuring Bedrock compliance (no conversation and tool result in same turn)"""
chat_history = ChatHistory()
last_was_tool = False

for msg in messages:
if msg.type == "SystemMessage":
chat_history.add_system_message(msg.content)
last_was_tool = False

elif msg.type == "UserMessage":
if isinstance(msg.content, str):
chat_history.add_user_message(msg.content)
else:
# Handle list of str/Image - convert to string for now
chat_history.add_user_message(str(msg.content))
last_was_tool = False

elif msg.type == "AssistantMessage":
# Check if it's a function-call style message
if isinstance(msg.content, list) and all(isinstance(fc, FunctionCall) for fc in msg.content):
# If there's a 'thought' field, you can add that as plain assistant text
if msg.thought:
chat_history.add_assistant_message(msg.thought)

function_call_contents: list[FunctionCallContent] = []
for fc in msg.content:
function_call_contents.append(
Expand All @@ -325,15 +325,14 @@ def _convert_to_chat_history(self, messages: Sequence[LLMMessage]) -> ChatHistor
arguments=fc.arguments,
)
)

# Mark the assistant's message as tool-calling
chat_history.add_assistant_message(
function_call_contents,
finish_reason=FinishReason.TOOL_CALLS,
)
last_was_tool = False
else:
# Plain assistant text
chat_history.add_assistant_message(msg.content)
last_was_tool = False

elif msg.type == "FunctionExecutionResultMessage":
# Add each function result as a separate tool message
Expand All @@ -347,8 +346,14 @@ def _convert_to_chat_history(self, messages: Sequence[LLMMessage]) -> ChatHistor
result=result.content,
)
)
# A single "tool" message with one or more results
# Bedrock: ensure tool result is not combined with conversation in same turn
if last_was_tool:
# Insert a dummy user message to break the turn if previous was also a tool
chat_history.add_user_message(".")
chat_history.add_tool_message(tool_results)
last_was_tool = True
else:
last_was_tool = False

return chat_history

Expand Down