- json/llm_call_trace_list.json: noedit只读列表;exclouded隐藏id/req_path/resp_path/org_id;
url/note加宽;kind/method内联枚举(含gen同步生成,此前草稿引用的get_llm_kind_options.dspy不存在);
删color_mapping(bricks全库0消费的死配置);toolbar查看IO+binds urlwidget→PopupWindow(85%)
url不带?id=${id}$——生成期ArgsConvert会eval成<built-in function id>垃圾串,
行数据id经_add_event_data自动并入params(dapi/llmage生产同款)
- api/llm_call_trace_io.dspy: 薄代理(get_user门禁+get_userorgid机构隔离)→env.llm_call_trace_io;
修草稿4处实锤bug:get_user未await/user.get当dict/sor块外使用/返回PopupWindow套娃
- init.py: llm_call_trace_io读表+同批次+llm_usage上下文(块内读全拷dict)→读文件
(trace.trace_root realpath前缀校验防穿越)→TabPanel三tab(摘要Html+pre escape防注入/
请求/响应CodeEditor readonly mode=null);单侧150K截断提示盘上路径;env注册
- api/llm_project_cost_query.dspy: 改{total,rows}契约接Tabular data_url(PageDataLoader);
wwwroot/llm_project_cost/index.ui: InlineForm(date_from/date_to/status)+Tabular;
script内getWidgetById起点bricks.app(弹窗DOM挂body下,app.root搜不到)
- card_popup.dspy: titles加llm_call_trace;新增page_targets白名单挂按项目费用页;
index.ui挂两张卡片(调用原文追踪/按项目费用)
- accounting.py: _maybe_cleanup_traces每日一次接cleanup_expired(trace.py铁律3
文档承诺worker每日调但循环没接,补齐);放抢锁前(清理幂等多进程同日无害)
- scripts/load_path.py: 注释说明/**通配已覆盖新页面(rbac check_roles_path前缀匹配)
- models/mysql.ddl/README/design-spec: 9张表同步(kind补gen枚举;3.9节;F19/F20)
- scripts/test_llm_call_trace_io.py: stub harness 22断言全过(隔离/穿越/转义/截断/每日门控)
- .gitignore: wwwroot/llm_call_trace/生成目录不入库
374 lines
21 KiB
XML
374 lines
21 KiB
XML
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"width": "100%",
|
||
"height": "100%",
|
||
"padding": "0"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {
|
||
"width": "100%",
|
||
"alignItems": "center",
|
||
"marginBottom": "24px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Title2",
|
||
"options": {
|
||
"text": "模型治理"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "Filler"
|
||
},
|
||
{
|
||
"widgettype": "Text",
|
||
"options": {
|
||
"text": "供应商/账号/模型 · 容错策略 · 限额限流 · 双维度记账 · 点击卡片弹窗处理",
|
||
"cfontsize": 1.2
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "urlwidget",
|
||
"options": {
|
||
"url": "{{entire_url('/pipeline-llm/api/llm_dashboard_widget.dspy')}}"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "VScrollPanel",
|
||
"options": {
|
||
"css": "filler"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"spacing": 24
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "ResponsableBox",
|
||
"options": {
|
||
"gap": "16px",
|
||
"minWidth": "300px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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_project_cost');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": "按项目分组统计调用次数/成本/客户应付/token(非项目调用单列一组)",
|
||
"cfontsize": 1.2
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"css": "card",
|
||
"cwidth": 25,
|
||
"padding": "16px",
|
||
"cursor": "pointer"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"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_call_trace');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": "每次上游往返的上行请求/下行响应原文(脱敏落盘,保留90天),选中行点「查看IO」",
|
||
"cfontsize": 1.2
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|