rag/wwwroot/engine_configs_list/engine_form.dspy

67 lines
5.1 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
env = request._run_ns
async def get_cfg(t):
async with get_sor_context(env, 'rag') as sor:
recs = await sor.sqlExe(
"SELECT model_name, endpoint_url, api_key, status FROM rag_engine_configs WHERE engine_type=${t}$ LIMIT 1",
{"t": t})
if not recs:
return {"model_id": "", "api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1", "has_key": False, "status": ""}
r = recs[0]
return {"model_id": r.model_name or "", "api_base": r.endpoint_url or "https://dashscope.aliyuncs.com/compatible-mode/v1",
"has_key": bool(r.api_key), "status": r.status or "active"}
emb = await get_cfg("embedding")
rr = await get_cfg("rerank")
mm_emb = await get_cfg("mm_embedding")
mm_rr = await get_cfg("mm_rerank")
def card(title, desc, prefix, cfg):
shielded = (not cfg["model_id"]) or cfg["status"] != "active"
state = "⛔ 已屏蔽" if shielded else "✅ 启用中"
key_hint = "已配置(留空沿用)" if cfg["has_key"] else "未配置"
test_script = ("var p=this.parent.parent;"
"var m=bricks.getWidgetById('" + prefix + "_model',p).resultValue()||'';"
"var b=bricks.getWidgetById('" + prefix + "_base',p).resultValue()||'';"
"var k=bricks.getWidgetById('" + prefix + "_key',p).resultValue()||'';"
"fetch('./engine_test.dspy?_webbricks_=1&engine_type=" + prefix +
"&model_id='+encodeURIComponent(m)+'&api_base='+encodeURIComponent(b)+'&api_key='+encodeURIComponent(k))"
".then(function(r){return r.json()}).then(function(d){"
"bricks.show_message({title:'" + title + " 测试',message:d.message||d.error||JSON.stringify(d)})})")
save_script = ("var p=this.parent.parent;"
"var m=bricks.getWidgetById('" + prefix + "_model',p).resultValue()||'';"
"var b=bricks.getWidgetById('" + prefix + "_base',p).resultValue()||'';"
"var k=bricks.getWidgetById('" + prefix + "_key',p).resultValue()||'';"
"fetch('./engine_save.dspy?_webbricks_=1&engine_type=" + prefix +
"&model_id='+encodeURIComponent(m)+'&api_base='+encodeURIComponent(b)+'&api_key='+encodeURIComponent(k))"
".then(function(r){return r.json()}).then(function(d){"
"bricks.show_message({title:'保存',message:(d.error||('已保存:'+(d.shielded?'能力屏蔽':'已启用')))+'(刷新页面查看状态)'})})")
return {
"widgettype": "VBox", "options": {"width": "100%", "spacing": "12px", "bgcolor": "#f8f9fa", "padding": "16px", "css": "card"},
"subwidgets": [
{"widgettype": "HBox", "options": {"spacing": "12px", "alignItems": "center"}, "subwidgets": [
{"widgettype": "Text", "options": {"text": title, "cfontsize": 16, "fontWeight": "bold"}},
{"widgettype": "Text", "id": prefix + "_state", "options": {"text": state, "cfontsize": 13, "color": "#f56c6c" if shielded else "#50b86c"}}
]},
{"widgettype": "Text", "options": {"text": desc, "cfontsize": 12, "color": "#888"}},
{"widgettype": "HBox", "options": {"spacing": "12px", "wrap": True}, "subwidgets": [
{"widgettype": "UiCode", "id": prefix + "_model", "options": {"name": prefix + "_model", "dataurl": "/rag/engine_configs_list/engine_options.dspy", "text": "未配置(屏蔽)", "cwidth": 24, "allowempty": True, "value": cfg["model_id"]}},
{"widgettype": "Input", "id": prefix + "_base", "options": {"label": "API Base", "name": prefix + "_base", "value": cfg["api_base"], "cwidth": 30}},
{"widgettype": "Input", "id": prefix + "_key", "options": {"label": "API Key" + key_hint + "", "name": prefix + "_key", "type": "password", "cwidth": 24}}
]},
{"widgettype": "HBox", "options": {"spacing": "12px"}, "subwidgets": [
{"widgettype": "Button", "options": {"label": "测试连通", "css": "outline", "binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self", "script": test_script}]}},
{"widgettype": "Button", "options": {"label": "保存", "bgcolor": "#10b981", "color": "#fff", "binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self", "script": save_script}]}}
]}
]
}
result = {"widgettype": "VBox", "options": {"width": "100%", "spacing": "16px"}, "subwidgets": [
card("🔤 文本向量化Embedding", "文本知识库(bge-m3引擎)必需。模型留空或停用 = 屏蔽(文档仍入库可浏览,检索不可用)。", "embedding", emb),
card("🎯 文本重排Rerank", "文本检索结果精排,可选。未配置时按召回分排序。", "rerank", rr),
card("🖼️ 多模态向量化qwen3-vl", "多媒体知识库必需(图文跨模态)。支持以文搜图/以图搜文。留空=屏蔽多媒体检索。", "mm_embedding", mm_emb),
card("🖼️ 多模态重排qwen3-vl-rerank", "多媒体/混合检索精排,可选。未配置时按召回分排序。", "mm_rerank", mm_rr)
]}
return json.dumps(result, ensure_ascii=False)