v1.3.0
Summary of Changes
This release brings many API and internal improvements. I've incorporated a lot of the great feedback I've been getting and improved multiple areas in terms of clarity, organization, and implementation.
What I'm most excited about is that the API feels like it's beginning to reach a relatively clean and extensible form, enabling more possibilities to follow.
A number of syntactic and semantic changes have been made. I've summarized the changes here, but for full details also refer to the updated docs/ or readme.
As always please let me know what you think, especially if you find any issues!
Syntax and functional changes
-
Introduced a new
@action
decorator based syntax for defining actions and their metadata, replacing the@access_policy
decorator. For example:@action def my_action(self): ...
An example showing how the
access_policy
is now declared:@action(access_policy=ACCESS_PERMITTED) def my_action(self): ...
Additionally, the
_action__
prefix is no longer needed on action method names. -
Agent
id
's are now enforced to be unique.Allowing duplicate
id
's creates more problems than it solves. If one needs to duplicate or distribute messages to multiple consumers, that can be achieved by simply sending multiple messages from the agent. -
Leading underscores removed from several agent methods and callbacks.
Moving forward, methods with leading underscores should be treated as internal API methods and should generally not be referenced in except when overriding methods or extending a class. To follow this convention, the following methods have been renamed:
Agent
class methods:-
_send
is nowsend
-
_before_add
is nowbefore_add
-
_after_add
is nowafter_add
-
_before_remove
is nowbefore_remove
-
_after_remove
is nowafter_remove
-
_request_permission
is nowrequest_permission
-
Additionally, the special action
return
is now renamed toresponse
.
-
-
The signatures for
response
(formerlyreturn
) anderror
have changed to the following:@action def response(self, data, original_message_id: str): ... @action def error(self, error: str, original_message_id: str): ...
Note that the
original_message
argument is replaced with theoriginal_message_id
parameter. This parameter is discussed with the message schema changes below. -
Updated
help
functionalityThe
help
action now returns a new schema for describing actions. The data structure returned is now a dictionary similar to the following example:{ "say": { "description": "Say something to this agent", "args": { "content": { "type": "string" "description": "The content to say" } }, "returns": { "type": "string" "description": "A response" } }, ... }
The help structure above is automatically generated from the method's docstring and signature. Additionally, you can provide a custom help schema using the
@action
decorator.See the "Defining Actions" section for more details on the help schema.
-
Space.remove_all()
method added for removing all agents who were added through the receiving space instance. In other words, in an AMQP distributed system, only the locally added agents would be removed.
Message schema changes
-
Added an optional
id
field. This field is automatically provided withresponse
orerror
messages for you to correlate with the original message. -
Added an optional
meta
field. This field is an optional dictionary of key-value pairs for you to attach metadata to a message. For example, you may use this to store timestamps, or a "thoughts" field for recording reasoning. -
The
to
field is now required. To send a broadcast use the special address*
. -
The
action
field is now an object containing thename
andargs
fields.
The full schema is summarized with this example:
{
"id": "optional string id",
"meta": {
"an": "optional",
"field": ["for", "metadata"]
},
"to": "an agent id", # or '*' to broadcast
"from": "sender's id",
"action": {
"name": "my_action",
"args": {
"the": "args"
}
}
}
See the docs "Schema" section for more details.
Message routing changes
-
Broadcasts are now self received by default. This is the normal semantics for broadcasts.
This behavior is now an option on the
Agent
class:receive_own_broadcasts: bool = True
.Setting it to
False
will restore the previous behavior. -
Messages sent to a non-existent agent will now be silently ignored. Previously this would result in an error message being returned. Note that calling a non-existent action on an existent agent will still result in an error message.
This change brings us more in line with the Actor model. Reliability options may be added at the Agent level in the future.
Internal Improvements
-
Removed
colorama
dependency -
Removed use of
id_queue
inAMQPSpace
for checking agent existence. -
Space._route()
no longer sets thefrom
field on messages. The entire
message must be populated within the Agent instance before calling_route()
. -
Threading improvements
Threading code has been greatly cleaned up and improved. The updated implementation should make it easy to support additional forms of multi-processing like green threads and the multiprocessing module. I'm really happy about this change in particular.
-
Space classes (
NativeSpace
andAMQPSpace
) moved to theagency.spaces
namespace. -
Tests have been better organized into separate files.
-
The
Space
class abstract methods have been changed.Space
subclasses now implement the following methods:_connect()
_disconnect()
_deliver()
_consume()
This is a change from the previous interface. See the
Space
class for more details.
Demo improvements
-
OpenAIFunctionAgent
now supplies argument descriptions to the OpenAI function calling API, enabled by the newhelp
information schema. -
Agent mixins have been refactored to better separate behavior.
-
Updated slash syntax in the UI. Slash commands now follow this example:
/agent_id.action_name arg1:value1 arg2:value2 ...
The
agent_id
above defines theto
field of the message and is required.To broadcast an action, use the syntax:
/*.action_name arg1:value1 arg2:value2 ...
Note that unformatted text is still considered a broadcasted
say
action.
That's all for now!