Support a list of messages

This commit is contained in:
Mark Backman
2024-11-15 17:37:33 -05:00
parent 7a55d2d7db
commit bd020320cd
3 changed files with 38 additions and 28 deletions

View File

@@ -61,10 +61,12 @@ flow_config = {
"initial_node": "start",
"nodes": {
"start": {
"message": {
"role": "system",
"content": "You are an order-taking assistant. You must ALWAYS use one of the available functions to progress the conversation. For this step, ask the user if they want pizza or sushi, and wait for them to use a function to choose.",
},
"messages": [
{
"role": "system",
"content": "You are an order-taking assistant. You must ALWAYS use one of the available functions to progress the conversation. For this step, ask the user if they want pizza or sushi, and wait for them to use a function to choose.",
}
],
"functions": [
{
"type": "function",
@@ -85,15 +87,17 @@ flow_config = {
],
},
"choose_pizza": {
"message": {
"role": "system",
"content": """You are handling a pizza order. Use the available functions:
"messages": [
{
"role": "system",
"content": """You are handling a pizza order. Use the available functions:
- Use select_pizza_size when the user specifies a size (can be used multiple times if they change their mind)
- Use the end function ONLY when the user confirms they are done with their order
After each size selection, confirm the selection and ask if they want to change it or complete their order.
Only use the end function after the user confirms they are satisfied with their order.""",
},
}
],
"functions": [
{
"type": "function",
@@ -127,15 +131,17 @@ flow_config = {
],
},
"choose_sushi": {
"message": {
"role": "system",
"content": """You are handling a sushi order. Use the available functions:
"messages": [
{
"role": "system",
"content": """You are handling a sushi order. Use the available functions:
- Use select_roll_count when the user specifies how many rolls (can be used multiple times if they change their mind)
- Use the end function ONLY when the user confirms they are done with their order
After each roll count selection, confirm the count and ask if they want to change it or complete their order.
Only use the end function after the user confirms they are satisfied with their order.""",
},
}
],
"functions": [
{
"type": "function",
@@ -170,10 +176,12 @@ flow_config = {
],
},
"end": {
"message": {
"role": "system",
"content": "The order is complete. Thank the user and end the conversation.",
},
"messages": [
{
"role": "system",
"content": "The order is complete. Thank the user and end the conversation.",
}
],
"functions": [],
"pre_actions": [{"type": "tts_say", "text": "Thank you for your order! Goodbye!"}],
"post_actions": [{"type": "end_conversation"}],

View File

@@ -25,7 +25,7 @@ class FlowManager:
This manager handles the progression through a flow defined by nodes, where each node
represents a state in the conversation. Each node has:
- A message for the LLM
- Messages for the LLM (system/user/assistant messages)
- Available functions that can be called
- Optional pre-actions to execute before LLM inference
- Optional post-actions to execute after LLM inference
@@ -65,7 +65,7 @@ class FlowManager:
to include in the context
"""
if not self.initialized:
messages = initial_messages + [self.flow.get_current_message()]
messages = initial_messages + self.flow.get_current_messages()
await self.task.queue_frame(LLMMessagesUpdateFrame(messages=messages))
await self.task.queue_frame(LLMSetToolsFrame(tools=self.flow.get_current_functions()))
self.initialized = True
@@ -204,8 +204,8 @@ class FlowManager:
await self._execute_actions(self.flow.get_current_pre_actions())
# Update LLM context and tools
current_message = self.flow.get_current_message()
await self.task.queue_frame(LLMMessagesAppendFrame(messages=[current_message]))
current_messages = self.flow.get_current_messages()
await self.task.queue_frame(LLMMessagesAppendFrame(messages=current_messages))
await self.task.queue_frame(
LLMSetToolsFrame(tools=self.flow.get_current_functions())
)

View File

@@ -18,13 +18,15 @@ class NodeConfig:
information needed for that particular point in the conversation.
Attributes:
message: Dict containing role and content for the LLM at this node
messages: List of message dicts to be added to LLM context at this node.
Each message should have 'role' (system/user/assistant) and 'content'.
Messages are added in order, allowing for complex prompt building.
functions: List of available function definitions for this node
pre_actions: Optional list of actions to execute before LLM inference
post_actions: Optional list of actions to execute after LLM inference
"""
message: dict
messages: List[dict]
functions: List[dict]
pre_actions: Optional[List[dict]] = None
post_actions: Optional[List[dict]] = None
@@ -34,7 +36,7 @@ class FlowState:
"""Manages the state and transitions between nodes in a conversation flow.
This class handles the state machine logic for conversation flows, where each node
represents a distinct state with its own message, available functions, and optional
represents a distinct state with its own messages, available functions, and optional
pre- and post-actions. It manages transitions between nodes based on function calls
and handles both regular and terminal functions.
@@ -73,19 +75,19 @@ class FlowState:
for node_id, node_config in config["nodes"].items():
self.nodes[node_id] = NodeConfig(
message=node_config["message"],
messages=node_config["messages"],
functions=node_config["functions"],
pre_actions=node_config.get("pre_actions"),
post_actions=node_config.get("post_actions"),
)
def get_current_message(self) -> dict:
"""Get the message configuration for the current node.
def get_current_messages(self) -> List[dict]:
"""Get the messages for the current node.
Returns:
Dictionary containing role and content for the current node's message
List of message dictionaries for the current node
"""
return self.nodes[self.current_node].message
return self.nodes[self.current_node].messages
def get_current_functions(self) -> List[dict]:
"""Get the available functions for the current node.