feat(ui): 模型治理卡片全部弹窗化(card_popup白名单)+模型注册弹窗加自动配置(auto_config_popup:API/定价链接或正文→内部助手全链)与上线检查(online_check_popup:选模型→真实调用+记账检查+状态复核→告知结果);删下方llm_content展示容器(2026-09-07用户定夺)
This commit is contained in:
parent
34ef256fe6
commit
bd732bf35f
21
README.md
21
README.md
@ -97,6 +97,27 @@
|
||||
且 r2v 判定加「输出为视频」限定防误吸文本输出模型);
|
||||
`_MEDIA_INPUT_CAPS` 加 m2t(模板生成按输入媒体处理)。
|
||||
|
||||
## 治理页面(弹窗化,2026-09-07 用户定夺)
|
||||
|
||||
`wwwroot/index.ui` 顶部统计条(llm_dashboard_widget)+ 7 张功能卡片。
|
||||
**每张卡片点击后弹窗处理(PopupWindow 85%×85%),不再在页面下方 llm_content 容器展示**:
|
||||
- `api/card_popup.dspy`:target 白名单(llm_vendor/llm_model/llm_api_profile/llm_org_policy/
|
||||
llm_org_quota/llm_user_quota/llm_usage)→ 弹窗内嵌对应 CRUD 页 urlwidget;
|
||||
非白名单 target 返回「无效的功能入口」提示(不拼 URL)。
|
||||
- 模型注册弹窗(target=llm_model)顶部额外两个按钮:
|
||||
- **🤖 自动配置** → `api/auto_config_popup.dspy`:输入 API 文档与定价信息的链接或正文,
|
||||
「开始自动配置」按钮 script 组装指令后驱动弹窗内嵌 AgentIO
|
||||
(pipeline_id=platform_general,弹窗级独立 session_id,spec 锚定会话隔离天然成立),
|
||||
内部助手全链完成(抓取/提取/落库/定价/测试/记账检查)后汇报模型状态。
|
||||
- **✅ 上线检查** → `api/online_check_popup.dspy`:模型下拉
|
||||
(`api/get_llm_online_check_models.dspy`,value=模型名,test_model_call 按名调用)+
|
||||
「上线检查」按钮 → 内部助手按模型配置后的测试过程处理(test_model_call 真实调用 →
|
||||
check_model_accounting 记账检查 → platform_llm_status 状态复核),最后明确告知通过/不通过。
|
||||
- 驱动 AgentIO 的机制:`io.inputw.textw.setValue(指令)` + `io.inputw.input_finished()`
|
||||
(AgentInput 原生方法 dispatch('inputed') → AgentIO POST 流),零自定义 JS 文件。
|
||||
- 权限:新 dspy 都在 `/pipeline-llm/**` logined 通配内,无需新增 RBAC;
|
||||
内部助手工具本身有 owner 角色代码层硬门禁(pipeline-platform)。
|
||||
|
||||
## API 文档端点(2026-09-05)
|
||||
|
||||
`/pipeline-llm/api/v1/docs/`(RBAC 授权 any,公开文档照 sage /bricks/docs 先例):
|
||||
|
||||
64
wwwroot/api/auto_config_popup.dspy
Normal file
64
wwwroot/api/auto_config_popup.dspy
Normal file
@ -0,0 +1,64 @@
|
||||
# auto_config_popup.dspy — 模型自动配置弹窗(2026-09-07 用户定夺)
|
||||
# 输入 API 文档与定价信息的链接或正文,内部助手(platform_general)自动完成
|
||||
# 抓取→提取→落库→定价→测试→记账检查全链,结束后汇报模型状态。
|
||||
|
||||
import json as _json
|
||||
import random
|
||||
|
||||
uid = await get_user()
|
||||
if not uid:
|
||||
return _json.dumps({
|
||||
"widgettype": "PopupWindow",
|
||||
"options": {"title": "提示", "cwidth": 30, "cheight": 8, "auto_open": True},
|
||||
"subwidgets": [{"widgettype": "Text", "options": {"text": "请先登录", "padding": "20px"}}]
|
||||
}, ensure_ascii=False)
|
||||
|
||||
# 每个弹窗实例独立会话(spec 锚定按 pipeline_id:user_id:session_id 隔离,
|
||||
# extract→apply 的会话级缓存在同一弹窗内天然可用)
|
||||
session_id = 'llmauto' + str(random.randint(100000, 999999))
|
||||
chat_url = entire_url('/pipeline_core/api/agent_chat.dspy') + '?session_id=' + session_id + '&pipeline_id=platform_general'
|
||||
|
||||
# 开始自动配置:读两个输入框(UiText.resultValue),组装指令,驱动 AgentIO 发送
|
||||
# (input_finished 是 AgentInput 原生方法:dispatch('inputed') → AgentIO 走 POST 流)
|
||||
start_script = (
|
||||
"var io=bricks.getWidgetById('llm_auto_io',bricks.app);if(!io||!io.inputw)return;"
|
||||
"var aw=bricks.getWidgetById('llm_auto_api',bricks.app);"
|
||||
"var pw=bricks.getWidgetById('llm_auto_pricing',bricks.app);"
|
||||
"var api=aw&&aw.resultValue?String(aw.resultValue()||'').trim():'';"
|
||||
"var pricing=pw&&pw.resultValue?String(pw.resultValue()||'').trim():'';"
|
||||
"if(!api){new bricks.Message({title:'缺少输入',message:'请填写 API 文档链接或粘贴文档正文'});return;}"
|
||||
"var p='请自动配置模型。API 文档(链接或正文)如下:\\n'+api;"
|
||||
"if(pricing){p+='\\n定价信息(链接或正文,若 API 文档已含定价则以文档为准)如下:\\n'+pricing;}"
|
||||
"p+='\\n请按模型自动配置全链工作流一口气完成(抓取/提取/落库/定价/测试/记账检查),"
|
||||
"结束后汇报模型状态(配置/定价/测试/记账四段结果+遗留事项)。';"
|
||||
"io.inputw.textw.setValue(p);io.inputw.input_finished();")
|
||||
|
||||
resp = {
|
||||
"widgettype": "PopupWindow",
|
||||
"id": "llm_auto_cfg_pw",
|
||||
"options": {"title": "🤖 模型自动配置(内部助手)", "width": "85%", "height": "85%", "auto_open": True},
|
||||
"subwidgets": [{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "filler", "width": "100%", "height": "100%", "padding": "12px", "gap": "8px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {
|
||||
"text": "粘贴 API 文档链接或直接粘贴文档正文;定价可单独给出(链接或正文),未给则从 API 文档提取。点击「开始自动配置」后由内部助手完成全链并汇报模型状态。",
|
||||
"cfontsize": 0.9, "color": "#64748b", "halign": "left"}},
|
||||
{"widgettype": "Text", "options": {"text": "API 文档(链接或正文)", "cfontsize": 0.95, "halign": "left"}},
|
||||
{"widgettype": "UiText", "id": "llm_auto_api",
|
||||
"options": {"name": "llm_auto_api", "placeholder": "https://help.aliyun.com/... 或直接粘贴文档正文"}},
|
||||
{"widgettype": "Text", "options": {"text": "定价信息(链接或正文,可空)", "cfontsize": 0.95, "halign": "left"}},
|
||||
{"widgettype": "UiText", "id": "llm_auto_pricing",
|
||||
"options": {"name": "llm_auto_pricing", "placeholder": "定价页链接或价格表正文(元/千token、元/秒等,须来自文档原文)"}},
|
||||
{"widgettype": "Button", "id": "llm_auto_start",
|
||||
"options": {"label": "开始自动配置", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self", "script": start_script}]},
|
||||
{"widgettype": "AgentIO", "id": "llm_auto_io",
|
||||
"options": {"css": "filler", "url": chat_url,
|
||||
"model_dataurl": entire_url('/pipeline_core/api/agent_model_options.dspy') + '?session_id=' + session_id + '&pipeline_id=platform_general',
|
||||
"model_cwidth": 14,
|
||||
"placeholder": "也可以直接对内部助手说话,例如:通读这份文档并配置模型 <URL> ..."}}
|
||||
]}]
|
||||
}
|
||||
return _json.dumps(resp, ensure_ascii=False)
|
||||
76
wwwroot/api/card_popup.dspy
Normal file
76
wwwroot/api/card_popup.dspy
Normal file
@ -0,0 +1,76 @@
|
||||
# card_popup.dspy — 模型治理功能卡片弹窗(2026-09-07 用户定夺:卡片点击一律弹窗处理,不在页面下方展示)
|
||||
# 参数:target=白名单内的 CRUD 目录名;模型注册弹窗额外带「自动配置/上线检查」工具按钮
|
||||
|
||||
import json as _json
|
||||
|
||||
uid = await get_user()
|
||||
if not uid:
|
||||
return _json.dumps({
|
||||
"widgettype": "PopupWindow",
|
||||
"options": {"title": "提示", "cwidth": 30, "cheight": 8, "auto_open": True},
|
||||
"subwidgets": [{"widgettype": "Text", "options": {"text": "请先登录", "padding": "20px"}}]
|
||||
}, ensure_ascii=False)
|
||||
|
||||
target = ((params_kw or {}).get('target', '') or '').strip()
|
||||
titles = {
|
||||
'llm_vendor': '供应商与端点',
|
||||
'llm_model': '模型注册',
|
||||
'llm_api_profile': '适配模板',
|
||||
'llm_org_policy': '组织容错策略',
|
||||
'llm_org_quota': '组织限额限流',
|
||||
'llm_user_quota': '个人限额限流',
|
||||
'llm_usage': '用量流水',
|
||||
}
|
||||
if target not in titles:
|
||||
return _json.dumps({
|
||||
"widgettype": "PopupWindow",
|
||||
"options": {"title": "提示", "cwidth": 40, "cheight": 10, "auto_open": True},
|
||||
"subwidgets": [{"widgettype": "Text", "options": {
|
||||
"text": "无效的功能入口:" + target, "padding": "20px"}}]
|
||||
}, ensure_ascii=False)
|
||||
|
||||
subwidgets = []
|
||||
if target == 'llm_model':
|
||||
# 模型注册工具栏:自动配置(内部助手全链)+ 上线检查(真实调用测试+记账检查)
|
||||
auto_url = entire_url('/pipeline-llm/api/auto_config_popup.dspy')
|
||||
check_url = entire_url('/pipeline-llm/api/online_check_popup.dspy')
|
||||
auto_script = (
|
||||
"var old=bricks.getWidgetById('llm_auto_cfg_pw',bricks.app);"
|
||||
"if(old&&old.destroy){old.destroy();}"
|
||||
"var r=await fetch(" + _json.dumps(auto_url) + ");"
|
||||
"var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}")
|
||||
check_script = (
|
||||
"var old=bricks.getWidgetById('llm_online_chk_pw',bricks.app);"
|
||||
"if(old&&old.destroy){old.destroy();}"
|
||||
"var r=await fetch(" + _json.dumps(check_url) + ");"
|
||||
"var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}")
|
||||
subwidgets.append({
|
||||
"widgettype": "HBox",
|
||||
"options": {"gap": "8px", "padding": "0 0 10px 0", "alignItems": "center"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Button",
|
||||
"options": {"label": "🤖 自动配置", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self", "script": auto_script}]},
|
||||
{"widgettype": "Button",
|
||||
"options": {"label": "✅ 上线检查", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self", "script": check_script}]},
|
||||
{"widgettype": "Text",
|
||||
"options": {"text": "自动配置:粘贴 API/定价文档链接或正文,内部助手全链完成并汇报模型状态;上线检查:选择模型后真实调用测试+记账检查",
|
||||
"cfontsize": 0.85, "color": "#94a3b8", "halign": "left"}},
|
||||
]})
|
||||
subwidgets.append({
|
||||
"widgettype": "urlwidget",
|
||||
"options": {"url": entire_url('/pipeline-llm/' + target)}})
|
||||
|
||||
resp = {
|
||||
"widgettype": "PopupWindow",
|
||||
"id": "llm_card_pw",
|
||||
"options": {"title": titles[target], "width": "85%", "height": "85%", "auto_open": True},
|
||||
"subwidgets": [{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "filler", "width": "100%", "height": "100%", "padding": "12px"},
|
||||
"subwidgets": subwidgets}]
|
||||
}
|
||||
return _json.dumps(resp, ensure_ascii=False)
|
||||
15
wwwroot/api/get_llm_online_check_models.dspy
Normal file
15
wwwroot/api/get_llm_online_check_models.dspy
Normal file
@ -0,0 +1,15 @@
|
||||
# get_llm_online_check_models.dspy — 上线检查用模型下拉(value=模型名,test_model_call 按名调用)
|
||||
dbname = get_module_dbname('pipeline_llm')
|
||||
try:
|
||||
async with get_sor_context(request._run_ns, dbname) as sor:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT name, capability, status FROM llm_model WHERE status='active' ORDER BY name", {})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
except Exception as e:
|
||||
return {"success": False, "message": str(e), "data": []}
|
||||
out = []
|
||||
for r in (recs or []):
|
||||
n = getattr(r, 'name', '') or ''
|
||||
c = getattr(r, 'capability', '') or ''
|
||||
out.append({"value": n, "text": (n + '(' + c + ')') if c else n})
|
||||
return out
|
||||
64
wwwroot/api/online_check_popup.dspy
Normal file
64
wwwroot/api/online_check_popup.dspy
Normal file
@ -0,0 +1,64 @@
|
||||
# online_check_popup.dspy — 模型上线检查弹窗(2026-09-07 用户定夺)
|
||||
# 选择一个模型 → 点击上线检查 → 内部助手按模型配置后的测试过程处理:
|
||||
# test_model_call 真实调用(完整治理链)→ check_model_accounting 记账检查
|
||||
# (created 等 60~120 秒复查)→ platform_llm_status 复核状态 → 给出最终结论。
|
||||
|
||||
import json as _json
|
||||
import random
|
||||
|
||||
uid = await get_user()
|
||||
if not uid:
|
||||
return _json.dumps({
|
||||
"widgettype": "PopupWindow",
|
||||
"options": {"title": "提示", "cwidth": 30, "cheight": 8, "auto_open": True},
|
||||
"subwidgets": [{"widgettype": "Text", "options": {"text": "请先登录", "padding": "20px"}}]
|
||||
}, ensure_ascii=False)
|
||||
|
||||
session_id = 'llmchk' + str(random.randint(100000, 999999))
|
||||
chat_url = entire_url('/pipeline_core/api/agent_chat.dspy') + '?session_id=' + session_id + '&pipeline_id=platform_general'
|
||||
models_url = entire_url('/pipeline-llm/api/get_llm_online_check_models.dspy')
|
||||
|
||||
# 上线检查:读模型下拉(UiCode.resultValue = 模型名),下达标准检查指令
|
||||
check_script = (
|
||||
"var io=bricks.getWidgetById('llm_chk_io',bricks.app);if(!io||!io.inputw)return;"
|
||||
"var sel=bricks.getWidgetById('llm_chk_model',bricks.app);"
|
||||
"var m=sel&&sel.resultValue?String(sel.resultValue()||'').trim():'';"
|
||||
"if(!m){new bricks.Message({title:'缺少输入',message:'请先选择要检查的模型'});return;}"
|
||||
"var p='请对模型「'+m+'」执行上线检查,按模型配置后的测试过程处理:"
|
||||
"1) test_model_call 真实调用测试(生成类模型缺业务参数时先问我,不要编造);"
|
||||
"2) check_model_accounting 用返回的 task_ref 检查记账(created 则等 60~120 秒复查一次);"
|
||||
"3) platform_llm_status 复核模型/定价/供应商状态;"
|
||||
"4) 最后明确告诉我检查结果:通过 / 不通过 + 各环节明细 + 遗留事项,不要粉饰。';"
|
||||
"io.inputw.textw.setValue(p);io.inputw.input_finished();")
|
||||
|
||||
resp = {
|
||||
"widgettype": "PopupWindow",
|
||||
"id": "llm_online_chk_pw",
|
||||
"options": {"title": "✅ 模型上线检查(内部助手)", "width": "85%", "height": "85%", "auto_open": True},
|
||||
"subwidgets": [{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "filler", "width": "100%", "height": "100%", "padding": "12px", "gap": "8px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {
|
||||
"text": "选择模型后点击「上线检查」:内部助手执行真实调用测试(完整治理链)→ 记账检查(独立复算金额)→ 状态复核,最后给出通过/不通过结论。",
|
||||
"cfontsize": 0.9, "color": "#64748b", "halign": "left"}},
|
||||
{"widgettype": "HBox",
|
||||
"options": {"gap": "8px", "alignItems": "center"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "模型:", "cfontsize": 0.95, "halign": "left"}},
|
||||
{"widgettype": "UiCode", "id": "llm_chk_model",
|
||||
"options": {"name": "llm_chk_model", "dataurl": models_url,
|
||||
"valueField": "value", "textField": "text",
|
||||
"nullable": True, "cwidth": 30}},
|
||||
{"widgettype": "Button", "id": "llm_chk_start",
|
||||
"options": {"label": "上线检查", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self", "script": check_script}]}]},
|
||||
{"widgettype": "AgentIO", "id": "llm_chk_io",
|
||||
"options": {"css": "filler", "url": chat_url,
|
||||
"model_dataurl": entire_url('/pipeline_core/api/agent_model_options.dspy') + '?session_id=' + session_id + '&pipeline_id=platform_general',
|
||||
"model_cwidth": 14,
|
||||
"placeholder": "也可以直接对内部助手说话,例如:对模型 xxx 做上线检查"}}
|
||||
]}]
|
||||
}
|
||||
return _json.dumps(resp, ensure_ascii=False)
|
||||
181
wwwroot/index.ui
181
wwwroot/index.ui
@ -26,7 +26,7 @@
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "供应商/账号/模型 · 容错策略 · 限额限流 · 双维度记账",
|
||||
"text": "供应商/账号/模型 · 容错策略 · 限额限流 · 双维度记账 · 点击卡片弹窗处理",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
@ -69,17 +69,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_vendor')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_vendor');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "供应商与端点", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "供应商协议 + 全球端点目录(国内/国际,配置一次全账号共用)", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "供应商与端点",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "供应商协议 + 全球端点目录(国内/国际,配置一次全账号共用)",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -94,17 +103,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_model')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_model');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "模型注册", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "能力分类(t2t/…)、挂定价项目(ppid)、成本/售价", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "模型注册",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "能力分类(t2t/…)、挂定价项目(ppid)、成本/售价 · 🤖自动配置 · ✅上线检查",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -119,17 +137,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_api_profile')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_api_profile');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "适配模板", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "协议×能力形态的请求/响应模板(按形态去重,不按模型开)", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "适配模板",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "协议×能力形态的请求/响应模板(按形态去重,不按模型开)",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -144,17 +171,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_org_policy')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_org_policy');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "组织容错策略", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "组织级主模型 + 备模型链 + 端点偏好(prefer/must)", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "组织容错策略",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "组织级主模型 + 备模型链 + 端点偏好(prefer/must)",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -169,17 +205,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_org_quota')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_org_quota');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "组织限额限流", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "组织池充值/余额 + 组织 QPM 上限", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "组织限额限流",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "组织池充值/余额 + 组织 QPM 上限",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -194,17 +239,26 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_user_quota')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_user_quota');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "个人限额限流", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "个人额度上限 + 个人 QPM(共享组织池模式)", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "个人限额限流",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "个人额度上限 + 个人 QPM(共享组织池模式)",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -219,26 +273,31 @@
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "app.llm_content",
|
||||
"options": {
|
||||
"url": "{{entire_url('/pipeline-llm/llm_usage')}}"
|
||||
},
|
||||
"mode": "replace"
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var old=bricks.getWidgetById('llm_card_pw',bricks.app);if(old&&old.destroy){old.destroy();}var r=await fetch('{{entire_url('/pipeline-llm/api/card_popup.dspy')}}?target=llm_usage');var d=await r.json();if(d&&d.widgettype){bricks.widgetBuild(d,bricks.app);}else{bricks.show_message({title:'打开失败',message:'未能加载功能窗口'});}"
|
||||
}
|
||||
],
|
||||
"subwidgets": [
|
||||
{"widgettype": "Title4", "options": {"text": "用量流水", "marginBottom": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "双维度记账:成本侧(账号)+ 消费侧(组织/个人)", "cfontsize": 1.2}}
|
||||
{
|
||||
"widgettype": "Title4",
|
||||
"options": {
|
||||
"text": "用量流水",
|
||||
"marginBottom": "8px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "Text",
|
||||
"options": {
|
||||
"text": "双维度记账:成本侧(账号)+ 消费侧(组织/个人)",
|
||||
"cfontsize": 1.2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"id": "llm_content"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user