feat(llm): profile表补path/headers自含字段;model表补query_profile_ids后续步骤模板链(异步模型提交→查询→[下载]);CRUD接helper+placeholder说明
This commit is contained in:
parent
4b6b4a2c95
commit
d5dd9f4be2
@ -6,6 +6,7 @@
|
|||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": [
|
"exclouded": [
|
||||||
"id",
|
"id",
|
||||||
|
"headers",
|
||||||
"request_template",
|
"request_template",
|
||||||
"response_template",
|
"response_template",
|
||||||
"param_schema"
|
"param_schema"
|
||||||
@ -28,6 +29,12 @@
|
|||||||
"dataurl": "{{entire_url('../api/get_llm_status_options.dspy')}}",
|
"dataurl": "{{entire_url('../api/get_llm_status_options.dspy')}}",
|
||||||
"valueField": "value",
|
"valueField": "value",
|
||||||
"textField": "text"
|
"textField": "text"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"placeholder": "请求路径(相对端点base_url),如 /chat/completions"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"placeholder": "请求头JSON,如 {\"Authorization\": \"Bearer {{api_key}}\", \"Content-Type\": \"application/json\"}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,8 @@
|
|||||||
"sortby": "name",
|
"sortby": "name",
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": [
|
"exclouded": [
|
||||||
"id"
|
"id",
|
||||||
|
"query_profile_ids"
|
||||||
],
|
],
|
||||||
"alters": {
|
"alters": {
|
||||||
"vendor_id": {
|
"vendor_id": {
|
||||||
@ -37,6 +38,16 @@
|
|||||||
"dataurl": "{{entire_url('../api/get_llm_ppid_options.dspy')}}",
|
"dataurl": "{{entire_url('../api/get_llm_ppid_options.dspy')}}",
|
||||||
"valueField": "value",
|
"valueField": "value",
|
||||||
"textField": "text"
|
"textField": "text"
|
||||||
|
},
|
||||||
|
"sync_mode": {
|
||||||
|
"uitype": "code",
|
||||||
|
"data": [
|
||||||
|
{"value": "sync", "text": "同步"},
|
||||||
|
{"value": "async", "text": "异步(提交后轮询)"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"query_profile_ids": {
|
||||||
|
"placeholder": "后续步骤模板ID的JSON数组(异步模型:提交后顺序执行 查询→[下载]),如 [\"模板ID1\",\"模板ID2\"]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -46,9 +57,9 @@
|
|||||||
"updated_at"
|
"updated_at"
|
||||||
],
|
],
|
||||||
"editable": {
|
"editable": {
|
||||||
"new_data_url": "{{entire_url('./add_llm_model.dspy')}}",
|
"new_data_url": "{{entire_url('../api/add_llm_model.dspy')}}",
|
||||||
"update_data_url": "{{entire_url('./update_llm_model.dspy')}}",
|
"update_data_url": "{{entire_url('../api/update_llm_model.dspy')}}",
|
||||||
"delete_data_url": "{{entire_url('./delete_llm_model.dspy')}}"
|
"delete_data_url": "{{entire_url('../api/delete_llm_model.dspy')}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,17 @@
|
|||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "'t2t'"
|
"default": "'t2t'"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "path",
|
||||||
|
"title": "请求路径",
|
||||||
|
"type": "str",
|
||||||
|
"length": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "headers",
|
||||||
|
"title": "请求头(JSON)",
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "request_template",
|
"name": "request_template",
|
||||||
"title": "请求模板(Jinja2)",
|
"title": "请求模板(Jinja2)",
|
||||||
|
|||||||
@ -65,6 +65,11 @@
|
|||||||
"type": "str",
|
"type": "str",
|
||||||
"length": 32
|
"length": 32
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "query_profile_ids",
|
||||||
|
"title": "后续步骤模板链(JSON)",
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ppid",
|
"name": "ppid",
|
||||||
"title": "定价项目ID",
|
"title": "定价项目ID",
|
||||||
|
|||||||
@ -41,6 +41,7 @@ CREATE TABLE IF NOT EXISTS llm_model (
|
|||||||
`capability` varchar(20) NOT NULL DEFAULT 't2t' comment '能力类型',
|
`capability` varchar(20) NOT NULL DEFAULT 't2t' comment '能力类型',
|
||||||
`sync_mode` varchar(10) NOT NULL DEFAULT 'sync' comment '同步性',
|
`sync_mode` varchar(10) NOT NULL DEFAULT 'sync' comment '同步性',
|
||||||
`profile_id` varchar(32) comment '适配模板ID',
|
`profile_id` varchar(32) comment '适配模板ID',
|
||||||
|
`query_profile_ids` text comment '后续步骤模板链(JSON数组,异步模型提交后顺序执行:查询/下载)',
|
||||||
`ppid` varchar(32) comment '定价项目ID(pricing_program)',
|
`ppid` varchar(32) comment '定价项目ID(pricing_program)',
|
||||||
`price_input` decimal(12,6) NOT NULL DEFAULT 0 comment '输入单价(元/千token)',
|
`price_input` decimal(12,6) NOT NULL DEFAULT 0 comment '输入单价(元/千token)',
|
||||||
`price_output` decimal(12,6) NOT NULL DEFAULT 0 comment '输出单价(元/千token)',
|
`price_output` decimal(12,6) NOT NULL DEFAULT 0 comment '输出单价(元/千token)',
|
||||||
@ -62,6 +63,8 @@ CREATE TABLE IF NOT EXISTS llm_api_profile (
|
|||||||
`name` varchar(100) NOT NULL comment '模板名称',
|
`name` varchar(100) NOT NULL comment '模板名称',
|
||||||
`protocol` varchar(20) NOT NULL comment '协议类型',
|
`protocol` varchar(20) NOT NULL comment '协议类型',
|
||||||
`capability` varchar(20) NOT NULL DEFAULT 't2t' comment '能力类型',
|
`capability` varchar(20) NOT NULL DEFAULT 't2t' comment '能力类型',
|
||||||
|
`path` varchar(200) comment '请求路径(相对端点base_url,如/chat/completions)',
|
||||||
|
`headers` text comment '请求头(JSON,含认证头模板)',
|
||||||
`request_template` text comment '请求模板(Jinja2)',
|
`request_template` text comment '请求模板(Jinja2)',
|
||||||
`response_template` text comment '响应模板(Jinja2)',
|
`response_template` text comment '响应模板(Jinja2)',
|
||||||
`param_schema` text comment '参数Schema(bricks input_fields)',
|
`param_schema` text comment '参数Schema(bricks input_fields)',
|
||||||
|
|||||||
@ -277,6 +277,15 @@ async def create_llm_model(params_kw):
|
|||||||
if dp.strip():
|
if dp.strip():
|
||||||
json.loads(dp) # 校验合法
|
json.loads(dp) # 校验合法
|
||||||
data['default_params'] = dp
|
data['default_params'] = dp
|
||||||
|
# 后续步骤模板链:JSON 数组校验
|
||||||
|
qp = data.get('query_profile_ids', '') or ''
|
||||||
|
if isinstance(qp, (list, dict)):
|
||||||
|
qp = json.dumps(qp, ensure_ascii=False)
|
||||||
|
if qp.strip():
|
||||||
|
ql = json.loads(qp)
|
||||||
|
if not isinstance(ql, list):
|
||||||
|
raise ValueError('query_profile_ids 必须是 JSON 数组')
|
||||||
|
data['query_profile_ids'] = qp
|
||||||
data['id'] = getID()
|
data['id'] = getID()
|
||||||
db, dbname = _get_sor()
|
db, dbname = _get_sor()
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
@ -303,6 +312,15 @@ async def update_llm_model(params_kw):
|
|||||||
if dp.strip():
|
if dp.strip():
|
||||||
json.loads(dp)
|
json.loads(dp)
|
||||||
data['default_params'] = dp
|
data['default_params'] = dp
|
||||||
|
if 'query_profile_ids' in data:
|
||||||
|
qp = data.get('query_profile_ids', '') or ''
|
||||||
|
if isinstance(qp, (list, dict)):
|
||||||
|
qp = json.dumps(qp, ensure_ascii=False)
|
||||||
|
if qp.strip():
|
||||||
|
ql = json.loads(qp)
|
||||||
|
if not isinstance(ql, list):
|
||||||
|
raise ValueError('query_profile_ids 必须是 JSON 数组')
|
||||||
|
data['query_profile_ids'] = qp
|
||||||
db, dbname = _get_sor()
|
db, dbname = _get_sor()
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
await sor.U('llm_model', data)
|
await sor.U('llm_model', data)
|
||||||
|
|||||||
5
wwwroot/api/add_llm_model.dspy
Normal file
5
wwwroot/api/add_llm_model.dspy
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# add_llm_model.dspy — 薄封装:走模块 helper(注册名唯一+JSON字段校验)
|
||||||
|
r = json.loads(await create_llm_model(dict(params_kw or {})))
|
||||||
|
if r.get('success'):
|
||||||
|
return {"widgettype": "Message", "options": {"title": "Success", "message": r.get('message') or 'ok', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
|
return {"widgettype": "Error", "options": {"title": "Error", "message": r.get('message') or 'failed', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
5
wwwroot/api/delete_llm_model.dspy
Normal file
5
wwwroot/api/delete_llm_model.dspy
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# delete_llm_model.dspy — 薄封装:走模块 helper(被组织策略引用时禁止删除)
|
||||||
|
r = json.loads(await delete_llm_model(dict(params_kw or {})))
|
||||||
|
if r.get('success'):
|
||||||
|
return {"widgettype": "Message", "options": {"title": "Success", "message": r.get('message') or 'ok', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
|
return {"widgettype": "Error", "options": {"title": "Error", "message": r.get('message') or 'failed', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
5
wwwroot/api/update_llm_model.dspy
Normal file
5
wwwroot/api/update_llm_model.dspy
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# update_llm_model.dspy — 薄封装:走模块 helper(JSON字段校验)
|
||||||
|
r = json.loads(await update_llm_model(dict(params_kw or {})))
|
||||||
|
if r.get('success'):
|
||||||
|
return {"widgettype": "Message", "options": {"title": "Success", "message": r.get('message') or 'ok', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
|
return {"widgettype": "Error", "options": {"title": "Error", "message": r.get('message') or 'failed', "timeout": 3, "cwidth": 16, "cheight": 9}}
|
||||||
Loading…
x
Reference in New Issue
Block a user