Open rossanodr opened 1 week ago
To resolve the "ValidationException: A conversation must alternate between user and assistant roles" issue when using ChatBedrockConverse
, you need to ensure that the conversation messages alternate between user and assistant roles. The provided code already includes a mechanism to combine consecutive user tool result messages into a single message. This helps in maintaining the required alternation between user and assistant roles.
Here is the relevant part of the code that handles this:
const combinedConverseMessages = converseMessages.reduce<BedrockMessage[]>(
(acc, curr) => {
const lastMessage = acc[acc.length - 1];
if (
lastMessage &&
lastMessage.role === "user" &&
lastMessage.content?.some((c) => "toolResult" in c) &&
curr.role === "user" &&
curr.content?.some((c) => "toolResult" in c)
) {
lastMessage.content = lastMessage.content.concat(curr.content);
} else {
acc.push(curr);
}
return acc;
},
[]
);
return { converseMessages: combinedConverseMessages, converseSystem };
Additionally, ensure that the roles are correctly assigned when converting messages to the required format. The messageToGroqRole
function and the convertMessagesToGroqParams
function from the libs/langchain-groq/src/chat_models.ts
file can help in correctly mapping the roles:
export function messageToGroqRole(message: BaseMessage): GroqRoleEnum {
const type = message._getType();
switch (type) {
case "system":
return "system";
case "ai":
return "assistant";
case "human":
return "user";
case "function":
return "function";
case "tool":
return "tool" as GroqRoleEnum;
default:
throw new Error(`Unknown message type: ${type}`);
}
}
function convertMessagesToGroqParams(
messages: BaseMessage[]
): Array<ChatCompletionsAPI.ChatCompletionMessage> {
return messages.map((message): ChatCompletionsAPI.ChatCompletionMessage => {
if (typeof message.content !== "string") {
throw new Error("Non string message content not supported");
}
const completionParam: Record<string, any> = {
role: messageToGroqRole(message),
content: message.content,
name: message.name,
function_call: message.additional_kwargs.function_call,
tool_calls: message.additional_kwargs.tool_calls,
tool_call_id: (message as ToolMessage).tool_call_id,
};
if (isAIMessage(message) && !!message.tool_calls?.length) {
completionParam.tool_calls = message.tool_calls.map(
convertLangChainToolCallToOpenAI
);
} else {
if (message.additional_kwargs.tool_calls != null) {
completionParam.tool_calls = message.additional_kwargs.tool_calls;
}
if ((message as ToolMessage).tool_call_id != null) {
completionParam.tool_call_id = (message as ToolMessage).tool_call_id;
}
}
return completionParam as ChatCompletionsAPI.ChatCompletionMessage;
});
}
This code ensures that the roles are correctly assigned and the messages are formatted properly, which helps in maintaining the required alternation between user and assistant roles [1][2][3].
To continue talking to Dosu, mention @dosu.
The problem does not occour using BedrockChat, but I can't use the tools with it
This fix the issue: The problem is that the you can't send the input + the last message with 'user' role. `const convertChatHistoryToMessages = ( chat_history: [role: string, content: string][] ) => { let previousRole: any = null;
const messages = chat_history.flatMap(([role, content], index) => {
const msgArray = [];
if (previousRole === role) {
if (role === "human" || role === "user") {
msgArray.push(new AIMessage("..."));
} else {
msgArray.push(new HumanMessage("..."));
}
}
switch (role) {
case "human":
case "user":
msgArray.push(new HumanMessage(content));
break;
case "assistant":
case "ai":
msgArray.push(new AIMessage(content));
break;
default:
msgArray.push(new HumanMessage(content));
}
previousRole = role;
return msgArray;
});
const lastMessage = chat_history[chat_history.length - 1];
if (
lastMessage &&
(lastMessage[0] === "user" || lastMessage[0] === "human")
) {
messages.push(new AIMessage("..."));
}
return messages;
};`
Checked other resources
Example Code
Basically its the same code you can find here but using ChatBedrockConverse: https://github.com/bracesproul/gen-ui/blob/main/ai/graph.tsx
llm = new ChatBedrockConverse({ model: "anthropic.claude-3-sonnet-20240229-v1:0", temperature: state.temperature, }).bindTools(tools);
Error Message and Stack Trace (if applicable)
No response
Description
I'm experiencing the following issue while using ChatBedrockConverse: "ValidationException: A conversation must alternate between user and assistant roles. Make sure the conversation alternates between user and assistant roles and try again."
The issue occurs when, for example, a tool's response is followed by an AI message, or when there are two consecutive user messages.
Could you check if there's a specific setting or configuration to handle this issue? I tried something like the following, but it didn't work:
Is there any adjustment or alternative solution to resolve the issue when consecutive messages come from the same role?
System Info
langchain@npm:0.2.17 ββ Instances: 1 ββ Version: 0.2.17 β ββ Dependencies ββ @langchain/core@npm:^0.2.18 β npm:0.2.31 ββ @langchain/openai@npm:>=0.1.0 <0.3.0 β npm:0.2.5 ββ @langchain/textsplitters@npm:~0.0.0 β npm:0.0.3 ββ binary-extensions@npm:^2.2.0 β npm:2.3.0 ββ js-tiktoken@npm:^1.0.12 β npm:1.0.12 ββ js-yaml@npm:^4.1.0 β npm:4.1.0 ββ jsonpointer@npm:^5.0.1 β npm:5.0.1 ββ langsmith@npm:~0.1.40 β npm:0.1.48 ββ openapi-types@npm:^12.1.3 β npm:12.1.3 ββ p-retry@npm:4 β npm:4.6.2 ββ uuid@npm:^10.0.0 β npm:10.0.0 ββ yaml@npm:^2.2.1 β npm:2.4.5 ββ zod-to-json-schema@npm:^3.22.3 β npm:3.23.1 ββ zod@npm:^3.22.4 β npm:3.23.8