chore: deprecate old agent messaging (#9120)
This commit is contained in:
committed by
Caren Thomas
parent
cd7e80acc3
commit
3fdf2b6c79
@@ -1,20 +1,14 @@
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
from letta.config import LettaConfig
|
||||
from letta.schemas.agent import CreateAgent
|
||||
from letta.schemas.block import CreateBlock
|
||||
from letta.schemas.group import (
|
||||
DynamicManager,
|
||||
DynamicManagerUpdate,
|
||||
GroupCreate,
|
||||
GroupUpdate,
|
||||
ManagerType,
|
||||
RoundRobinManagerUpdate,
|
||||
SupervisorManager,
|
||||
)
|
||||
from letta.schemas.message import MessageCreate
|
||||
from letta.server.server import SyncServer
|
||||
|
||||
|
||||
@@ -125,30 +119,6 @@ async def manager_agent(server, default_user):
|
||||
yield agent_scooby
|
||||
|
||||
|
||||
async def test_empty_group(server, default_user):
|
||||
group = await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description="This is a group chat between best friends all like to hang out together. In their free time they like to solve mysteries.",
|
||||
agent_ids=[],
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
with pytest.raises(ValueError, match="Empty group"):
|
||||
await server.send_group_message_to_agent(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
input_messages=[
|
||||
MessageCreate(
|
||||
role="user",
|
||||
content="what is everyone up to for the holidays?",
|
||||
),
|
||||
],
|
||||
stream_steps=False,
|
||||
stream_tokens=False,
|
||||
)
|
||||
await server.group_manager.delete_group_async(group_id=group.id, actor=default_user)
|
||||
|
||||
|
||||
async def test_modify_group_pattern(server, default_user, four_participant_agents, manager_agent):
|
||||
group = await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
@@ -195,243 +165,3 @@ async def test_list_agent_groups(server, default_user, four_participant_agents):
|
||||
|
||||
await server.group_manager.delete_group_async(group_id=group_a.id, actor=default_user)
|
||||
await server.group_manager.delete_group_async(group_id=group_b.id, actor=default_user)
|
||||
|
||||
|
||||
async def test_round_robin(server, default_user, four_participant_agents):
|
||||
description = (
|
||||
"This is a group chat between best friends all like to hang out together. In their free time they like to solve mysteries."
|
||||
)
|
||||
group = await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description=description,
|
||||
agent_ids=[agent.id for agent in four_participant_agents],
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
|
||||
# verify group creation
|
||||
assert group.manager_type == ManagerType.round_robin
|
||||
assert group.description == description
|
||||
assert group.agent_ids == [agent.id for agent in four_participant_agents]
|
||||
assert group.max_turns is None
|
||||
assert group.manager_agent_id is None
|
||||
assert group.termination_token is None
|
||||
|
||||
try:
|
||||
server.group_manager.reset_messages(group_id=group.id, actor=default_user)
|
||||
response = await server.send_group_message_to_agent(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
input_messages=[
|
||||
MessageCreate(
|
||||
role="user",
|
||||
content="what is everyone up to for the holidays?",
|
||||
),
|
||||
],
|
||||
stream_steps=False,
|
||||
stream_tokens=False,
|
||||
)
|
||||
assert response.usage.step_count == len(group.agent_ids)
|
||||
assert len(response.messages) == response.usage.step_count * 2
|
||||
for i, message in enumerate(response.messages):
|
||||
assert message.message_type == "reasoning_message" if i % 2 == 0 else "assistant_message"
|
||||
assert message.name == four_participant_agents[i // 2].name
|
||||
|
||||
for agent_id in group.agent_ids:
|
||||
agent_messages = await server.get_agent_recall(
|
||||
user_id=default_user.id,
|
||||
agent_id=agent_id,
|
||||
group_id=group.id,
|
||||
reverse=True,
|
||||
return_message_object=False,
|
||||
)
|
||||
assert len(agent_messages) == len(group.agent_ids) + 2 # add one for user message, one for reasoning message
|
||||
|
||||
# TODO: filter this to return a clean conversation history
|
||||
messages = server.group_manager.list_group_messages(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
)
|
||||
assert len(messages) == (len(group.agent_ids) + 2) * len(group.agent_ids)
|
||||
|
||||
max_turns = 3
|
||||
group = await server.group_manager.modify_group_async(
|
||||
group_id=group.id,
|
||||
group_update=GroupUpdate(
|
||||
agent_ids=[agent.id for agent in four_participant_agents][::-1],
|
||||
manager_config=RoundRobinManagerUpdate(
|
||||
max_turns=max_turns,
|
||||
),
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
assert group.manager_type == ManagerType.round_robin
|
||||
assert group.description == description
|
||||
assert group.agent_ids == [agent.id for agent in four_participant_agents][::-1]
|
||||
assert group.max_turns == max_turns
|
||||
assert group.manager_agent_id is None
|
||||
assert group.termination_token is None
|
||||
|
||||
server.group_manager.reset_messages(group_id=group.id, actor=default_user)
|
||||
|
||||
response = await server.send_group_message_to_agent(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
input_messages=[
|
||||
MessageCreate(
|
||||
role="user",
|
||||
content="when should we plan our next adventure?",
|
||||
),
|
||||
],
|
||||
stream_steps=False,
|
||||
stream_tokens=False,
|
||||
)
|
||||
assert response.usage.step_count == max_turns
|
||||
assert len(response.messages) == max_turns * 2
|
||||
|
||||
for i, message in enumerate(response.messages):
|
||||
assert message.message_type == "reasoning_message" if i % 2 == 0 else "assistant_message"
|
||||
assert message.name == four_participant_agents[::-1][i // 2].name
|
||||
|
||||
for i in range(len(group.agent_ids)):
|
||||
agent_messages = await server.get_agent_recall(
|
||||
user_id=default_user.id,
|
||||
agent_id=group.agent_ids[i],
|
||||
group_id=group.id,
|
||||
reverse=True,
|
||||
return_message_object=False,
|
||||
)
|
||||
expected_message_count = max_turns + 1 if i >= max_turns else max_turns + 2
|
||||
assert len(agent_messages) == expected_message_count
|
||||
|
||||
finally:
|
||||
await server.group_manager.delete_group_async(group_id=group.id, actor=default_user)
|
||||
|
||||
|
||||
async def test_supervisor(server, default_user, four_participant_agents):
|
||||
agent_scrappy = await server.create_agent_async(
|
||||
request=CreateAgent(
|
||||
name="shaggy",
|
||||
memory_blocks=[
|
||||
CreateBlock(
|
||||
label="persona",
|
||||
value="You are a puppy operations agent for Letta and you help run multi-agent group chats. Your role is to supervise the group, sending messages and aggregating the responses.",
|
||||
),
|
||||
CreateBlock(
|
||||
label="human",
|
||||
value="",
|
||||
),
|
||||
],
|
||||
model="openai/gpt-4o-mini",
|
||||
embedding="openai/text-embedding-3-small",
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
|
||||
group = await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description="This is a group chat between best friends all like to hang out together. In their free time they like to solve mysteries.",
|
||||
agent_ids=[agent.id for agent in four_participant_agents],
|
||||
manager_config=SupervisorManager(
|
||||
manager_agent_id=agent_scrappy.id,
|
||||
),
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
try:
|
||||
response = await server.send_group_message_to_agent(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
input_messages=[
|
||||
MessageCreate(
|
||||
role="user",
|
||||
content="ask everyone what they like to do for fun and then come up with an activity for everyone to do together.",
|
||||
),
|
||||
],
|
||||
stream_steps=False,
|
||||
stream_tokens=False,
|
||||
)
|
||||
assert response.usage.step_count == 2
|
||||
assert len(response.messages) == 5
|
||||
|
||||
# verify tool call
|
||||
assert response.messages[0].message_type == "reasoning_message"
|
||||
assert (
|
||||
response.messages[1].message_type == "tool_call_message"
|
||||
and response.messages[1].tool_call.name == "send_message_to_all_agents_in_group"
|
||||
)
|
||||
assert response.messages[2].message_type == "tool_return_message" and len(eval(response.messages[2].tool_return)) == len(
|
||||
four_participant_agents
|
||||
)
|
||||
assert response.messages[3].message_type == "reasoning_message"
|
||||
assert response.messages[4].message_type == "assistant_message"
|
||||
|
||||
finally:
|
||||
await server.group_manager.delete_group_async(group_id=group.id, actor=default_user)
|
||||
server.agent_manager.delete_agent(agent_id=agent_scrappy.id, actor=default_user)
|
||||
|
||||
|
||||
@pytest.mark.flaky(max_runs=2)
|
||||
async def test_dynamic_group_chat(server, default_user, manager_agent, four_participant_agents):
|
||||
description = (
|
||||
"This is a group chat between best friends all like to hang out together. In their free time they like to solve mysteries."
|
||||
)
|
||||
# error on duplicate agent in participant list
|
||||
with pytest.raises(ValueError, match="Duplicate agent ids"):
|
||||
await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description=description,
|
||||
agent_ids=[agent.id for agent in four_participant_agents] + [four_participant_agents[0].id],
|
||||
manager_config=DynamicManager(
|
||||
manager_agent_id=manager_agent.id,
|
||||
),
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
# error on duplicate agent names
|
||||
duplicate_agent_shaggy = server.create_agent(
|
||||
request=CreateAgent(
|
||||
name="shaggy",
|
||||
model="openai/gpt-4o-mini",
|
||||
embedding="openai/text-embedding-3-small",
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
with pytest.raises(ValueError, match="Duplicate agent names"):
|
||||
await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description=description,
|
||||
agent_ids=[agent.id for agent in four_participant_agents] + [duplicate_agent_shaggy.id],
|
||||
manager_config=DynamicManager(
|
||||
manager_agent_id=manager_agent.id,
|
||||
),
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
server.agent_manager.delete_agent(duplicate_agent_shaggy.id, actor=default_user)
|
||||
|
||||
group = await server.group_manager.create_group_async(
|
||||
group=GroupCreate(
|
||||
description=description,
|
||||
agent_ids=[agent.id for agent in four_participant_agents],
|
||||
manager_config=DynamicManager(
|
||||
manager_agent_id=manager_agent.id,
|
||||
),
|
||||
),
|
||||
actor=default_user,
|
||||
)
|
||||
try:
|
||||
response = await server.send_group_message_to_agent(
|
||||
group_id=group.id,
|
||||
actor=default_user,
|
||||
input_messages=[
|
||||
MessageCreate(role="user", content="what is everyone up to for the holidays?"),
|
||||
],
|
||||
stream_steps=False,
|
||||
stream_tokens=False,
|
||||
)
|
||||
assert response.usage.step_count == len(four_participant_agents) * 2
|
||||
assert len(response.messages) == response.usage.step_count * 2
|
||||
|
||||
finally:
|
||||
await server.group_manager.delete_group_async(group_id=group.id, actor=default_user)
|
||||
|
||||
Reference in New Issue
Block a user