Merge pull request #628 from iorisa/fixbug/role/assistant

fixbug: 修复通用智能体role及其相关的TalkAction和SkillAction
This commit is contained in:
geekan 2023-12-25 23:14:21 +08:00 committed by GitHub
commit 59586f30d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 541 additions and 512 deletions

View file

@ -0,0 +1,65 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2023/9/19
@Author : mashenquan
@File : test_skill_action.py
@Desc : Unit tests.
"""
import pytest
from metagpt.actions.skill_action import ArgumentsParingAction, SkillAction
from metagpt.learn.skill_loader import Example, Parameter, Returns, Skill
class TestSkillAction:
skill = Skill(
name="text_to_image",
description="Create a drawing based on the text.",
id="text_to_image.text_to_image",
x_prerequisite={
"configurations": {
"OPENAI_API_KEY": {
"type": "string",
"description": "OpenAI API key, For more details, checkout: `https://platform.openai.com/account/api-keys`",
},
"METAGPT_TEXT_TO_IMAGE_MODEL_URL": {"type": "string", "description": "Model url."},
},
"required": {"oneOf": ["OPENAI_API_KEY", "METAGPT_TEXT_TO_IMAGE_MODEL_URL"]},
},
parameters={
"text": Parameter(type="string", description="The text used for image conversion."),
"size_type": Parameter(type="string", description="size type"),
},
examples=[
Example(ask="Draw a girl", answer='text_to_image(text="Draw a girl", size_type="512x512")'),
Example(ask="Draw an apple", answer='text_to_image(text="Draw an apple", size_type="512x512")'),
],
returns=Returns(type="string", format="base64"),
)
@pytest.mark.asyncio
async def test_parser(self):
args = ArgumentsParingAction.parse_arguments(
skill_name="text_to_image", txt='`text_to_image(text="Draw an apple", size_type="512x512")`'
)
assert args.get("text") == "Draw an apple"
assert args.get("size_type") == "512x512"
@pytest.mark.asyncio
async def test_parser_action(self):
parser_action = ArgumentsParingAction(skill=self.skill, ask="Draw an apple")
rsp = await parser_action.run()
assert rsp
assert parser_action.args
assert parser_action.args.get("text") == "Draw an apple"
assert parser_action.args.get("size_type") == "512x512"
action = SkillAction(skill=self.skill, args=parser_action.args)
rsp = await action.run()
assert rsp
assert "image/png;base64," in rsp.content
if __name__ == "__main__":
pytest.main([__file__, "-s"])

View file

@ -6,12 +6,14 @@
@File : test_skill_loader.py
@Desc : Unit tests.
"""
import pytest
from metagpt.config import CONFIG
from metagpt.learn.skill_loader import SkillLoader
from metagpt.learn.skill_loader import SkillsDeclaration
def test_suite():
@pytest.mark.asyncio
async def test_suite():
CONFIG.agent_skills = [
{"id": 1, "name": "text_to_speech", "type": "builtin", "config": {}, "enabled": True},
{"id": 2, "name": "text_to_image", "type": "builtin", "config": {}, "enabled": True},
@ -21,7 +23,7 @@ def test_suite():
{"id": 6, "name": "knowledge", "type": "builtin", "config": {}, "enabled": True},
{"id": 6, "name": "web_search", "type": "builtin", "config": {}, "enabled": True},
]
loader = SkillLoader()
loader = await SkillsDeclaration.load()
skills = loader.get_skill_list()
assert skills
assert len(skills) >= 3
@ -29,7 +31,7 @@ def test_suite():
assert desc
assert name
entity = loader.get_entity("Assistant")
entity = loader.entities.get("Assistant")
assert entity
assert entity.skills
for sk in entity.skills:
@ -38,4 +40,4 @@ def test_suite():
if __name__ == "__main__":
test_suite()
pytest.main([__file__, "-s"])

View file

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2023/12/25
@Author : mashenquan
@File : test_asssistant.py
@Desc : Used by AgentStore.
"""
import pytest
from pydantic import BaseModel
from metagpt.actions.skill_action import SkillAction
from metagpt.actions.talk_action import TalkAction
from metagpt.config import CONFIG
from metagpt.logs import logger
from metagpt.memory.brain_memory import BrainMemory
from metagpt.roles.assistant import Assistant
from metagpt.schema import Message
from metagpt.utils.common import any_to_str
@pytest.mark.asyncio
async def test_run():
CONFIG.language = "Chinese"
class Input(BaseModel):
memory: BrainMemory
language: str
agent_description: str
cause_by: str
inputs = [
{
"memory": {
"history": [
{
"content": "who is tulin",
"role": "user",
"id": 1,
},
{"content": "The one who eaten a poison apple.", "role": "assistant"},
],
"knowledge": [{"content": "tulin is a scientist."}],
"last_talk": "what's apple?",
},
"language": "English",
"agent_description": "chatterbox",
"cause_by": any_to_str(TalkAction),
},
{
"memory": {
"history": [
{
"content": "can you draw me an picture?",
"role": "user",
"id": 1,
},
{"content": "Yes, of course. What do you want me to draw", "role": "assistant"},
],
"knowledge": [{"content": "tulin is a scientist."}],
"last_talk": "Draw me an apple.",
},
"language": "English",
"agent_description": "painter",
"cause_by": any_to_str(SkillAction),
},
]
CONFIG.agent_skills = [
{"id": 1, "name": "text_to_speech", "type": "builtin", "config": {}, "enabled": True},
{"id": 2, "name": "text_to_image", "type": "builtin", "config": {}, "enabled": True},
{"id": 3, "name": "ai_call", "type": "builtin", "config": {}, "enabled": True},
{"id": 3, "name": "data_analysis", "type": "builtin", "config": {}, "enabled": True},
{"id": 5, "name": "crawler", "type": "builtin", "config": {"engine": "ddg"}, "enabled": True},
{"id": 6, "name": "knowledge", "type": "builtin", "config": {}, "enabled": True},
{"id": 6, "name": "web_search", "type": "builtin", "config": {}, "enabled": True},
]
for i in inputs:
seed = Input(**i)
CONFIG.language = seed.language
CONFIG.agent_description = seed.agent_description
role = Assistant(language="Chinese")
role.memory = seed.memory # Restore historical conversation content.
while True:
has_action = await role.think()
if not has_action:
break
msg: Message = await role.act()
logger.info(msg)
assert msg
assert msg.cause_by == seed.cause_by
assert msg.content
# # Retrieve user terminal input.
# logger.info("Enter prompt")
# talk = input("You: ")
# await role.talk(talk)
if __name__ == "__main__":
pytest.main([__file__, "-s"])