Skip to content

Commit

Permalink
Code executors (#1405)
Browse files Browse the repository at this point in the history
* code executor

* test

* revert to main conversable agent

* prepare for pr

* kernel

* run open ai tests only when it's out of draft status

* update workflow file

* revert workflow changes

* ipython executor

* check kernel installed; fix tests

* fix tests

* fix tests

* update system prompt

* Update notebook, more tests

* notebook

* raise instead of return None

* allow user provided code executor.

* fixing types

* wip

* refactoring

* polishing

* fixed failing tests

* resolved merge conflict

* fixing failing test

* wip

* local command line executor and embedded ipython executor

* revert notebook

* fix format

* fix merged error

* fix lmm test

* fix lmm test

* move warning

* name and description should be part of the agent protocol, reset is not as it is only used for ConversableAgent; removing accidentally commited file

* version for dependency

* Update autogen/agentchat/conversable_agent.py

Co-authored-by: Jack Gerrits <[email protected]>

* ordering of protocol

* description

* fix tests

* make ipython executor dependency optional

* update document optional dependencies

* Remove exclude from Agent protocol

* Make ConversableAgent consistent with Agent

* fix tests

* add doc string

* add doc string

* fix notebook

* fix interface

* merge and update agents

* disable config usage in reply function

* description field setter

* customize system message update

* update doc

---------

Co-authored-by: Davor Runje <[email protected]>
Co-authored-by: Jack Gerrits <[email protected]>
Co-authored-by: Aaron <[email protected]>
Co-authored-by: Chi Wang <[email protected]>
  • Loading branch information
5 people authored Feb 10, 2024
1 parent 5d81ed4 commit 609ba7c
Show file tree
Hide file tree
Showing 22 changed files with 1,419 additions and 129 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ jobs:
pip install -e .
python -c "import autogen"
pip install pytest mock
pip install jupyter-client ipykernel
python -m ipykernel install --user --name python3
- name: Set AUTOGEN_USE_DOCKER based on OS
shell: bash
run: |
if [[ ${{ matrix.os }} != ubuntu-latest ]]; then
echo "AUTOGEN_USE_DOCKER=False" >> $GITHUB_ENV
fi
- name: Test with pytest skipping openai tests
if: matrix.python-version != '3.10' && matrix.os == 'ubuntu-latest'
run: |
Expand Down
134 changes: 100 additions & 34 deletions autogen/agentchat/agent.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,136 @@
from typing import Dict, List, Optional, Union
from typing import Any, Dict, List, Optional, Protocol, Union, runtime_checkable


class Agent:
"""(In preview) An abstract class for AI agent.
@runtime_checkable
class Agent(Protocol):
"""(In preview) A protocol for Agent.
An agent can communicate with other agents and perform actions.
Different agents can differ in what actions they perform in the `receive` method.
"""

def __init__(
@property
def name(self) -> str:
"""The name of the agent."""
...

@property
def description(self) -> str:
"""The description of the agent. Used for the agent's introduction in
a group chat setting."""
...

def send(
self,
name: str,
):
"""
message: Union[Dict[str, Any], str],
recipient: "Agent",
request_reply: Optional[bool] = None,
) -> None:
"""Send a message to another agent.
Args:
name (str): name of the agent.
message (dict or str): the message to send. If a dict, it should be
a JSON-serializable and follows the OpenAI's ChatCompletion schema.
recipient (Agent): the recipient of the message.
request_reply (bool): whether to request a reply from the recipient.
"""
# a dictionary of conversations, default value is list
self._name = name
...

@property
def name(self):
"""Get the name of the agent."""
return self._name
async def a_send(
self,
message: Union[Dict[str, Any], str],
recipient: "Agent",
request_reply: Optional[bool] = None,
) -> None:
"""(Async) Send a message to another agent.
def send(self, message: Union[Dict, str], recipient: "Agent", request_reply: Optional[bool] = None):
"""(Abstract method) Send a message to another agent."""
Args:
message (dict or str): the message to send. If a dict, it should be
a JSON-serializable and follows the OpenAI's ChatCompletion schema.
recipient (Agent): the recipient of the message.
request_reply (bool): whether to request a reply from the recipient.
"""
...

async def a_send(self, message: Union[Dict, str], recipient: "Agent", request_reply: Optional[bool] = None):
"""(Abstract async method) Send a message to another agent."""
def receive(
self,
message: Union[Dict[str, Any], str],
sender: "Agent",
request_reply: Optional[bool] = None,
) -> None:
"""Receive a message from another agent.
def receive(self, message: Union[Dict, str], sender: "Agent", request_reply: Optional[bool] = None):
"""(Abstract method) Receive a message from another agent."""
Args:
message (dict or str): the message received. If a dict, it should be
a JSON-serializable and follows the OpenAI's ChatCompletion schema.
sender (Agent): the sender of the message.
request_reply (bool): whether the sender requests a reply.
"""

async def a_receive(self, message: Union[Dict, str], sender: "Agent", request_reply: Optional[bool] = None):
"""(Abstract async method) Receive a message from another agent."""
async def a_receive(
self,
message: Union[Dict[str, Any], str],
sender: "Agent",
request_reply: Optional[bool] = None,
) -> None:
"""(Async) Receive a message from another agent.
def reset(self):
"""(Abstract method) Reset the agent."""
Args:
message (dict or str): the message received. If a dict, it should be
a JSON-serializable and follows the OpenAI's ChatCompletion schema.
sender (Agent): the sender of the message.
request_reply (bool): whether the sender requests a reply.
"""
...

def generate_reply(
self,
messages: Optional[List[Dict]] = None,
messages: Optional[List[Dict[str, Any]]] = None,
sender: Optional["Agent"] = None,
**kwargs,
) -> Union[str, Dict, None]:
"""(Abstract method) Generate a reply based on the received messages.
**kwargs: Any,
) -> Union[str, Dict[str, Any], None]:
"""Generate a reply based on the received messages.
Args:
messages (list[dict]): a list of messages received.
messages (list[dict]): a list of messages received from other agents.
The messages are dictionaries that are JSON-serializable and
follows the OpenAI's ChatCompletion schema.
sender: sender of an Agent instance.
Returns:
str or dict or None: the generated reply. If None, no reply is generated.
"""

async def a_generate_reply(
self,
messages: Optional[List[Dict]] = None,
messages: Optional[List[Dict[str, Any]]] = None,
sender: Optional["Agent"] = None,
**kwargs,
) -> Union[str, Dict, None]:
"""(Abstract async method) Generate a reply based on the received messages.
**kwargs: Any,
) -> Union[str, Dict[str, Any], None]:
"""(Async) Generate a reply based on the received messages.
Args:
messages (list[dict]): a list of messages received.
messages (list[dict]): a list of messages received from other agents.
The messages are dictionaries that are JSON-serializable and
follows the OpenAI's ChatCompletion schema.
sender: sender of an Agent instance.
Returns:
str or dict or None: the generated reply. If None, no reply is generated.
"""


@runtime_checkable
class LLMAgent(Agent, Protocol):
"""(In preview) A protocol for an LLM agent."""

@property
def system_message(self) -> str:
"""The system message of this agent."""

def update_system_message(self, system_message: str) -> None:
"""Update this agent's system message.
Args:
system_message (str): system message for inference.
"""
Loading

0 comments on commit 609ba7c

Please sign in to comment.