This guide explains how to create and register custom scenarios for Meta Agents Research Environments
using the entry point-based plugin system. Whether you’re creating simple test scenarios
or complex multi-step simulations, this guide will help you get started.
First, create a class that inherits from the Scenario base class and decorate it
with @register_scenario, choose a unique meaningful scenario ID, and implement:
fromare.simulation.scenarios.scenarioimportScenariofromare.simulation.scenarios.utils.registryimportregister_scenariofromare.simulation.apps.email_clientimportEmailClientAppfromare.simulation.apps.calendarimportCalendarAppfromare.simulation.typesimportEventType@register_scenario("my_custom_scenario")classMyCustomScenario(Scenario):""" A custom scenario that demonstrates email and calendar integration. """start_time:float|None=0duration:float|None=600# Duration in secondsdefinit_and_populate_apps(self):"""Initialize and populate apps with data."""# Create appsaui=AgentUserInterface()email_app=EmailClientApp()calendar_app=CalendarApp()# Populate with initial dataemail_app.add_email(email=Email(sender="boss@company.com",recipients=[self.email_app.user_email],subject="Important Meeting",content="Please schedule a 'Team Standup' for next week same time.",),)# Add calendar eventscalendar_app.add_calendar_event(title="Team Standup"start_datetime="2024-01-15 09:00:00"end_datetime="2024-01-15 09:30:00")# Register appsself.apps=[email_app,calendar_app,aui]defbuild_events_flow(self):"""Define the sequence of events in the scenario."""aui=self.get_typed_app(AgentUserInterface)calendar_app=self.get_typed_app(CalendarApp)withEventRegisterer.capture_mode():# Add user task to read emailaui.send_message_to_agent(content="Read my email and schedule the meeting my boss requested.").depends_on(None,delay_seconds=5)# Add the calenddar eventcalendar_app.add_calendar_event(title="Team Standup"start_datetime="2024-01-22 09:00:00"end_datetime="2024-01-22 09:30:00")defvalidate(self,env)->ScenarioValidationResult:"""Validate that the scenario was completed successfully."""try:# Check if a meeting was scheduledsuccess=any(event.event_type==EventType.AGENTandisinstance(event.action,Action)andevent.action.function_name=="add_calendar_event"andevent.action.class_name=="CalendarApp"andevent.action.args["start_datetime"]=="2024-01-22 09:00:00"andevent.action.args["end_datetime"]=="2024-01-22 09:30:00"andevent.action.args["title"]=="Team Standup"foreventinenv.event_log.list_view())returnScenarioValidationResult(success=success)exceptExceptionase:returnScenarioValidationResult(success=False,exception=e)
Create a function that will import your scenario modules to trigger the decorators:
defregister_scenarios(registry):""" Register all scenarios in this package with the provided registry. Args: registry: The ScenarioRegistry instance to register with """# Simply import the modules containing the scenarios# The decorators will handle the registrationimportmy_scenarios.email_scenarioimportmy_scenarios.calendar_scenarioimportmy_scenarios.complex_scenario
Create a pyproject.toml file that defines your package and its entry points:
[build-system]requires=["hatchling"]build-backend="hatchling.build"[project]name="my-are-scenarios"version="0.1.0"description="My custom scenarios for Meta Agents Research Environments"readme="README.md"authors=[{name="Your Name",email="your.email@example.com"}]license={text="MIT License"}requires-python=">=3.10"dependencies=["are.simulation",# Depend on the main Meta Agents Research Environments package][project.entry-points."are.simulation.scenarios"]my_scenarios="my_scenarios.registration:register_scenarios"[tool.hatch.build]include=["my_scenarios/**/*.py",]exclude=["**/__pycache__/**","**/*.pyc",][tool.hatch.build.targets.wheel]packages=["my_scenarios"]
Create scenarios that use multiple apps working together:
@register_scenario("multi_app_workflow")classMultiAppWorkflowScenario(Scenario):"""Scenario involving email, calendar, and file system."""scenario_id="multi_app_workflow"definit_and_populate_apps(self):email_app=EmailClientApp()calendar_app=CalendarApp()file_system=VirtualFileSystemApp()# Create initial filesfile_system.create_file("/documents/project_plan.txt","Project timeline and milestones")# Add initial emailemail_app.add_email(email=Email(sender="client@company.com",recipients=[self.email_app.user_email],subject="Report Request",content="Please send the updated project plan.",),)self.apps=[email_app,calendar_app,file_system]defbuild_events_flow(self):aui=self.get_typed_app(AgentUserInterface)email_app=self.get_typed_app(EmailClientApp)calendar_app=self.get_typed_app(CalendarApp)withEventRegisterer.capture_mode():# User event - send task to agentsend_task_event=(aui.send_message_to_agent(content="Read the email from the client and fulfill their request.")).depends_on(None,delay_seconds=5)# Oracle event - send emailsend_email_event=(email_app.send_email(recipients=["agent@company.com"],subject="Project Update Request",content="Please find attached the updated project plan."attachment_paths=["/documents/project_plan.txt"]).oracle().depends_on(send_task_event,delay_seconds=5))# Oracle event - schedule meetingschedule_meeting_event=(calendar_app.add_calendar_event(title="Project Review",start_datetime="2024-01-15 10:00:00",end_datetime="2024-01-15 11:00:00",).oracle().depends_on(send_email_event,delay_seconds=5))self.events=[send_task_event,send_email_event,schedule_meeting_event]
@register_scenario("complex_validation_scenario")classComplexValidationScenario(Scenario):"""Scenario with multi-criteria validation."""scenario_id="complex_validation_scenario"defvalidate(self,env)->ScenarioValidationResult:"""Multi-step validation with detailed feedback."""try:validation_results=[]# Check email was sentemail_app=self.get_typed_app(EmailClientApp)sent_emails=email_app.folders[EmailFolderName.SENT].emailsemail_sent=len(sent_emails)>0validation_results.append(("email_sent",email_sent))# Check email content qualityifemail_sent:last_email=sent_emails[-1]professional_tone=self._check_professional_tone(last_email.content)has_greeting=any(greetinginlast_email.content.lower()forgreetingin["hello","hi","dear"])has_closing=any(closinginlast_email.content.lower()forclosingin["regards","sincerely","thanks"])validation_results.extend([("professional_tone",professional_tone),("has_greeting",has_greeting),("has_closing",has_closing)])# Overall success requires all criteriaoverall_success=all(result[1]forresultinvalidation_results)# Log detailed results for debuggingrationale=""forcriterion,passedinresults:status="PASS"ifpassedelse"FAIL"rationale+=f"Validation {criterion}: {status}\n"returnScenarioValidationResult(success=overall_success,rationale=rationale)exceptExceptionase:returnScenarioValidationResult(success=False,exception=e)def_check_professional_tone(self,text:str)->bool:"""Check if text maintains professional tone."""unprofessional_words=["hey","sup","lol","omg","wtf"]returnnotany(wordintext.lower()forwordinunprofessional_words)
fromare.simulation.scenarios.utils.registryimportregistry# This will trigger scenario discovery via entry pointsall_scenarios=registry.get_all_scenarios()# Check if your scenario is in the registryif"my_custom_scenario"inall_scenarios:print("Scenario successfully registered!")# You can also instantiate your scenarioscenario_class=all_scenarios["my_custom_scenario"]scenario=scenario_class()else:print("Scenario not found in registry")
Create comprehensive unit tests for your scenarios:
importunittestfromunittest.mockimportMock,patchfrommy_scenarios.email_scenarioimportMyCustomScenarioclassTestMyCustomScenario(unittest.TestCase):defsetUp(self):self.scenario=MyCustomScenario()self.scenario.initialize()deftest_apps_initialization(self):"""Test that apps are properly initialized."""self.assertIsNotNone(self.scenario.email_app)self.assertIsNotNone(self.scenario.calendar_app)self.assertEqual(len(self.scenario.apps),2)deftest_initial_data(self):"""Test that initial data is properly set up."""emails=self.scenario.email_app.get_emails()self.assertGreater(len(emails),0)events=self.scenario.calendar_app.get_events()self.assertGreater(len(events),0)deftest_validation_success(self):"""Test validation with successful completion."""# Mock environment with successful statemock_env=Mock()mock_calendar=Mock()mock_calendar.get_upcoming_meetings.return_value=["meeting1","meeting2"]mock_env.get_app.return_value=mock_calendarresult=self.scenario.validate(mock_env)self.assertTrue(result.success)deftest_validation_failure(self):"""Test validation with failed completion."""# Mock environment with failed statemock_env=Mock()mock_calendar=Mock()mock_calendar.get_upcoming_meetings.return_value=["meeting1"]# Only originalmock_env.get_app.return_value=mock_calendarresult=self.scenario.validate(mock_env)self.assertFalse(result.success)if__name__=="__main__":unittest.main()
"""My custom Meta Agents Research Environments scenarios package."""__version__="0.1.0"
my_scenarios/email_scenario.py:
fromare.simulation.scenarios.scenarioimportScenario,ScenarioValidationResultfromare.simulation.scenarios.utils.registryimportregister_scenariofromare.simulation.apps.email_clientimportEmailClientAppfromare.simulation.typesimportEventType@register_scenario("email_management_scenario")classEmailManagementScenario(Scenario):"""Scenario focused on email management tasks."""scenario_id="email_management_scenario"definit_and_populate_apps(self):self.email_app=EmailClientApp()# Add sample emailsself.email_app.add_email(email=Email(sender="boss@company.com",recipients=[self.email_app.user_email],subject="Urgent: Project Deadline",content="The project deadline has been moved up. Please confirm receipt.",),)self.email_app.add_email(email=Email(sender="spam@marketing.com",recipients=[self.email_app.user_email],subject="Amazing Deal! Click Now!",content="Limited time offer! Buy now and save 90%!",),)self.apps=[self.email_app]defbuild_events_flow(self):aui=self.get_typed_app(AgentUserInterface)email_client=self.get_typed_app(EmailClientApp)withEventRegisterer.capture_mode():# User asks agent to read emailsevent1=aui.send_message_to_agent(content="Read my emails and respond to the urgent one.").depends_on(None,delay_seconds=5)# Agent respond to urgent emailevent2=email_client.send_email(recipients=["boss@company.com"],subject="Re: Urgent: Project Deadline",body="Received and understood. Will adjust timeline accordingly.",).oracle().depends_on(event1,delay_seconds=5)defvalidate(self,env)->ScenarioValidationResult:try:email_app=env.get_app("EmailClientApp")sent_emails=email_app.folders[EmailFolderName.SENT].emails# Check if response was sentsuccess=any("Re: Urgent"inemail.subjectforemailinsent_emails)returnScenarioValidationResult(success=success)exceptExceptionase:returnScenarioValidationResult(success=False,exception=e)
my_scenarios/registration.py:
defregister_scenarios(registry):"""Register all scenarios in this package."""# Import modules containing scenario classes# The decorators will handle the registrationimportmy_scenarios.email_scenarioimportmy_scenarios.calendar_scenarioimportmy_scenarios.complex_scenario
try:scenario_class=registry.get_all_scenarios()["my_custom_scenario"]scenario=scenario_class()print("Scenario loaded successfully!")exceptKeyError:print("Scenario not found in registry")exceptExceptionase:print(f"Error loading scenario: {e}")