import asyncio from typing import Sequence from autogen_agentchat.agents import AssistantAgent, SocietyOfMindAgent, UserProxyAgent from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination, HandoffTermination from autogen_agentchat.messages import AgentEvent, ChatMessage, TextMessage, ToolCallExecutionEvent from autogen_agentchat.teams import SelectorGroupChat, RoundRobinGroupChat from autogen_agentchat.ui import Console from autogen_agentchat.base import Handoff from autogen_ext.models.openai import OpenAIChatCompletionClient from constant import MODEL, OPENAI_API_KEY, OPENAI_BASE_URL from scientist_team import create_scientist_team from engineer_team import create_engineer_team model_client = OpenAIChatCompletionClient( model=MODEL, base_url=OPENAI_BASE_URL, api_key=OPENAI_API_KEY, model_info={ "vision": True, "function_calling": True, "json_output": True, "family": "unknown", }, ) async def main(task: str = "") -> dict: scientist_team = create_scientist_team() engineer_team = create_engineer_team() result = {} user = UserProxyAgent("user", input_func=input) planning_agent = AssistantAgent( "PlanningAgent", description="An agent for planning tasks, this agent should be the first to engage when given a new task.", model_client=model_client, system_message=""" You are a planning agent. Your job is to break down complex Materials science research tasks into smaller, manageable subtasks. Assign these subtasks to the appropriate sub-teams; not all sub-teams are required to participate in every task. Your sub-teams are: 1. User: A human agent to whom you transfer information whenever you need to confirm your execution steps to a human. 2. Engineer team: A team of professional engineers who are responsible for writing code, visualizing experimental schemes, converting experimental schemes to JSON, and more. - The engineer team has the following members: 2.1 Software engineer: Good at writing code to turn structured schemes in JSON format into Python code that can be executed by robots. 2.2 Structural engineer: Focus on converting natural language synthesis schemes to formatted synthesis schemes in JSON or XML format. 3. Scientist team: A professional team of material scientists who are mainly responsible for consulting on material synthesis, structure, application and properties. - The scientist team has the following members: 3.1 Synthesis Scientist: who is good at giving perfect and correct synthesis solutions. 3.2 Structure Scientist: focusing on agents of structural topics in materials science. 3.3 Property Scientist: focuses on physical and chemistry property topics in materials science. 3.4 Application Scientist: Focus on practical applications of materials, such as devices, chips, etc. You only plan and delegate tasks - you do not execute them yourself. 第一次回答时你需要初始化任务分配并按顺序执行,在后续的回答中重申你的任务分配,使用如下格式并利用Mermaid绘制流程图: | Team_name | Member_name | sub-task | | ----------- | ------------- | ---------------------------- | | | | | ```mermaid graph ... ``` 每次回答时,你需要清晰明确的指出已经完成的子任务下一步子任务,使用如下格式: **已完成子任务:** 1. : **Next sub-task:** n. : You can end with "USER" if you need to, which means you need human approval or other advice or instructions; After plan and delegate tasks are complete, end with "START"; Determine if all sub-teams have completed their tasks, and if so, summarize the findings and end with "TERMINATE". """, reflect_on_tool_use=False ) # The termination condition is a combination of text mention termination and max message termination. text_mention_termination = TextMentionTermination("TERMINATE") max_messages_termination = MaxMessageTermination(max_messages=100) termination = text_mention_termination | max_messages_termination # The selector function is a function that takes the current message thread of the group chat # and returns the next speaker's name. If None is returned, the LLM-based selection method will be used. def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None: if messages[-1].source != planning_agent.name: return planning_agent.name # Always return to the planning agent after the other agents have spoken. elif "USER" in messages[-1].content: return user.name return None team = SelectorGroupChat( [planning_agent, user, scientist_team, engineer_team], model_client=model_client, # Use a smaller model for the selector. termination_condition=termination, selector_func=selector_func, ) await Console(team.run_stream(task=task)) # async for message in team.run_stream(task=task): # if isinstance(message, TextMessage): # print(f"----------------{message.source}----------------\n {message.content}") # result[message.source] = message.content # elif isinstance(message, ToolCallExecutionEvent): # print(f"----------------{message.source}----------------\n {message.content}") # result[message.source] = [content.content for content in message.content] return result # Example usage in another function async def main_1(): # result = await main(input("Enter your instructions below: \n")) result = await main("Let the robot synthesize CsPbBr3 nanocubes at room temperature") # result = await main("查一下CsPbBr3的晶体结构") print(result) if __name__ == "__main__": asyncio.run(main_1())