mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-05-03 21:02:38 +02:00
Merge pull request #628 from iorisa/fixbug/role/assistant
fixbug: 修复通用智能体role及其相关的TalkAction和SkillAction
This commit is contained in:
commit
59586f30d6
12 changed files with 541 additions and 512 deletions
65
tests/metagpt/actions/test_skill_action.py
Normal file
65
tests/metagpt/actions/test_skill_action.py
Normal 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"])
|
||||
|
|
@ -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"])
|
||||
|
|
|
|||
100
tests/metagpt/roles/test_assistant.py
Normal file
100
tests/metagpt/roles/test_assistant.py
Normal 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"])
|
||||
Loading…
Add table
Add a link
Reference in a new issue