Spaces:
Sleeping
Sleeping
import os | |
from http import HTTPStatus | |
import json | |
import requests | |
from config_utils import DEFAULT_BUILDER_CONFIG_DIR, get_user_cfg_file | |
from dashscope import ImageSynthesis | |
from modelscope_agent.tools import Tool | |
from modelscope_agent.utils.logger import agent_logger as logger | |
from modelscope.utils.config import Config | |
LOGO_NAME = 'custom_bot_avatar.png' | |
LOGO_PATH = os.path.join(DEFAULT_BUILDER_CONFIG_DIR, LOGO_NAME) | |
CONFIG_FORMAT = """ | |
{ | |
"name": ... # CustomGPT的名字。 | |
"description": ... # CustomGPT 的简介。 | |
"instructions": ... # CustomGPT 的功能要求,类型是string。 | |
"prompt_recommend": ... # CustomGPT 的起始交互语句,类型是一个字符串数组,起始为[]。 | |
} | |
""" | |
CONF_GENERATOR_INST = """你现在要扮演一个 CustomGPT 的配置生成器 | |
在接下来的对话中,每次均生成如下格式的内容: | |
{config_format} | |
现在,已知原始配置为{old_config},用户在原始配置上有一些建议修改项,包括: | |
1. 用户建议的 CustomGPT 的名称为{app_name} | |
2. CustomGPT 的描述为{app_description} | |
3. CustomGPT 的启动器为{app_conversation_starter} | |
请你参考原始配置生成新的修改后的配置,请注意: | |
1. 如果用户对原本的简介、功能要求、交互语句不满意,则直接换掉原本的简介、功能要求、交互语句。 | |
2. 如果用户对原本的简介、功能要求、交互语句比较满意,参考用户的起始交互语句和原配置中的起始交互语句,生成新的简介、功能要求、交互语句。 | |
3. 如果原始配置没有实际内容,请你根据你的知识帮助用户生成第一个版本的配置,简介在100字左右,功能要求在150字左右,起始交互语句在4条左右。 | |
请你生成新的配置文件,严格遵循给定格式,请不要创造其它字段,仅输出要求的json格式,请勿输出其它内容。 | |
""" | |
LOGO_INST = """定制化软件 CustomGPT 的作用是{description},{user_requirement}请你为它生成一个专业的logo""" | |
def get_logo_path(uuid_str=''): | |
logo_path = os.getenv('LOGO_PATH', LOGO_PATH) | |
# convert from ./config/builder_config.json to ./config/user/builder_config.json | |
logo_path = logo_path.replace('config/', 'config/user/') | |
# convert from ./config/user to ./config/uuid | |
if uuid_str != '': | |
logo_path = logo_path.replace('user', uuid_str) | |
if not os.path.exists(logo_path): | |
os.makedirs(os.path.dirname(logo_path), exist_ok=True) | |
return logo_path | |
def call_wanx(prompt, save_path, uuid_str): | |
rsp = ImageSynthesis.call( | |
model='wanx-lite', prompt=prompt, n=1, size='768*768') | |
if rsp.status_code == HTTPStatus.OK: | |
if os.path.exists(save_path): | |
os.remove(save_path) | |
# save file to current directory | |
for result in rsp.output.results: | |
with open(save_path, 'wb+') as f: | |
f.write(requests.get(result.url).content) | |
else: | |
logger.error( | |
uuid=uuid_str, | |
error='wanx error', | |
content={ | |
'wanx_status_code': rsp.status_code, | |
'wanx_code': rsp.code, | |
'wanx_message': rsp.message | |
}) | |
class LogoGeneratorTool(Tool): | |
description = 'logo_designer是一个AI绘制logo的服务,输入用户对 CustomGPT 的要求,会生成 CustomGPT 的logo。' | |
name = 'logo_designer' | |
parameters: list = [{ | |
'name': 'user_requirement', | |
'description': '用户对 CustomGPT logo的要求和建议', | |
'required': True, | |
'schema': { | |
'type': 'string' | |
}, | |
}] | |
def _remote_call(self, *args, **kwargs): | |
user_requirement = kwargs['user_requirement'] | |
uuid_str = kwargs.get('uuid_str', '') | |
builder_cfg_file = get_user_cfg_file(uuid_str) | |
builder_cfg = Config.from_file(builder_cfg_file) | |
avatar_prompt = LOGO_INST.format( | |
description=builder_cfg.description, | |
user_requirement=user_requirement) | |
call_wanx( | |
prompt=avatar_prompt, | |
save_path=get_logo_path(uuid_str=uuid_str), | |
uuid_str=uuid_str) | |
builder_cfg.avatar = LOGO_NAME | |
return {'result': builder_cfg} | |
def config_conversion(generated_config: dict, save=False, uuid_str=''): | |
""" | |
convert | |
{ | |
name: "铁人", | |
description: "我希望我的AI-Agent是一个专业的健身教练,专注于力量训练方面,可以提供相关的建议和指南。 | |
它还可以帮我跟踪和记录每次的力量训练数据,以及提供相应的反馈和建议,帮助我不断改进和优化我的训练计划。 | |
此外,我希望它可以拥有一些特殊技能和功能,让它更加实用和有趣。例如,它可以帮助我预测未来的身体状况、分析我的营养摄入情况、 | |
提供心理支持等等。我相信,在它的帮助下,我可以更快地达到自己的目标,变得更加强壮和健康。", | |
instructions: [ | |
"提供力量训练相关的建议和指南", | |
"跟踪和记录每次的力量训练数据", | |
"提供反馈和建议,帮助改进和优化训练计划", | |
"预测未来的身体状况", | |
"分析营养摄入情况", | |
"提供心理支持", | |
], | |
prompt_recommend: [ | |
"你好,今天的锻炼计划是什么呢?", | |
"你觉得哪种器械最适合练背部肌肉呢?", | |
"你觉得我现在的训练强度合适吗?", | |
"你觉得哪种食物最适合增肌呢?", | |
], | |
logo_prompt: "设计一个肌肉男形象的Logo", | |
} | |
to | |
{ | |
name: "铁人", | |
description: "我希望我的AI-Agent是一个专业的健身教练,专注于力量训练方面,可以提供相关的建议和指南。 | |
它还可以帮我跟踪和记录每次的力量训练数据,以及提供相应的反馈和建议,帮助我不断改进和优化我的训练计划。 | |
此外,我希望它可以拥有一些特殊技能和功能,让它更加实用和有趣。例如,它可以帮助我预测未来的身体状况、 | |
分析我的营养摄入情况、提供心理支持等等。我相信,在它的帮助下,我可以更快地达到自己的目标,变得更加强壮和健康。", | |
instructions: "提供力量训练相关的建议和指南;跟踪和记录每次的力量训练数据;提供反馈和建议,帮助改进和优化训练计划; | |
预测未来的身体状况;分析营养摄入情况;提供心理支持", | |
prompt_recommend: [ | |
"你好,今天的锻炼计划是什么呢?", | |
"你觉得哪种器械最适合练背部肌肉呢?", | |
"你觉得我现在的训练强度合适吗?", | |
"你觉得哪种食物最适合增肌呢?", | |
], | |
tools: xxx | |
model: yyy | |
} | |
:param generated_config: | |
:return: | |
""" | |
builder_cfg_file = get_user_cfg_file(uuid_str) | |
builder_cfg = Config.from_file(builder_cfg_file) | |
try: | |
builder_cfg.name = generated_config['name'] | |
builder_cfg.description = generated_config['description'] | |
builder_cfg.prompt_recommend = generated_config['prompt_recommend'] | |
if isinstance(generated_config['instructions'], list): | |
builder_cfg.instruction = ';'.join( | |
generated_config['instructions']) | |
else: | |
builder_cfg.instruction = generated_config['instructions'] | |
if save: | |
json.dump( | |
builder_cfg.to_dict(), | |
open(builder_cfg_file, 'w'), | |
indent=2, | |
ensure_ascii=False) | |
return builder_cfg | |
except ValueError as e: | |
raise ValueError(f'failed to save the configuration with info: {e}') | |