Messages Subsystem¶
Overview¶
This subsystem handles structured messages in LionAGI, enabling: - User instructions (with context, images, or tool references), - System messages that define context or constraints, - Assistant responses capturing AI output, - ActionRequests and ActionResponses to call code or tools.
All are subclasses of RoledMessage
, which defines a role, sender, recipient, and content.
Contents¶
Base Types¶
Holds foundational enumerations and types for messages, including roles like SYSTEM, USER, and helper functions for validating sender/recipient fields.
Key enumerations like MessageRole
(SYSTEM
, USER
, ASSISTANT
, etc.) and the basic notion of a “sender/recipient” reside here.
- class lionagi.protocols.messages.base.MessageRole(str, Enum)¶
Predefined roles for conversation participants or message semantics.
Members¶
- SYSTEMstr
System-level message role
- USERstr
User message role
- ASSISTANTstr
Assistant (AI) message role
- UNSETstr
Unset or default role
- ACTIONstr
Action-related message role
- class lionagi.protocols.messages.base.MessageFlag(str, Enum)¶
Internal flags for certain message states, e.g., clones or loads.
Members¶
- MESSAGE_CLONEstr
Flag indicating a cloned message
- MESSAGE_LOADstr
Flag indicating a loaded message
- class lionagi.protocols.messages.base.MessageField(str, Enum)¶
Common field names used in message objects.
Members¶
- CREATED_ATstr
Field name for creation timestamp
- ROLEstr
Field name for message role
- CONTENTstr
Field name for message content
- IDstr
Field name for message ID
- SENDERstr
Field name for message sender
- RECIPIENTstr
Field name for message recipient
- METADATAstr
Field name for message metadata
- lionagi.protocols.messages.base.SenderRecipient¶
A union type indicating that a sender or recipient could be: - A lionagi IDType - A string-based role or ID - A specific enum role from MessageRole
- lionagi.protocols.messages.base.MESSAGE_FIELDS¶
List of all common message field names from MessageField enum.
- lionagi.protocols.messages.base.validate_sender_recipient(value)¶
Normalize a sender/recipient value into a recognized type.
Parameters¶
- valueAny
Input to interpret as a role or ID
Returns¶
- SenderRecipient
A validated and normalized entity
Raises¶
- ValueError
If the input cannot be recognized as a role or ID
RoledMessage¶
Implements the RoledMessage base for system, user, assistant, and action messages, plus Jinja2 environment and template loading.
Defines a general base class for typed messages with a role. Every specialized message (like system instructions, user instructions, or AI responses) inherits from RoledMessage
.
- class lionagi.protocols.messages.message.RoledMessage(Node, Sendable)¶
A base class for all messages that have a role and carry structured content. Subclasses might be Instruction, ActionRequest, etc.
Attributes¶
- contentdict
The content of the message
- roleMessageRole | None
The role of the message in the conversation
- templatestr | Template | None
Optional Jinja template for rendering content
- senderSenderRecipient | None
The ID of the sender node or a role
- recipientSenderRecipient | None
The ID of the recipient node or a role
Properties¶
- image_contentlist[dict[str, Any]] | None
Extract structured image data from the message content if it is represented as a chat message array
- chat_msgdict[str, Any] | None
A dictionary representation typically used in chat-based contexts
- renderedstr
Attempt to format the message with a Jinja template (if provided)
Methods¶
- create(**kwargs)
Must be implemented in subclass to create new instances
- from_dict(dict_)
Deserialize a dictionary into a RoledMessage or subclass
- is_clone()
Check if this message is flagged as a clone
- clone(keep_role=True)
Create a shallow copy of this message, possibly resetting the role
- to_log()
Convert this message into a Log, preserving all current fields
- update(sender, recipient, template, **kwargs)
Generic update mechanism for customizing the message in place
Notes¶
The RoledMessage class is designed to be subclassed by specific message types like System, Instruction, etc. It provides template-based rendering of content and serialization support for various field types.
System¶
Defines the System class, representing system-level instructions or settings that guide the AI’s behavior from a privileged role.
System
sets system-level instructions. Typically the very first message in a conversation, it describes how the AI should behave overall.
- class lionagi.protocols.messages.system.System(RoledMessage)¶
A specialized message that sets a system-level context or policy. Usually the first in a conversation, instructing the AI about general constraints or identity.
Attributes¶
- templatestr | Template | None
Template for rendering system messages, defaults to system_message.jinja2
Methods¶
- create(system_message=”You are a helpful AI assistant. Let’s think step by step.”, system_datetime=None, sender=None, recipient=None, template=None, system=None, **kwargs)
Construct a system message with optional datetime annotation
- system_messagestr
The main text instructing the AI about behavior/identity
- system_datetimebool | str, optional
If True or str, embed a time reference. If str, it is used directly
- senderSenderRecipient, optional
Typically MessageRole.SYSTEM
- recipientSenderRecipient, optional
Typically MessageRole.ASSISTANT
- templateTemplate | str | None
An optional custom template for rendering
- systemAny
Alias for system_message (deprecated)
- **kwargs
Additional content merged into the final dict
- System
A newly created system-level message
- update(system_message=None, sender=None, recipient=None, system_datetime=None, template=None, **kwargs)
Adjust fields of this system message
- system_messageJsonValue
New system message text
- senderSenderRecipient
Updated sender or role
- recipientSenderRecipient
Updated recipient or role
- system_datetimebool | str
If set, embed new datetime info
- templateTemplate | str | None
New template override
- **kwargs
Additional fields for self.content
Notes¶
The System class is designed to be the first message in a conversation, setting up the context and behavior expectations for the AI. It supports datetime annotations and custom templates for rendering the system message.
Instruction¶
Defines the Instruction class, representing user commands or instructions sent to the system. Supports optional context, images, and schema requests.
Instruction
captures the user’s command or question. It may contain optional context or images, as well as a schema for structured responses.
- class lionagi.protocols.messages.instruction.Instruction(RoledMessage)¶
A user-facing message that conveys commands or tasks. It supports optional images, tool references, and schema-based requests.
Properties¶
- guidancestr | None
Optional guiding text for the instruction
- instructionJsonValue | None
The main instruction or command
- contextJsonValue | None
Additional context about the environment
- tool_schemasJsonValue | None
Extra data describing available tools
- plain_contentstr | None
Raw plain text fallback
- image_detailLiteral[“low”, “high”, “auto”] | None
Detail level for included images
- imageslist
List of images associated with the instruction
- request_fieldsdict | None
Fields requested in the response
- response_formattype[BaseModel] | None
Pydantic model for structured responses
- respond_schema_infodict | None
Schema information for responses
- request_response_formatstr | None
Formatted request response template
Methods¶
- create(instruction=None, *, context=None, guidance=None, images=None, sender=None, recipient=None, request_fields=None, plain_content=None, image_detail=None, request_model=None, response_format=None, tool_schemas=None)
Construct a new Instruction
- extend_images(images, image_detail=None)
Append images to the existing list
- extend_context(*args, **kwargs)
Append additional context to the existing context array
- update(*, guidance=None, instruction=None, context=None, request_fields=None, plain_content=None, request_model=None, response_format=None, images=None, image_detail=None, tool_schemas=None, sender=None, recipient=None)
Batch-update this Instruction
Notes¶
The Instruction class is designed to be flexible in how it represents user commands, supporting everything from simple text instructions to complex requests with images, schemas, and tool references.
AssistantResponse¶
Defines AssistantResponse, a specialized RoledMessage for the AI’s assistant replies (usually from LLM or related).
AssistantResponse
is the AI’s reply to a user or system message. This may store raw model data (JSON output) in metadata["model_response"]
.
- class lionagi.protocols.messages.assistant_response.AssistantResponse(RoledMessage)¶
A message representing the AI assistant’s reply, typically from a model or LLM call. If the raw model output is available, it’s placed in metadata[“model_response”].
Attributes¶
- templateTemplate | str | None
Template for rendering assistant responses, defaults to assistant_response.jinja2
Properties¶
- responsestr
Get or set the text portion of the assistant’s response
- model_responsedict | list[dict]
Access the underlying model’s raw data, if available
Methods¶
- create(assistant_response, sender=None, recipient=None, template=None, **kwargs)
Build an AssistantResponse from arbitrary assistant data
- assistant_responseBaseModel | list[BaseModel] | dict | str | Any
A pydantic model, list, dict, or string representing an LLM or system response
- senderSenderRecipient | None
The ID or role denoting who sends this response
- recipientSenderRecipient | None
The ID or role to receive it
- templateTemplate | str | None
Optional custom template
- **kwargs
Additional content key-value pairs
- AssistantResponse
The constructed instance
- update(assistant_response=None, sender=None, recipient=None, template=None, **kwargs)
Update this AssistantResponse with new data or fields
- assistant_responseBaseModel | list[BaseModel] | dict | str | Any
Additional or replaced assistant model output
- senderSenderRecipient | None
Updated sender
- recipientSenderRecipient | None
Updated recipient
- templateTemplate | str | None
Optional new template
- **kwargs
Additional content updates for self.content
Notes¶
The AssistantResponse class is designed to handle various formats of AI model outputs, from simple strings to complex structured responses. It preserves both the human-readable response and the raw model output when available.
ActionRequest¶
Defines the ActionRequest class, a specific RoledMessage for requesting a function or action call within LionAGI. It is typically accompanied by arguments and can later be answered by an ActionResponse.
ActionRequest
is a special message for requesting a function call or action. Contains a function name and arguments.
- class lionagi.protocols.messages.action_request.ActionRequest(RoledMessage)¶
A message that requests an action or function to be executed. It inherits from RoledMessage and includes function name, arguments, and optional linking to a subsequent ActionResponse.
Attributes¶
- templateTemplate | str | None
Template for rendering action requests, defaults to action_request.jinja2
Properties¶
- action_response_idIDType | None
Get or set the ID of the corresponding action response
- requestdict[str, Any]
Get the entire ‘action_request’ dictionary if present
- argumentsdict[str, Any]
Access just the ‘arguments’ from the action request
- functionstr
Name of the function to be invoked
Methods¶
- create(function=None, arguments=None, sender=None, recipient=None, template=None, **kwargs)
Build a new ActionRequest
- functionstr | Callable | None
The function or callable name
- argumentsdict | None
Arguments for that function call
- senderSenderRecipient | None
The sender identifier or role
- recipientSenderRecipient | None
The recipient identifier or role
- templateTemplate | str | None
Optional custom template
- **kwargs
Extra key-value pairs to merge into the content
- ActionRequest
A newly constructed instance
- update(function=None, arguments=None, sender=None, recipient=None, action_response=None, template=None, **kwargs)
Update this request with new function, arguments, or link to an action response
- functionstr
New function name, if changing
- argumentsdict
New arguments dictionary, if changing
- senderSenderRecipient
New sender
- recipientSenderRecipient
New recipient
- action_responseActionResponse
If provided, this request is flagged as responded
- templateTemplate | str | None
Optional new template
- **kwargs
Additional fields to store in content
- ValueError
If the request is already responded to
- is_responded()
Check if there’s a linked action response
- bool
True if an action response ID is present
Notes¶
The ActionRequest class is designed to represent function or action calls within the system. It maintains a link to its corresponding ActionResponse once the action is completed.
ActionResponse¶
Defines ActionResponse, an RoledMessage that answers an ActionRequest with output from a function call or action.
Pairs with an ActionRequest
, providing the output of that requested function. The original request ID is also tracked.
- class lionagi.protocols.messages.action_response.ActionResponse(RoledMessage)¶
A message fulfilling an ActionRequest. It stores the function name, the arguments used, and the output produced by the function.
Attributes¶
- templateTemplate | str | None
Template for rendering action responses, defaults to action_response.jinja2
Properties¶
- functionstr
Name of the function that was executed
- argumentsdict[str, Any]
Arguments used for the executed function
- outputAny
The result or returned data from the function call
- responsedict[str, Any]
A helper to get the entire ‘action_response’ dictionary
- action_request_idIDType
The ID of the original action request
Methods¶
- create(action_request, output=None, response_model=None, sender=None, recipient=None)
Build an ActionResponse from a matching ActionRequest and output
- action_requestActionRequest
The original request being fulfilled
- outputAny, optional
The function output or result
- response_modelAny, optional
If present and has .output, this is used instead of output
- senderSenderRecipient, optional
The role or ID of the sender (defaults to the request’s recipient)
- recipientSenderRecipient, optional
The role or ID of the recipient (defaults to the request’s sender)
- ActionResponse
A new instance referencing the ActionRequest
- update(action_request=None, output=None, response_model=None, sender=None, recipient=None, template=None, **kwargs)
Update this response with a new request reference or new output
- action_requestActionRequest
The updated request
- outputAny
The new function output data
- response_modelAny
If present, uses response_model.output
- senderSenderRecipient
New sender ID or role
- recipientSenderRecipient
New recipient ID or role
- templateTemplate | str | None
Optional new template
- **kwargs
Additional fields to store in content
Notes¶
The ActionResponse class is designed to pair with ActionRequest messages, providing a structured way to return function call results while maintaining the link to the original request.
MessageManager¶
Implements the MessageManager class, a manager for collecting or manipulating sequences of RoledMessage objects, including system, instructions, or action requests/responses.
A manager for collecting messages in order, offering utility methods to add system instructions, user instructions, or assistant responses, and to fetch them (e.g. “last instruction”). Also includes action request/response handling.
- class lionagi.protocols.messages.manager.MessageManager(Manager)¶
A manager maintaining an ordered list of RoledMessage items. Capable of setting or replacing a system message, adding instructions, assistant responses, or actions, and retrieving them conveniently.
Properties¶
- progressionProgression
Access to the underlying progression of messages
- last_responseAssistantResponse | None
Retrieve the most recent AssistantResponse
- last_instructionInstruction | None
Retrieve the most recent Instruction
- assistant_responsesPile[AssistantResponse]
All AssistantResponse messages in the manager
- actionsPile[ActionRequest | ActionResponse]
All action messages in the manager
- action_requestsPile[ActionRequest]
All ActionRequest messages in the manager
- action_responsesPile[ActionResponse]
All ActionResponse messages in the manager
- instructionsPile[Instruction]
All Instruction messages in the manager
Methods¶
- set_system(system)
Replace or set the system message. If one existed, remove it.
- aclear_messages()
Async clear all messages except system.
- a_add_message(**kwargs)
Add a message asynchronously with a manager-level lock.
- create_instruction(*, instruction=None, context=None, guidance=None, images=None, request_fields=None, plain_content=None, image_detail=None, request_model=None, response_format=None, tool_schemas=None, sender=None, recipient=None)
Construct or update an Instruction message with advanced parameters.
- create_assistant_response(*, sender=None, recipient=None, assistant_response=None, template=None, template_context=None)
Build or update an AssistantResponse.
- create_action_request(*, sender=None, recipient=None, function=None, arguments=None, action_request=None, template=None, template_context=None)
Build or update an ActionRequest.
- create_action_response(*, action_request, action_output=None, action_response=None, sender=None, recipient=None)
Create or update an ActionResponse, referencing a prior ActionRequest.
- create_system(*, system=None, system_datetime=None, sender=None, recipient=None, template=None, template_context=None)
Create or update a System message.
- add_message(**kwargs)
The central method to add a new message of various types.
- clear_messages()
Remove all messages except the system message if it exists.
- remove_last_instruction_tool_schemas()
Convenience method to strip ‘tool_schemas’ from the most recent Instruction.
- concat_recent_action_responses_to_instruction(instruction)
Example method to merge the content of recent ActionResponses into an instruction’s context.
- to_chat_msgs(progression=None)
Convert a subset (or all) of messages into a chat representation array.
Parameters¶
- messageslist[RoledMessage] | None
Initial list of messages to manage
- progressionProgression | None
Optional custom progression to use
- systemSystem | None
Optional system message to start with
Notes¶
The MessageManager class provides a central point for managing all types of messages in a conversation, including system messages, instructions, responses, and action requests/responses. It maintains message order and provides convenient access methods.
Example Usage¶
from lionagi.protocols.messages.message_manager import MessageManager
from lionagi.protocols.messages.system import System
from lionagi.protocols.messages.instruction import Instruction
from lionagi.protocols.messages.assistant_response import AssistantResponse
# 1) Create a manager
manager = MessageManager(system=System.create())
# 2) Add a user instruction
instruct = Instruction.create(instruction="How to deploy a python app?")
msg, _ = manager.add_message(instruction=instruct)
# 3) AI responds
response = AssistantResponse.create("You can use Docker or a PaaS like Heroku.")
msg, _ = manager.add_message(assistant_response=response)
# Inspect
print(manager.last_response.response)
# -> "You can use Docker or a PaaS like Heroku."
File Locations¶
base.py: Shared role/flag definitions.
message.py: The
RoledMessage
base class + jinja environment.system.py: The
System
specialized message.instruction.py: The
Instruction
specialized message.assistant_response.py: The
AssistantResponse
specialized message.action_request.py: The
ActionRequest
specialized message.action_response.py: The
ActionResponse
specialized message.message_manager.py: A manager class for storing and operating on multiple messages.
Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
SPDX-License-Identifier: Apache-2.0