diff --git a/README.md b/README.md
index 91a5483e0..c326190b0 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ # MetaGPT: The Multi-Agent Framework
-
+
@@ -162,9 +162,9 @@ ### Installation by Docker
```bash
# Step 1: Download metagpt official image and prepare config.yaml
-docker pull metagpt/metagpt:v0.3.1
+docker pull metagpt/metagpt:latest
mkdir -p /opt/metagpt/{config,workspace}
-docker run --rm metagpt/metagpt:v0.3.1 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
+docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
vim /opt/metagpt/config/key.yaml # Change the config
# Step 2: Run metagpt demo with container
@@ -172,7 +172,7 @@ # Step 2: Run metagpt demo with container
--privileged \
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
-v /opt/metagpt/workspace:/app/metagpt/workspace \
- metagpt/metagpt:v0.3.1 \
+ metagpt/metagpt:latest \
python startup.py "Write a cli snake game"
# You can also start a container and execute commands in it
@@ -180,7 +180,7 @@ # You can also start a container and execute commands in it
--privileged \
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
-v /opt/metagpt/workspace:/app/metagpt/workspace \
- metagpt/metagpt:v0.3.1
+ metagpt/metagpt:latest
docker exec -it metagpt /bin/bash
$ python startup.py "Write a cli snake game"
diff --git a/docs/README_CN.md b/docs/README_CN.md
index 1372bf9f4..7a27a0e59 100644
--- a/docs/README_CN.md
+++ b/docs/README_CN.md
@@ -15,7 +15,7 @@ # MetaGPT: 多智能体框架
-
+
@@ -87,9 +87,9 @@ ### Docker安装
```bash
# 步骤1: 下载metagpt官方镜像并准备好config.yaml
-docker pull metagpt/metagpt:v0.3
+docker pull metagpt/metagpt:latest
mkdir -p /opt/metagpt/{config,workspace}
-docker run --rm metagpt/metagpt:v0.3 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/config.yaml
+docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/config.yaml
vim /opt/metagpt/config/config.yaml # 修改config
# 步骤2: 使用容器运行metagpt演示
@@ -97,7 +97,7 @@ # 步骤2: 使用容器运行metagpt演示
--privileged \
-v /opt/metagpt/config:/app/metagpt/config \
-v /opt/metagpt/workspace:/app/metagpt/workspace \
- metagpt/metagpt:v0.3 \
+ metagpt/metagpt:latest \
python startup.py "Write a cli snake game"
# 您也可以启动一个容器并在其中执行命令
@@ -105,7 +105,7 @@ # 您也可以启动一个容器并在其中执行命令
--privileged \
-v /opt/metagpt/config:/app/metagpt/config \
-v /opt/metagpt/workspace:/app/metagpt/workspace \
- metagpt/metagpt:v0.3
+ metagpt/metagpt:latest
docker exec -it metagpt /bin/bash
$ python startup.py "Write a cli snake game"
@@ -123,7 +123,7 @@ ### 自己构建镜像
```bash
# 您也可以自己构建metagpt镜像
git clone https://github.com/geekan/MetaGPT.git
-cd MetaGPT && docker build -t metagpt:v0.3 .
+cd MetaGPT && docker build -t metagpt:custom .
```
## 配置
diff --git a/docs/README_JA.md b/docs/README_JA.md
index 8d6c2fe84..eab69d912 100644
--- a/docs/README_JA.md
+++ b/docs/README_JA.md
@@ -15,7 +15,7 @@ # MetaGPT: マルチエージェントフレームワーク
-
+
@@ -92,9 +92,9 @@ ### Docker によるインストール ```bash # ステップ 1: metagpt 公式イメージをダウンロードし、config.yaml を準備する -docker pull metagpt/metagpt:v0.3.1 +docker pull metagpt/metagpt:latest mkdir -p /opt/metagpt/{config,workspace} -docker run --rm metagpt/metagpt:v0.3.1 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml +docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml vim /opt/metagpt/config/key.yaml # 設定を変更する # ステップ 2: コンテナで metagpt デモを実行する @@ -102,7 +102,7 @@ # ステップ 2: コンテナで metagpt デモを実行する --privileged \ -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ - metagpt/metagpt:v0.3.1 \ + metagpt/metagpt:latest \ python startup.py "Write a cli snake game" # コンテナを起動し、その中でコマンドを実行することもできます @@ -110,7 +110,7 @@ # コンテナを起動し、その中でコマンドを実行することもで --privileged \ -v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \ -v /opt/metagpt/workspace:/app/metagpt/workspace \ - metagpt/metagpt:v0.3.1 + metagpt/metagpt:latest docker exec -it metagpt /bin/bash $ python startup.py "Write a cli snake game" diff --git a/metagpt/actions/design_api.py b/metagpt/actions/design_api.py index f19fcbeaa..75df8b909 100644 --- a/metagpt/actions/design_api.py +++ b/metagpt/actions/design_api.py @@ -207,5 +207,11 @@ class WriteDesign(Action): prompt = prompt_template.format(context=context, format_example=format_example) # system_design = await self._aask(prompt) system_design = await self._aask_v1(prompt, "system_design", OUTPUT_MAPPING, format=format) + # fix Python package name, we can't system_design.instruct_content.python_package_name = "xxx" since "Python package name" contain space, have to use setattr + setattr( + system_design.instruct_content, + "Python package name", + system_design.instruct_content.dict()["Python package name"].strip().strip("'").strip('"'), + ) await self._save(context, system_design) return system_design diff --git a/metagpt/tools/moderation.py b/metagpt/tools/moderation.py new file mode 100644 index 000000000..c56a6afc4 --- /dev/null +++ b/metagpt/tools/moderation.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/9/26 14:27 +@Author : zhanglei +@File : moderation.py +""" +from typing import Union + +from metagpt.llm import LLM + + +class Moderation: + def __init__(self): + self.llm = LLM() + + def moderation(self, content: Union[str, list[str]]): + resp = [] + if content: + moderation_results = self.llm.moderation(content=content) + results = moderation_results.results + for item in results: + resp.append(item.flagged) + + return resp + + async def amoderation(self, content: Union[str, list[str]]): + resp = [] + if content: + moderation_results = await self.llm.amoderation(content=content) + results = moderation_results.results + for item in results: + resp.append(item.flagged) + + return resp + + +if __name__ == "__main__": + moderation = Moderation() + print(moderation.moderation(content=["I will kill you", "The weather is really nice today", "I want to hit you"])) diff --git a/metagpt/utils/common.py b/metagpt/utils/common.py index aef5546fa..f09666beb 100644 --- a/metagpt/utils/common.py +++ b/metagpt/utils/common.py @@ -180,7 +180,7 @@ class OutputParser: if start_index != -1 and end_index != -1: # Extract the structure part - structure_text = text[start_index:end_index + 1] + structure_text = text[start_index : end_index + 1] try: # Attempt to convert the text to a Python data type using ast.literal_eval @@ -238,7 +238,7 @@ class CodeParser: logger.error(f"{pattern} not match following text:") logger.error(text) # raise Exception - return "" + return text # just assume original text is code return code @classmethod diff --git a/metagpt/utils/serialize.py b/metagpt/utils/serialize.py index ffafca8cd..124176fcb 100644 --- a/metagpt/utils/serialize.py +++ b/metagpt/utils/serialize.py @@ -4,7 +4,7 @@ import copy import pickle -from typing import Dict, List, Tuple +from typing import Dict, List from metagpt.actions.action_output import ActionOutput from metagpt.schema import Message @@ -37,8 +37,8 @@ def actionoutout_schema_to_mapping(schema: Dict) -> Dict: elif property["type"] == "array" and property["items"]["type"] == "string": mapping[field] = (List[str], ...) elif property["type"] == "array" and property["items"]["type"] == "array": - # here only consider the `Tuple[str, str]` situation - mapping[field] = (List[Tuple[str, str]], ...) + # here only consider the `List[List[str]]` situation + mapping[field] = (List[List[str]], ...) return mapping diff --git a/tests/metagpt/tools/test_moderation.py b/tests/metagpt/tools/test_moderation.py new file mode 100644 index 000000000..225acff75 --- /dev/null +++ b/tests/metagpt/tools/test_moderation.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@Time : 2023/9/26 14:46 +@Author : zhanglei +@File : test_translate.py +""" + +import pytest + +from metagpt.tools.moderation import Moderation + + +@pytest.mark.parametrize( + ("content",), + [ + [ + ["I will kill you", "The weather is really nice today", "I want to hit you"], + ] + ], +) +def test_moderation(content): + moderation = Moderation() + results = moderation.moderation(content=content) + assert isinstance(results, list) + assert len(results) == len(content) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + ("content",), + [ + [ + ["I will kill you", "The weather is really nice today", "I want to hit you"], + ] + ], +) +async def test_amoderation(content): + moderation = Moderation() + results = await moderation.amoderation(content=content) + assert isinstance(results, list) + assert len(results) == len(content)