Duibonduil's picture
Upload 7 files
d0c79e9 verified
import logging
import uuid
from typing import Optional, AsyncGenerator
from aworld.memory.main import MemoryFactory
from examples.debate.agent.base import DebateSpeech
from examples.debate.agent.debate_agent import DebateAgent
from examples.debate.agent.moderator_agent import ModeratorAgent
from aworld.core.common import Observation
from aworld.core.memory import MemoryItem, MemoryConfig
from aworld.output import Output, WorkSpace, Artifact, ArtifactType, CodeArtifact
class DebateArena:
"""
DebateArena is platform for debate
"""
affirmative_speaker: DebateAgent
negative_speaker: DebateAgent
moderator: Optional[ModeratorAgent]
speeches: list[DebateSpeech]
display_panel: str
def __init__(self,
affirmative_speaker: DebateAgent,
negative_speaker: DebateAgent,
moderator: ModeratorAgent,
workspace: WorkSpace,
**kwargs
):
self.affirmative_speaker = affirmative_speaker
self.negative_speaker = negative_speaker
self.moderator = moderator
self.speeches = []
self.workspace = workspace
self.affirmative_speaker.set_workspace(workspace)
self.negative_speaker.set_workspace(workspace)
self.moderator.set_workspace(workspace)
self.moderator.memory = MemoryFactory.from_config(MemoryConfig(provider="inmemory", enable_summary=False))
# Event.register("topic", func= );
async def async_run(self, topic: str, rounds: int) \
-> AsyncGenerator[Output, None]:
"""
Start the debate
1. debate will start from round 1
2. each round will have two speeches, one from affirmative_speaker and one from negative_speaker
3. after all rounds finished, the debate will end
Args:
topic: str -> topic of the debate
affirmative_opinion: str -> affirmative speaker's opinion
negative_opinion: str -> negative speaker's opinion
rounds: int -> number of rounds
Returns: list[DebateSpeech]
"""
## 1. generate opinions
moderator_speech = await self.moderator_speech(topic, rounds)
if not moderator_speech:
return
yield moderator_speech
await moderator_speech.wait_until_finished()
self.store_speech(moderator_speech)
affirmative_opinion = moderator_speech.metadata["affirmative_opinion"]
negative_opinion = moderator_speech.metadata["negative_opinion"]
logging.info(f"✈️==================================== opinions =============================================")
logging.info(f"topic: {topic}")
logging.info(f"affirmative_opinion: {affirmative_opinion}")
logging.info(f"negative_opinion: {negative_opinion}")
logging.info(f"✈️==================================== start... =============================================")
## 2. Alternating speeches
for i in range(1, rounds + 1):
logging.info(
f"✈️==================================== round#{i} start =============================================")
loading_speech = DebateSpeech.from_dict({
"content": f"\n\n**round#{i} start** \n\n",
"round": i,
"type": "loading",
"stance": "stage",
"name": "stage",
"finished": True
})
yield loading_speech
loading_speech = DebateSpeech.from_dict({
"content": f"\n\n【affirmative】✅:{self.affirmative_speaker.name()}\n Searching ....\n",
"round": i,
"type": "loading",
"stance": "stage",
"name": "stage",
"finished": True
})
yield loading_speech
# affirmative_speech
speech = await self.affirmative_speech(i, topic, affirmative_opinion, negative_opinion)
yield speech
await speech.wait_until_finished()
self.store_speech(speech)
loading_speech = DebateSpeech.from_dict({
"content": f"\n\n【negative】❌:{self.negative_speaker.name()}\n Searching ....\n",
"round": i,
"type": "loading",
"stance": "stage",
"name": "stage",
"finished": True
})
yield loading_speech
# negative_speech
speech = await self.negative_speech(i, topic, negative_opinion, affirmative_opinion)
yield speech
await speech.wait_until_finished()
self.store_speech(speech)
logging.info(
f"🛬==================================== round#{i} end =============================================")
## 3. Summary speeches
moderator_speech = await self.moderator.summary_speech()
if not moderator_speech:
return
yield moderator_speech
await moderator_speech.wait_until_finished()
await self.workspace.add_artifact(
CodeArtifact.build_artifact(
artifact_type=ArtifactType.CODE,
artifact_id="result",
code_type='html',
content=moderator_speech.content,
metadata={
"topic": topic
}
)
)
logging.info(
f"🛬==================================== total is end =============================================")
async def moderator_speech(self, topic, rounds) -> DebateSpeech | None:
results = await self.moderator.async_policy(Observation(content=topic, info={"rounds": rounds}))
if not results or not results[0] or not results[0].policy_info:
return None
return results[0].policy_info
async def affirmative_speech(self, round: int, topic: str, opinion: str, oppose_opinion: str) -> DebateSpeech:
"""
affirmative_speaker will start speech
"""
affirmative_speaker = self.get_affirmative_speaker()
logging.info(affirmative_speaker.name() + ": " + "start")
speech = await affirmative_speaker.speech(topic, opinion, oppose_opinion, round, self.speeches)
logging.info(affirmative_speaker.name() + ": result: " + speech.content)
return speech
async def negative_speech(self, round: int, topic: str, opinion: str, oppose_opinion: str) -> DebateSpeech:
"""
after affirmative_speaker finished speech, negative_speaker will start speech
"""
negative_speaker = self.get_negative_speaker()
logging.info(negative_speaker.name() + ": " + "start")
speech = await negative_speaker.speech(topic, opinion, oppose_opinion, round, self.speeches)
logging.info(negative_speaker.name() + ": result: " + speech.content)
return speech
def get_affirmative_speaker(self) -> DebateAgent:
"""
return the affirmative speaker
"""
return self.affirmative_speaker
def get_negative_speaker(self) -> DebateAgent:
"""
return the negative speaker
"""
return self.negative_speaker
def store_speech(self, speech: DebateSpeech):
self.moderator.memory.add(MemoryItem.from_dict({
"content": speech.content,
"metadata": {
"round": speech.round,
"speaker": speech.name,
"type": speech.type
}
}))
self.speeches.append(speech)
def gen_closing_statement(self):
pass