mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-07-14 16:32:16 +02:00
Merge branch 'main' into feature-openai-v1
This commit is contained in:
commit
9a4f0d555c
260 changed files with 10576 additions and 3191 deletions
42
metagpt/tools/azure_tts.py
Normal file
42
metagpt/tools/azure_tts.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/6/9 22:22
|
||||
@Author : Leo Xiao
|
||||
@File : azure_tts.py
|
||||
"""
|
||||
from azure.cognitiveservices.speech import AudioConfig, SpeechConfig, SpeechSynthesizer
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
|
||||
|
||||
class AzureTTS:
|
||||
"""https://learn.microsoft.com/zh-cn/azure/cognitive-services/speech-service/language-support?tabs=tts#voice-styles-and-roles"""
|
||||
|
||||
@classmethod
|
||||
def synthesize_speech(cls, lang, voice, role, text, output_file):
|
||||
subscription_key = CONFIG.get("AZURE_TTS_SUBSCRIPTION_KEY")
|
||||
region = CONFIG.get("AZURE_TTS_REGION")
|
||||
speech_config = SpeechConfig(subscription=subscription_key, region=region)
|
||||
|
||||
speech_config.speech_synthesis_voice_name = voice
|
||||
audio_config = AudioConfig(filename=output_file)
|
||||
synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
|
||||
|
||||
# if voice=="zh-CN-YunxiNeural":
|
||||
ssml_string = f"""
|
||||
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='{lang}' xmlns:mstts='http://www.w3.org/2001/mstts'>
|
||||
<voice name='{voice}'>
|
||||
<mstts:express-as style='affectionate' role='{role}'>
|
||||
{text}
|
||||
</mstts:express-as>
|
||||
</voice>
|
||||
</speak>
|
||||
"""
|
||||
|
||||
synthesizer.speak_ssml_async(ssml_string).get()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
azure_tts = AzureTTS()
|
||||
azure_tts.synthesize_speech("zh-CN", "zh-CN-YunxiNeural", "Boy", "Hello, I am Kaka", "output.wav")
|
||||
|
|
@ -10,8 +10,9 @@ from typing import Union
|
|||
|
||||
class GPTPromptGenerator:
|
||||
"""Using LLM, given an output, request LLM to provide input (supporting instruction, chatbot, and query styles)"""
|
||||
|
||||
def __init__(self):
|
||||
self._generators = {i: getattr(self, f"gen_{i}_style") for i in ['instruction', 'chatbot', 'query']}
|
||||
self._generators = {i: getattr(self, f"gen_{i}_style") for i in ["instruction", "chatbot", "query"]}
|
||||
|
||||
def gen_instruction_style(self, example):
|
||||
"""Instruction style: Given an output, request LLM to provide input"""
|
||||
|
|
@ -35,7 +36,7 @@ Query: X
|
|||
Document: {example} What is the detailed query X?
|
||||
X:"""
|
||||
|
||||
def gen(self, example: str, style: str = 'all') -> Union[list[str], str]:
|
||||
def gen(self, example: str, style: str = "all") -> Union[list[str], str]:
|
||||
"""
|
||||
Generate one or multiple outputs using the example, allowing LLM to reply with the corresponding input
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ X:"""
|
|||
:param style: (all|instruction|chatbot|query)
|
||||
:return: Expected LLM input sample (one or multiple)
|
||||
"""
|
||||
if style != 'all':
|
||||
if style != "all":
|
||||
return self._generators[style](example)
|
||||
return [f(example) for f in self._generators.values()]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @Date : 2023/7/19 16:28
|
||||
# @Author : stellahong (stellahong@fuzhi.ai)
|
||||
# @Author : stellahong (stellahong@deepwisdom.ai)
|
||||
# @Desc :
|
||||
import asyncio
|
||||
import base64
|
||||
|
|
@ -13,11 +13,10 @@ from typing import List
|
|||
from aiohttp import ClientSession
|
||||
from PIL import Image, PngImagePlugin
|
||||
|
||||
from metagpt.config import Config
|
||||
from metagpt.const import WORKSPACE_ROOT
|
||||
from metagpt.logs import logger
|
||||
from metagpt.config import CONFIG
|
||||
|
||||
config = Config()
|
||||
# from metagpt.const import WORKSPACE_ROOT
|
||||
from metagpt.logs import logger
|
||||
|
||||
payload = {
|
||||
"prompt": "",
|
||||
|
|
@ -56,9 +55,8 @@ default_negative_prompt = "(easynegative:0.8),black, dark,Low resolution"
|
|||
class SDEngine:
|
||||
def __init__(self):
|
||||
# Initialize the SDEngine with configuration
|
||||
self.config = Config()
|
||||
self.sd_url = self.config.get("SD_URL")
|
||||
self.sd_t2i_url = f"{self.sd_url}{self.config.get('SD_T2I_API')}"
|
||||
self.sd_url = CONFIG.get("SD_URL")
|
||||
self.sd_t2i_url = f"{self.sd_url}{CONFIG.get('SD_T2I_API')}"
|
||||
# Define default payload settings for SD API
|
||||
self.payload = payload
|
||||
logger.info(self.sd_t2i_url)
|
||||
|
|
@ -81,7 +79,7 @@ class SDEngine:
|
|||
return self.payload
|
||||
|
||||
def _save(self, imgs, save_name=""):
|
||||
save_dir = WORKSPACE_ROOT / "resources" / "SD_Output"
|
||||
save_dir = CONFIG.workspace_path / "resources" / "SD_Output"
|
||||
if not os.path.exists(save_dir):
|
||||
os.makedirs(save_dir, exist_ok=True)
|
||||
batch_decode_base64_to_image(imgs, save_dir, save_name=save_name)
|
||||
|
|
@ -120,11 +118,13 @@ def decode_base64_to_image(img, save_name):
|
|||
image.save(f"{save_name}.png", pnginfo=pnginfo)
|
||||
return pnginfo, image
|
||||
|
||||
|
||||
def batch_decode_base64_to_image(imgs, save_dir="", save_name=""):
|
||||
for idx, _img in enumerate(imgs):
|
||||
save_name = join(save_dir, save_name)
|
||||
decode_base64_to_image(_img, save_name=save_name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
engine = SDEngine()
|
||||
prompt = "pixel style, game design, a game interface should be minimalistic and intuitive with the score and high score displayed at the top. The snake and its food should be easily distinguishable. The game should have a simple color scheme, with a contrasting color for the snake and its food. Complete interface boundary"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
@File : search_engine.py
|
||||
"""
|
||||
import importlib
|
||||
from typing import Callable, Coroutine, Literal, overload, Optional, Union
|
||||
from typing import Callable, Coroutine, Literal, Optional, Union, overload
|
||||
|
||||
from semantic_kernel.skill_definition import sk_function
|
||||
|
||||
|
|
@ -43,8 +43,8 @@ class SearchEngine:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
engine: Optional[SearchEngineType] = None,
|
||||
run_func: Callable[[str, int, bool], Coroutine[None, None, Union[str, list[str]]]] = None,
|
||||
engine: Optional[SearchEngineType] = None,
|
||||
run_func: Callable[[str, int, bool], Coroutine[None, None, Union[str, list[str]]]] = None,
|
||||
):
|
||||
engine = engine or CONFIG.search_engine
|
||||
if engine == SearchEngineType.SERPAPI_GOOGLE:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ from typing import List
|
|||
import meilisearch
|
||||
from meilisearch.index import Index
|
||||
|
||||
from metagpt.utils.exceptions import handle_exception
|
||||
|
||||
|
||||
class DataSource:
|
||||
def __init__(self, name: str, url: str):
|
||||
|
|
@ -29,16 +31,12 @@ class MeilisearchEngine:
|
|||
def add_documents(self, data_source: DataSource, documents: List[dict]):
|
||||
index_name = f"{data_source.name}_index"
|
||||
if index_name not in self.client.get_indexes():
|
||||
self.client.create_index(uid=index_name, options={'primaryKey': 'id'})
|
||||
self.client.create_index(uid=index_name, options={"primaryKey": "id"})
|
||||
index = self.client.get_index(index_name)
|
||||
index.add_documents(documents)
|
||||
self.set_index(index)
|
||||
|
||||
@handle_exception(exception_type=Exception, default_return=[])
|
||||
def search(self, query):
|
||||
try:
|
||||
search_results = self._index.search(query)
|
||||
return search_results['hits']
|
||||
except Exception as e:
|
||||
# Handle MeiliSearch API errors
|
||||
print(f"MeiliSearch API error: {e}")
|
||||
return []
|
||||
search_results = self._index.search(query)
|
||||
return search_results["hits"]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
@File : translator.py
|
||||
"""
|
||||
|
||||
prompt = '''
|
||||
prompt = """
|
||||
# 指令
|
||||
接下来,作为一位拥有20年翻译经验的翻译专家,当我给出英文句子或段落时,你将提供通顺且具有可读性的{LANG}翻译。注意以下要求:
|
||||
1. 确保翻译结果流畅且易于理解
|
||||
|
|
@ -17,11 +17,10 @@ prompt = '''
|
|||
{ORIGINAL}
|
||||
|
||||
# 译文
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
class Translator:
|
||||
|
||||
@classmethod
|
||||
def translate_prompt(cls, original, lang='中文'):
|
||||
return prompt.format(LANG=lang, ORIGINAL=original)
|
||||
def translate_prompt(cls, original, lang="中文"):
|
||||
return prompt.format(LANG=lang, ORIGINAL=original)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from pathlib import Path
|
|||
|
||||
from metagpt.provider.openai_api import OpenAIGPTAPI as GPTAPI
|
||||
|
||||
ICL_SAMPLE = '''Interface definition:
|
||||
ICL_SAMPLE = """Interface definition:
|
||||
```text
|
||||
Interface Name: Element Tagging
|
||||
Interface Path: /projects/{project_key}/node-tags
|
||||
|
|
@ -60,20 +60,20 @@ def test_node_tags(project_key, nodes, operations, expected_msg):
|
|||
# 3. If comments are needed, use Chinese.
|
||||
|
||||
# If you understand, please wait for me to give the interface definition and just answer "Understood" to save tokens.
|
||||
'''
|
||||
"""
|
||||
|
||||
ACT_PROMPT_PREFIX = '''Refer to the test types: such as missing request parameters, field boundary verification, incorrect field type.
|
||||
ACT_PROMPT_PREFIX = """Refer to the test types: such as missing request parameters, field boundary verification, incorrect field type.
|
||||
Please output 10 test cases within one `@pytest.mark.parametrize` scope.
|
||||
```text
|
||||
'''
|
||||
"""
|
||||
|
||||
YFT_PROMPT_PREFIX = '''Refer to the test types: such as SQL injection, cross-site scripting (XSS), unauthorized access and privilege escalation,
|
||||
YFT_PROMPT_PREFIX = """Refer to the test types: such as SQL injection, cross-site scripting (XSS), unauthorized access and privilege escalation,
|
||||
authentication and authorization, parameter verification, exception handling, file upload and download.
|
||||
Please output 10 test cases within one `@pytest.mark.parametrize` scope.
|
||||
```text
|
||||
'''
|
||||
"""
|
||||
|
||||
OCR_API_DOC = '''```text
|
||||
OCR_API_DOC = """```text
|
||||
Interface Name: OCR recognition
|
||||
Interface Path: /api/v1/contract/treaty/task/ocr
|
||||
Method: POST
|
||||
|
|
@ -96,14 +96,20 @@ code integer Yes
|
|||
message string Yes
|
||||
data object Yes
|
||||
```
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
class UTGenerator:
|
||||
"""UT Generator: Construct UT through API documentation"""
|
||||
|
||||
def __init__(self, swagger_file: str, ut_py_path: str, questions_path: str,
|
||||
chatgpt_method: str = "API", template_prefix=YFT_PROMPT_PREFIX) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
swagger_file: str,
|
||||
ut_py_path: str,
|
||||
questions_path: str,
|
||||
chatgpt_method: str = "API",
|
||||
template_prefix=YFT_PROMPT_PREFIX,
|
||||
) -> None:
|
||||
"""Initialize UT Generator
|
||||
|
||||
Args:
|
||||
|
|
@ -274,7 +280,7 @@ class UTGenerator:
|
|||
|
||||
def gpt_msgs_to_code(self, messages: list) -> str:
|
||||
"""Choose based on different calling methods"""
|
||||
result = ''
|
||||
result = ""
|
||||
if self.chatgpt_method == "API":
|
||||
result = GPTAPI().ask_code(msgs=messages)
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ def _gen_get_driver_func(browser_type, *args, executable_path=None):
|
|||
options.add_argument("--headless")
|
||||
options.add_argument("--enable-javascript")
|
||||
if browser_type == "chrome":
|
||||
options.add_argument("--disable-gpu") # This flag can help avoid renderer issue
|
||||
options.add_argument("--disable-dev-shm-usage") # Overcome limited resource problems
|
||||
options.add_argument("--no-sandbox")
|
||||
for i in args:
|
||||
options.add_argument(i)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue