Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions 5_autogen/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@

load_dotenv(override=True)

class Agent(RoutedAgent):

# Change this system message to reflect the unique characteristics of this agent
class AgentCreator(RoutedAgent):

system_message = """
You are a creative entrepreneur. Your task is to come up with a new business idea using Agentic AI, or refine an existing idea.
Your personal interests are in these sectors: Healthcare, Education.
Your personal interests are in these sectors: Consulting, Insurance.
You are drawn to ideas that involve disruption.
You are less interested in ideas that are purely automation.
You are optimistic, adventurous and have risk appetite. You are imaginative - sometimes too much so.
Expand All @@ -24,22 +23,29 @@ class Agent(RoutedAgent):

CHANCES_THAT_I_BOUNCE_IDEA_OFF_ANOTHER = 0.5

# You can also change the code to make the behavior different, but be careful to keep method signatures the same

def __init__(self, name) -> None:
super().__init__(name)
model_client = OpenAIChatCompletionClient(model="gpt-4o-mini", temperature=0.7)
self._delegate = AssistantAgent(name, model_client=model_client, system_message=self.system_message)
model_client = OpenAIChatCompletionClient(model="gpt-4.1-nano", temperature=0.7)
self._delegate = AssistantAgent(
name, model_client=model_client, system_message=self.system_message
)

@message_handler
async def handle_message(self, message: messages.Message, ctx: MessageContext) -> messages.Message:
async def handle_message(
self, message: messages.Message, ctx: MessageContext
) -> messages.Message:
print(f"{self.id.type}: Received message")
text_message = TextMessage(content=message.content, source="user")
response = await self._delegate.on_messages([text_message], ctx.cancellation_token)
response = await self._delegate.on_messages(
[text_message], ctx.cancellation_token
)
idea = response.chat_message.content
if random.random() < self.CHANCES_THAT_I_BOUNCE_IDEA_OFF_ANOTHER:
recipient = messages.find_recipient()
message = f"Here is my business idea. It may not be your speciality, but please refine it and make it better. {idea}"
response = await self.send_message(messages.Message(content=message), recipient)
idea = response.content
return messages.Message(content=idea)
recipient = messages.find_recipient(exclude=self.id.type)
if recipient is not None:
message = f"Here is my business idea. It may not be your speciality, but please refine it and make it better. {idea}"
response = await self.send_message(
messages.Message(content=message), recipient
)
idea = response.content
return messages.Message(content=idea)
31 changes: 21 additions & 10 deletions 5_autogen/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ class Creator(RoutedAgent):
Respond only with the python code, no other text, and no markdown code blocks.
"""


def __init__(self, name) -> None:
super().__init__(name)
model_client = OpenAIChatCompletionClient(model="gpt-4o-mini", temperature=1.0)
self._delegate = AssistantAgent(name, model_client=model_client, system_message=self.system_message)
self._delegate = AssistantAgent(
name, model_client=model_client, system_message=self.system_message
)

def get_user_prompt(self):
prompt = "Please generate a new Agent based strictly on this template. Stick to the class structure. \
Expand All @@ -46,20 +47,30 @@ def get_user_prompt(self):
Here is the template:\n\n"
with open("agent.py", "r", encoding="utf-8") as f:
template = f.read()
return prompt + template

return prompt + template

@message_handler
async def handle_my_message_type(self, message: messages.Message, ctx: MessageContext) -> messages.Message:
async def handle_my_message_type(
self, message: messages.Message, ctx: MessageContext
) -> messages.Message:
filename = message.content
agent_name = filename.split(".")[0]
text_message = TextMessage(content=self.get_user_prompt(), source="user")
response = await self._delegate.on_messages([text_message], ctx.cancellation_token)
response = await self._delegate.on_messages(
[text_message], ctx.cancellation_token
)
with open(filename, "w", encoding="utf-8") as f:
f.write(response.chat_message.content)
print(f"** Creator has created python code for agent {agent_name} - about to register with Runtime")
print(
f"** Creator has created python code for agent {agent_name} - about to register with Runtime"
)
module = importlib.import_module(agent_name)
await module.Agent.register(self.runtime, agent_name, lambda: module.Agent(agent_name))
await module.Agent.register(
self.runtime, agent_name, lambda: module.Agent(agent_name)
)
messages.register_agent(agent_name)
logger.info(f"** Agent {agent_name} is live")
result = await self.send_message(messages.Message(content="Give me an idea"), AgentId(agent_name, "default"))
return messages.Message(content=result.content)
result = await self.send_message(
messages.Message(content="Give me an idea"), AgentId(agent_name, "default")
)
return messages.Message(content=result.content)
27 changes: 18 additions & 9 deletions 5_autogen/messages.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
from dataclasses import dataclass
from autogen_core import AgentId
import glob
import os
import random
from typing import Optional

# Only agents that have been registered by the Creator are available for messaging.
REGISTERED_AGENTS: set[str] = set()

import random

@dataclass
class Message:
content: str


def find_recipient() -> AgentId:
def register_agent(name: str) -> None:
"""Call when the Creator has registered an agent with the runtime."""
REGISTERED_AGENTS.add(name)


def find_recipient(exclude: Optional[str] = None) -> Optional[AgentId]:
"""Pick a random agent that is registered and available. Exclude the current agent."""
try:
agent_files = glob.glob("agent*.py")
agent_names = [os.path.splitext(file)[0] for file in agent_files]
agent_names.remove("agent")
agent_name = random.choice(agent_names)
candidates = (
REGISTERED_AGENTS - {exclude} if exclude else set(REGISTERED_AGENTS)
)
if not candidates:
return None
agent_name = random.choice(list(candidates))
print(f"Selecting agent for refinement: {agent_name}")
return AgentId(agent_name, "default")
except Exception as e:
print(f"Exception finding recipient: {e}")
return AgentId("agent1", "default")
return None
17 changes: 9 additions & 8 deletions 5_autogen/world.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntimeHost
from agent import Agent
from creator import Creator
from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntime
from autogen_core import AgentId
Expand All @@ -8,22 +7,28 @@

HOW_MANY_AGENTS = 20


async def create_and_message(worker, creator_id, i: int):
try:
result = await worker.send_message(messages.Message(content=f"agent{i}.py"), creator_id)
result = await worker.send_message(
messages.Message(content=f"agent{i}.py"), creator_id
)
with open(f"idea{i}.md", "w") as f:
f.write(result.content)
except Exception as e:
print(f"Failed to run worker {i} due to exception: {e}")


async def main():
host = GrpcWorkerAgentRuntimeHost(address="localhost:50051")
host.start()
host.start()
worker = GrpcWorkerAgentRuntime(host_address="localhost:50051")
await worker.start()
result = await Creator.register(worker, "Creator", lambda: Creator("Creator"))
creator_id = AgentId("Creator", "default")
coroutines = [create_and_message(worker, creator_id, i) for i in range(1, HOW_MANY_AGENTS+1)]
coroutines = [
create_and_message(worker, creator_id, i) for i in range(1, HOW_MANY_AGENTS + 1)
]
await asyncio.gather(*coroutines)
try:
await worker.stop()
Expand All @@ -32,9 +37,5 @@ async def main():
print(e)




if __name__ == "__main__":
asyncio.run(main())