Merge branch 'dev' of https://github.com/geekan/MetaGPT into geekan/dev

This commit is contained in:
莘权 马 2024-01-11 23:16:39 +08:00
commit 2ed7c50822
26 changed files with 282 additions and 117 deletions

View file

@ -23,14 +23,12 @@ from metagpt.team import Team
async def test_debate_two_roles():
action1 = Action(name="AlexSay", instruction="Express your opinion with emotion and don't repeat it")
action2 = Action(name="BobSay", instruction="Express your opinion with emotion and don't repeat it")
biden = Role(
alex = Role(
name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action1], watch=[action2]
)
trump = Role(
name="Bob", profile="Republican candidate", goal="Win the election", actions=[action2], watch=[action1]
)
bob = Role(name="Bob", profile="Republican candidate", goal="Win the election", actions=[action2], watch=[action1])
env = Environment(desc="US election live broadcast")
team = Team(investment=10.0, env=env, roles=[biden, trump])
team = Team(investment=10.0, env=env, roles=[alex, bob])
history = await team.run(idea="Topic: climate change. Under 80 words per message.", send_to="Alex", n_round=3)
assert "Alex" in history
@ -39,9 +37,9 @@ async def test_debate_two_roles():
@pytest.mark.asyncio
async def test_debate_one_role_in_env():
action = Action(name="Debate", instruction="Express your opinion with emotion and don't repeat it")
biden = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
alex = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
env = Environment(desc="US election live broadcast")
team = Team(investment=10.0, env=env, roles=[biden])
team = Team(investment=10.0, env=env, roles=[alex])
history = await team.run(idea="Topic: climate change. Under 80 words per message.", send_to="Alex", n_round=3)
assert "Alex" in history
@ -49,8 +47,8 @@ async def test_debate_one_role_in_env():
@pytest.mark.asyncio
async def test_debate_one_role():
action = Action(name="Debate", instruction="Express your opinion with emotion and don't repeat it")
biden = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
msg: Message = await biden.run("Topic: climate change. Under 80 words per message.")
alex = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
msg: Message = await alex.run("Topic: climate change. Under 80 words per message.")
assert len(msg.content) > 10
assert msg.sent_from == "metagpt.roles.role.Role"

View file

@ -39,5 +39,6 @@ mock_llm_config_zhipu = LLMConfig(
llm_type="zhipu",
api_key="mock_api_key.zhipu",
base_url="mock_base_url",
model="mock_zhipu_model",
proxy="http://localhost:8080",
)

View file

@ -4,6 +4,7 @@
import pytest
from metagpt.config2 import Config
from metagpt.provider.spark_api import GetMessageFromWeb, SparkLLM
from tests.metagpt.provider.mock_llm_config import mock_llm_config
@ -33,6 +34,14 @@ def mock_spark_get_msg_from_web_run(self) -> str:
return resp_content
@pytest.mark.asyncio
async def test_spark_aask():
llm = SparkLLM(Config.from_home("spark.yaml").llm)
resp = await llm.aask("Hello!")
print(resp)
@pytest.mark.asyncio
async def test_spark_acompletion(mocker):
mocker.patch("metagpt.provider.spark_api.GetMessageFromWeb.run", mock_spark_get_msg_from_web_run)

View file

@ -3,6 +3,7 @@
# @Desc : unittest of Role
import pytest
from metagpt.llm import HumanProvider
from metagpt.roles.role import Role
@ -12,5 +13,10 @@ def test_role_desc():
assert role.desc == "Best Seller"
def test_role_human():
role = Role(is_human=True)
assert isinstance(role.llm, HumanProvider)
if __name__ == "__main__":
pytest.main([__file__, "-s"])

View file

@ -5,15 +5,10 @@
@Author : alexanderwu
@File : test_config.py
"""
from pydantic import BaseModel
from metagpt.config2 import Config
from metagpt.configs.llm_config import LLMType
from metagpt.context_mixin import ContextMixin
from tests.metagpt.provider.mock_llm_config import (
mock_llm_config,
mock_llm_config_proxy,
)
from tests.metagpt.provider.mock_llm_config import mock_llm_config
def test_config_1():
@ -27,57 +22,3 @@ def test_config_from_dict():
cfg = Config(llm=mock_llm_config)
assert cfg
assert cfg.llm.api_key == "mock_api_key"
class ModelX(ContextMixin, BaseModel):
a: str = "a"
b: str = "b"
class WTFMixin(BaseModel):
c: str = "c"
d: str = "d"
class ModelY(WTFMixin, ModelX):
pass
def test_config_mixin_1():
new_model = ModelX()
assert new_model.a == "a"
assert new_model.b == "b"
def test_config_mixin_2():
i = Config(llm=mock_llm_config)
j = Config(llm=mock_llm_config_proxy)
obj = ModelX(config=i)
assert obj.config == i
assert obj.config.llm == mock_llm_config
obj.set_config(j)
# obj already has a config, so it will not be set
assert obj.config == i
def test_config_mixin_3():
"""Test config mixin with multiple inheritance"""
i = Config(llm=mock_llm_config)
j = Config(llm=mock_llm_config_proxy)
obj = ModelY(config=i)
assert obj.private_config == i
assert obj.private_config.llm == mock_llm_config
obj.set_config(j)
# obj already has a config, so it will not be set
assert obj.private_config == i
assert obj.private_config.llm == mock_llm_config
assert obj.a == "a"
assert obj.b == "b"
assert obj.c == "c"
assert obj.d == "d"
print(obj.__dict__.keys())
assert "_config" in obj.__dict__.keys()

View file

@ -0,0 +1,128 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2024/1/11 19:24
@Author : alexanderwu
@File : test_context_mixin.py
"""
import pytest
from pydantic import BaseModel
from metagpt.actions import Action
from metagpt.config2 import Config
from metagpt.context_mixin import ContextMixin
from metagpt.environment import Environment
from metagpt.roles import Role
from metagpt.team import Team
from tests.metagpt.provider.mock_llm_config import (
mock_llm_config,
mock_llm_config_proxy,
mock_llm_config_zhipu,
)
class ModelX(ContextMixin, BaseModel):
a: str = "a"
b: str = "b"
class WTFMixin(BaseModel):
c: str = "c"
d: str = "d"
class ModelY(WTFMixin, ModelX):
pass
def test_config_mixin_1():
new_model = ModelX()
assert new_model.a == "a"
assert new_model.b == "b"
def test_config_mixin_2():
i = Config(llm=mock_llm_config)
j = Config(llm=mock_llm_config_proxy)
obj = ModelX(config=i)
assert obj.config == i
assert obj.config.llm == mock_llm_config
obj.set_config(j)
# obj already has a config, so it will not be set
assert obj.config == i
def test_config_mixin_3_multi_inheritance_not_override_config():
"""Test config mixin with multiple inheritance"""
i = Config(llm=mock_llm_config)
j = Config(llm=mock_llm_config_proxy)
obj = ModelY(config=i)
assert obj.config == i
assert obj.config.llm == mock_llm_config
obj.set_config(j)
# obj already has a config, so it will not be set
assert obj.config == i
assert obj.config.llm == mock_llm_config
assert obj.a == "a"
assert obj.b == "b"
assert obj.c == "c"
assert obj.d == "d"
print(obj.__dict__.keys())
assert "private_config" in obj.__dict__.keys()
def test_config_mixin_4_multi_inheritance_override_config():
"""Test config mixin with multiple inheritance"""
i = Config(llm=mock_llm_config)
j = Config(llm=mock_llm_config_zhipu)
obj = ModelY(config=i)
assert obj.config == i
assert obj.config.llm == mock_llm_config
obj.set_config(j, override=True)
# override obj.config
assert obj.config == j
assert obj.config.llm == mock_llm_config_zhipu
assert obj.a == "a"
assert obj.b == "b"
assert obj.c == "c"
assert obj.d == "d"
print(obj.__dict__.keys())
assert "private_config" in obj.__dict__.keys()
assert obj.llm.model == "mock_zhipu_model"
@pytest.mark.asyncio
async def test_config_priority():
"""If action's config is set, then its llm will be set, otherwise, it will use the role's llm"""
gpt4t = Config.from_home("gpt-4-1106-preview.yaml")
gpt35 = Config.default()
gpt4 = Config.default()
gpt4.llm.model = "gpt-4-0613"
a1 = Action(config=gpt4t, name="Say", instruction="Say your opinion with emotion and don't repeat it")
a2 = Action(name="Say", instruction="Say your opinion with emotion and don't repeat it")
a3 = Action(name="Vote", instruction="Vote for the candidate, and say why you vote for him/her")
# it will not work for a1 because the config is already set
A = Role(name="A", profile="Democratic candidate", goal="Win the election", actions=[a1], watch=[a2], config=gpt4)
# it will work for a2 because the config is not set
B = Role(name="B", profile="Republican candidate", goal="Win the election", actions=[a2], watch=[a1], config=gpt4)
# ditto
C = Role(name="C", profile="Voter", goal="Vote for the candidate", actions=[a3], watch=[a1, a2], config=gpt35)
env = Environment(desc="US election live broadcast")
Team(investment=10.0, env=env, roles=[A, B, C])
assert a1.llm.model == "gpt-4-1106-preview"
assert a2.llm.model == "gpt-4-0613"
assert a3.llm.model == "gpt-3.5-turbo-1106"
# history = await team.run(idea="Topic: climate change. Under 80 words per message.", send_to="a1", n_round=3)
# assert "Alex" in history

View file

@ -5,25 +5,26 @@
@Author : mashenquan
@File : test_redis.py
"""
from unittest.mock import AsyncMock
import mock
import pytest
from pytest_mock import mocker
from metagpt.config2 import Config
from metagpt.utils.redis import Redis
async def async_mock_from_url(*args, **kwargs):
mock_client = mock.AsyncMock()
mock_client = AsyncMock()
mock_client.set.return_value = None
mock_client.get.side_effect = [b"test", b""]
return mock_client
@pytest.mark.asyncio
@mock.patch("aioredis.from_url", return_value=async_mock_from_url())
async def test_redis(i):
redis = Config.default().redis
mocker.patch("aioredis.from_url", return_value=async_mock_from_url())
conn = Redis(redis)
await conn.set("test", "test", timeout_sec=0)