Skip to content

Commit

Permalink
Move agent creation into the runtime (autogenhub#89)
Browse files Browse the repository at this point in the history
* Move agent creation into the runtime

* update doc

* add test

* Remove limitation of subscriptions being same across namespaces

* constrain agent types to namespaces
  • Loading branch information
jackgerrits authored Jun 18, 2024
1 parent 6d7cbe0 commit 5b01f69
Show file tree
Hide file tree
Showing 30 changed files with 970 additions and 643 deletions.
5 changes: 3 additions & 2 deletions docs/src/guides/type-routed-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ from agnext.core import AgentRuntime, CancellationToken


class MyAgent(TypeRoutedAgent):
def __init__(self, name: str, runtime: AgentRuntime):
super().__init__(name, "I am a demo agent", runtime)
def __init__(self):
super().__init__(description="I am a demo agent")
self._received_count = 0

@message_handler()
async def on_text_message(
self, message: TextMessage | MultiModalMessage, cancellation_token: CancellationToken
) -> None:
self._received_count += 1
await self._publish_message(
TextMessage(
content=f"I received a message from {message.source}. Message received #{self._received_count}",
Expand Down
55 changes: 28 additions & 27 deletions examples/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from agnext.chat.patterns.group_chat_manager import GroupChatManager
from agnext.chat.types import PublishNow, TextMessage
from agnext.components import TypeRoutedAgent, message_handler
from agnext.core import AgentRuntime, CancellationToken
from agnext.core import AgentId, AgentRuntime, CancellationToken
from openai import AsyncAssistantEventHandler
from openai.types.beta.thread import ToolResources
from openai.types.beta.threads import Message, Text, TextDelta
Expand All @@ -29,17 +29,13 @@
class UserProxyAgent(TypeRoutedAgent): # type: ignore
def __init__( # type: ignore
self,
name: str,
runtime: AgentRuntime, # type: ignore
client: openai.AsyncClient, # type: ignore
assistant_id: str,
thread_id: str,
vector_store_id: str,
) -> None: # type: ignore
super().__init__(
name=name,
description="A human user",
runtime=runtime,
) # type: ignore
self._client = client
self._assistant_id = assistant_id
Expand Down Expand Up @@ -166,7 +162,7 @@ async def on_message_done(self, message: Message) -> None:
print("\n".join(citations))


def assistant_chat(runtime: AgentRuntime) -> UserProxyAgent: # type: ignore
def assistant_chat(runtime: AgentRuntime) -> AgentId:
oai_assistant = openai.beta.assistants.create(
model="gpt-4-turbo",
description="An AI assistant that helps with everyday tasks.",
Expand All @@ -177,30 +173,35 @@ def assistant_chat(runtime: AgentRuntime) -> UserProxyAgent: # type: ignore
thread = openai.beta.threads.create(
tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)
assistant = OpenAIAssistantAgent(
name="Assistant",
description="An AI assistant that helps with everyday tasks.",
runtime=runtime,
client=openai.AsyncClient(),
assistant_id=oai_assistant.id,
thread_id=thread.id,
assistant_event_handler_factory=lambda: EventHandler(),
assistant = runtime.register_and_get(
"Assistant",
lambda: OpenAIAssistantAgent(
description="An AI assistant that helps with everyday tasks.",
client=openai.AsyncClient(),
assistant_id=oai_assistant.id,
thread_id=thread.id,
assistant_event_handler_factory=lambda: EventHandler(),
),
)
user = UserProxyAgent(
name="User",
runtime=runtime,
client=openai.AsyncClient(),
assistant_id=oai_assistant.id,
thread_id=thread.id,
vector_store_id=vector_store.id,

user = runtime.register_and_get(
"User",
lambda: UserProxyAgent(
client=openai.AsyncClient(),
assistant_id=oai_assistant.id,
thread_id=thread.id,
vector_store_id=vector_store.id,
),
)
# Create a group chat manager to facilitate a turn-based conversation.
_ = GroupChatManager(
name="GroupChatManager",
description="A group chat manager.",
runtime=runtime,
memory=BufferedChatMemory(buffer_size=10),
participants=[assistant.id, user.id],
runtime.register(
"GroupChatManager",
lambda: GroupChatManager(
description="A group chat manager.",
runtime=runtime,
memory=BufferedChatMemory(buffer_size=10),
participants=[assistant, user],
),
)
return user

Expand Down
68 changes: 37 additions & 31 deletions examples/chat_room.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ def __init__( # type: ignore
self,
name: str,
description: str,
runtime: AgentRuntime, # type: ignore
background_story: str,
memory: ChatMemory, # type: ignore
model_client: ChatCompletionClient, # type: ignore
) -> None: # type: ignore
super().__init__(name, description, runtime)
super().__init__(description)
system_prompt = f"""Your name is {name}.
Your background story is:
{background_story}
Expand Down Expand Up @@ -86,40 +85,47 @@ async def on_chat_room_message(self, message: TextMessage, cancellation_token: C

# Define a chat room with participants -- the runtime is the chat room.
def chat_room(runtime: AgentRuntime, app: TextualChatApp) -> None: # type: ignore
_ = ChatRoomUserAgent(
name="User",
description="The user in the chat room.",
runtime=runtime,
app=app,
runtime.register(
"User",
lambda: ChatRoomUserAgent(
description="The user in the chat room.",
app=app,
),
)
alice = ChatRoomAgent(
name="Alice",
description="Alice in the chat room.",
runtime=runtime,
background_story="Alice is a software engineer who loves to code.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
alice = runtime.register_and_get_proxy(
"Alice",
lambda rt, id: ChatRoomAgent(
name=id.name,
description="Alice in the chat room.",
background_story="Alice is a software engineer who loves to code.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
),
)
bob = ChatRoomAgent(
name="Bob",
description="Bob in the chat room.",
runtime=runtime,
background_story="Bob is a data scientist who loves to analyze data.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
bob = runtime.register_and_get_proxy(
"Bob",
lambda rt, id: ChatRoomAgent(
name=id.name,
description="Bob in the chat room.",
background_story="Bob is a data scientist who loves to analyze data.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
),
)
charlie = ChatRoomAgent(
name="Charlie",
description="Charlie in the chat room.",
runtime=runtime,
background_story="Charlie is a designer who loves to create art.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
charlie = runtime.register_and_get_proxy(
"Charlie",
lambda rt, id: ChatRoomAgent(
name=id.name,
description="Charlie in the chat room.",
background_story="Charlie is a designer who loves to create art.",
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"), # type: ignore
),
)
app.welcoming_notice = f"""Welcome to the chat room demo with the following participants:
1. 👧 {alice.metadata['name']}: {alice.metadata['description']}
2. 👱🏼‍♂️ {bob.metadata['name']}: {bob.metadata['description']}
3. 👨🏾‍🦳 {charlie.metadata['name']}: {charlie.metadata['description']}
1. 👧 {alice.id.name}: {alice.metadata['description']}
2. 👱🏼‍♂️ {bob.id.name}: {bob.metadata['description']}
3. 👨🏾‍🦳 {charlie.id.name}: {charlie.metadata['description']}
Each participant decides on its own whether to respond to the latest message.
Expand Down
78 changes: 41 additions & 37 deletions examples/chess_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,54 +150,58 @@ def get_board_text() -> Annotated[str, "The current board state"]:
),
]

black = ChatCompletionAgent(
name="PlayerBlack",
description="Player playing black.",
runtime=runtime,
system_messages=[
SystemMessage(
content="You are a chess player and you play as black. "
"Use get_legal_moves() to get list of legal moves. "
"Use get_board() to get the current board state. "
"Think about your strategy and call make_move(thinking, move) to make a move."
),
],
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"),
tools=black_tools,
black = runtime.register_and_get(
"PlayerBlack",
lambda: ChatCompletionAgent(
description="Player playing black.",
system_messages=[
SystemMessage(
content="You are a chess player and you play as black. "
"Use get_legal_moves() to get list of legal moves. "
"Use get_board() to get the current board state. "
"Think about your strategy and call make_move(thinking, move) to make a move."
),
],
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"),
tools=black_tools,
),
)
white = ChatCompletionAgent(
name="PlayerWhite",
description="Player playing white.",
runtime=runtime,
system_messages=[
SystemMessage(
content="You are a chess player and you play as white. "
"Use get_legal_moves() to get list of legal moves. "
"Use get_board() to get the current board state. "
"Think about your strategy and call make_move(thinking, move) to make a move."
),
],
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"),
tools=white_tools,
white = runtime.register_and_get(
"PlayerWhite",
lambda: ChatCompletionAgent(
description="Player playing white.",
system_messages=[
SystemMessage(
content="You are a chess player and you play as white. "
"Use get_legal_moves() to get list of legal moves. "
"Use get_board() to get the current board state. "
"Think about your strategy and call make_move(thinking, move) to make a move."
),
],
memory=BufferedChatMemory(buffer_size=10),
model_client=OpenAI(model="gpt-4-turbo"),
tools=white_tools,
),
)
# Create a group chat manager for the chess game to orchestrate a turn-based
# conversation between the two agents.
_ = GroupChatManager(
name="ChessGame",
description="A chess game between two agents.",
runtime=runtime,
memory=BufferedChatMemory(buffer_size=10),
participants=[white.id, black.id], # white goes first
runtime.register(
"ChessGame",
lambda: GroupChatManager(
description="A chess game between two agents.",
runtime=runtime,
memory=BufferedChatMemory(buffer_size=10),
participants=[white, black], # white goes first
),
)


async def main() -> None:
runtime = SingleThreadedAgentRuntime()
chess_game(runtime)
# Publish an initial message to trigger the group chat manager to start orchestration.
runtime.publish_message(TextMessage(content="Game started.", source="System"))
runtime.publish_message(TextMessage(content="Game started.", source="System"), namespace="default")
while True:
await runtime.process_next()
await asyncio.sleep(1)
Expand Down
89 changes: 47 additions & 42 deletions examples/coder_reviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,56 @@


def coder_reviewer(runtime: AgentRuntime, app: TextualChatApp) -> None:
_ = TextualUserAgent(
name="Human",
description="A human user that provides a problem statement.",
runtime=runtime,
app=app,
runtime.register(
"Human",
lambda: TextualUserAgent(
description="A human user that provides a problem statement.",
app=app,
),
)
coder = ChatCompletionAgent(
name="Coder",
description="An agent that writes code",
runtime=runtime,
system_messages=[
SystemMessage(
"You are a coder. You can write code to solve problems.\n"
"Work with the reviewer to improve your code."
)
],
model_client=OpenAI(model="gpt-4-turbo"),
memory=BufferedChatMemory(buffer_size=10),
coder = runtime.register_and_get_proxy(
"Coder",
lambda: ChatCompletionAgent(
description="An agent that writes code",
system_messages=[
SystemMessage(
"You are a coder. You can write code to solve problems.\n"
"Work with the reviewer to improve your code."
)
],
model_client=OpenAI(model="gpt-4-turbo"),
memory=BufferedChatMemory(buffer_size=10),
),
)
reviewer = ChatCompletionAgent(
name="Reviewer",
description="An agent that reviews code",
runtime=runtime,
system_messages=[
SystemMessage(
"You are a code reviewer. You focus on correctness, efficiency and safety of the code.\n"
"Respond using the following format:\n"
"Code Review:\n"
"Correctness: <Your comments>\n"
"Efficiency: <Your comments>\n"
"Safety: <Your comments>\n"
"Approval: <APPROVE or REVISE>\n"
"Suggested Changes: <Your comments>"
)
],
model_client=OpenAI(model="gpt-4-turbo"),
memory=BufferedChatMemory(buffer_size=10),
reviewer = runtime.register_and_get_proxy(
"Reviewer",
lambda: ChatCompletionAgent(
description="An agent that reviews code",
system_messages=[
SystemMessage(
"You are a code reviewer. You focus on correctness, efficiency and safety of the code.\n"
"Respond using the following format:\n"
"Code Review:\n"
"Correctness: <Your comments>\n"
"Efficiency: <Your comments>\n"
"Safety: <Your comments>\n"
"Approval: <APPROVE or REVISE>\n"
"Suggested Changes: <Your comments>"
)
],
model_client=OpenAI(model="gpt-4-turbo"),
memory=BufferedChatMemory(buffer_size=10),
),
)
_ = GroupChatManager(
name="Manager",
description="A manager that orchestrates a back-and-forth converation between a coder and a reviewer.",
runtime=runtime,
participants=[coder.id, reviewer.id], # The order of the participants indicates the order of speaking.
memory=BufferedChatMemory(buffer_size=10),
termination_word="APPROVE",
runtime.register(
"Manager",
lambda: GroupChatManager(
description="A manager that orchestrates a back-and-forth converation between a coder and a reviewer.",
runtime=runtime,
participants=[coder.id, reviewer.id], # The order of the participants indicates the order of speaking.
memory=BufferedChatMemory(buffer_size=10),
termination_word="APPROVE",
),
)
app.welcoming_notice = f"""Welcome to the coder-reviewer demo with the following roles:
1. 🤖 {coder.metadata['name']}: {coder.metadata['description']}
Expand Down
Loading

0 comments on commit 5b01f69

Please sign in to comment.