导入 DSL 创建助手源码解析
YMl 文件解析
# 基本信息
app:
description: "测试助手0827" # 应用描述
icon: "🤖" # 应用图标
icon_background: "#FFEAD5" # 图标背景颜色
mode: "chat" # 应用模式(例如:chat、workflow 等)
name: "测试助手0827" # 应用名称
kind: "app" # 定义的类型,这里为应用
# 配置信息
model_config:
agent_mode:
enabled: false # 是否启用代理模式
max_iteration: 5 # 最大迭代次数
strategy: "function_call" # 调用策略
tools: [] # 工具列表
annotation_reply:
enabled: false # 是否启用注释回复
chat_prompt_config: {} # 聊天提示配置
completion_prompt_config: {} # 补全提示配置
dataset_configs:
datasets:
datasets: [] # 数据集列表
retrieval_model: "multiple" # 检索模型类型
dataset_query_variable: "" # 数据集查询变量
external_data_tools: [] # 外部数据工具列表
file_upload:
image:
detail: "high" # 图像细节级别
enabled: false # 是否启用图像上传
number_limits: 3 # 图像数量限制
transfer_methods: # 传输方法列表
- "remote_url"
- "local_file"
# 模型信息
model:
completion_params:
stop: [] # 补全参数停止条件
mode: "chat" # 模型模式
name: "glm-4" # 模型名称
provider: "zhipuai" # 提供商名称
more_like_this:
enabled: false # 是否启用类似功能
opening_statement: "" # 开场白
pre_prompt: "测试你好" # 预设提示
prompt_type: "simple" # 提示类型
retriever_resource:
enabled: true # 是否启用检索资源
sensitive_word_avoidance:
configs: [] # 敏感词避免配置
enabled: false # 是否启用敏感词避免
type: "" # 敏感词类型
speech_to_text:
enabled: false # 是否启用语音转文本
suggested_questions: [] # 建议问题列表
suggested_questions_after_answer:
enabled: false # 回答后是否启用建议问题
text_to_speech:
enabled: false # 是否启用文本转语音
language: "" # 语言设置
voice: "" # 语音设置
user_input_form: [] # 用户输入表单
version: "0.1.1" # 版本号
导入 DSL 创建助手
######### AppImportApi.post
校验参数,将参数传递给 AppDslService.import_and_create_new_app 创建助手
源码地址:api/controllers/console/app/app.py
class AppImportApi(Resource):
@setup_required
@login_required
@account_initialization_required
@marshal_with(app_detail_fields_with_site)
@cloud_edition_billing_resource_check("apps")
def post(self):
_"""Import app"""_
_ _# 确认角色是否有权限
if not current_user.is_editor:
raise Forbidden()
#校验参数
parser = reqparse.RequestParser()
parser.add_argument("data", type=str, required=True, nullable=False, location="json")
parser.add_argument("name", type=str, location="json")
parser.add_argument("description", type=str, location="json")
parser.add_argument("icon_type", type=str, location="json")
parser.add_argument("icon", type=str, location="json")
parser.add_argument("icon_background", type=str, location="json")
args = parser.parse_args()
app = AppDslService.import_and_create_new_app(
tenant_id=current_user.current_tenant_id, data=args["data"], args=args, account=current_user
)
return app, 201
######### AppDslService.import_and_create_new_app
解析 yaml 格式文件获取所需数据根据数据类型去调用对应的存储函数(如本次选择是助手的 DSL)
源码地址:api/services/app_dsl_service.py
@classmethod
def import_and_create_new_app(cls, tenant_id: str, data: str, args: dict, account: Account) -> App:
_"""_
_ 导入应用 DSL 并创建新的应用实例_
_ :param tenant_id: tenant id_
_ :param data: 应用描述语言数据 (YAML 格式)_
_ :param args: request args_
_ :param account: Account instance_
_ """_
_ _# 尝试将data字符串解析成Python字典结构
try:
import_data = yaml.safe_load(data)
except yaml.YAMLError:
# 如果解析失败,则抛出错误提示YAML格式不正确
raise ValueError("Invalid YAML format in data argument.")
# 检查或修正DSL版本,确保其符合当前系统要求
import_data = cls._check_or_fix_dsl(import_data)
# 获取应用的基本信息部分
app_data = import_data.get("app")
if not app_data:
# 如果没有找到应用信息,则抛出错误
raise ValueError("Missing app in data argument")
# 从请求参数或导入的数据中获取应用名称,优先使用请求参数中的值
name = args.get("name") if args.get("name") else app_data.get("name")
description = args.get("description") if args.get("description") else app_data.get("description", "")
icon_type = args.get("icon_type") if args.get("icon_type") else app_data.get("icon_type")
icon = args.get("icon") if args.get("icon") else app_data.get("icon")
icon_background = (
args.get("icon_background") if args.get("icon_background") else app_data.get("icon_background")
)
# 根据应用模式创建不同类型的应用
app_mode = AppMode.value_of(app_data.get("mode"))
if app_mode in [AppMode.ADVANCED_CHAT, AppMode.WORKFLOW]:
app = cls._import_and_create_new_workflow_based_app(
tenant_id=tenant_id,
app_mode=app_mode,
workflow_data=import_data.get("workflow"),
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background,
)
#如果是助手
elif app_mode in [AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.COMPLETION]:
app = cls._import_and_create_new_model_config_based_app(
tenant_id=tenant_id,
app_mode=app_mode,
model_config_data=import_data.get("model_config"),
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background,
)
else:
raise ValueError("Invalid app mode")
return app
######### _import_and_create_new_model_config_based_app
存储 app 信息以及配置信息
@classmethod
def _import_and_create_new_model_config_based_app(
cls,
tenant_id: str,
app_mode: AppMode,
model_config_data: dict,
account: Account,
name: str,
description: str,
icon_type: str,
icon: str,
icon_background: str,
) -> App:
_"""_
_ Import app dsl and create new model config based app_
_ :param tenant_id: tenant id_
_ :param app_mode: app mode_
_ :param model_config_data: model config data_
_ :param account: Account instance_
_ :param name: app name_
_ :param description: app description_
_ :param icon: app icon_
_ :param icon_background: app icon background_
_ """_
_ _if not model_config_data:
raise ValueError("Missing model_config in data argument " "when app mode is chat, agent-chat or completion")
#创建app
app = cls._create_app(
tenant_id=tenant_id,
app_mode=app_mode,
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background,
)
app_model_config = AppModelConfig()
#创建配置
app_model_config = app_model_config.from_model_config_dict(model_config_data)
#更新关联的配置id
app_model_config.app_id = app.id
db.session.add(app_model_config)
db.session.commit()
app.app_model_config_id = app_model_config.id
app_model_config_was_updated.send(app, app_model_config=app_model_config)
return app