pipeline-llm/wwwroot/api/llm_dashboard_widget.dspy
yumoqing 671d320d59 feat(llm): status统一枚举SUCCEEDED/FAILED/PENDING/RUNNING+非SUCCEEDED记账状态NULL;llm_api_profile加method独立列(2026-09-06用户定夺)
- llm_usage.status 各家归一枚举(其他=recharge对账行);accounting_status仅SUCCEEDED行写created,其余NULL不冒充待记账
- govern_settle失败行不再挂created;充值行不写accounting_status
- 出账循环拾取条件 status='SUCCEEDED';面板/概览统计同步改
- llm_api_profile.method GET/POST独立列(默认POST),运行时读列决定动词;查询步骤存量兼容回退解析request_template.$.method
- 字典llm_usage_status更新五枚举;README同步
2026-09-06 17:15:40 +08:00

49 lines
2.4 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.

# llm_dashboard_widget.dspy — 模型治理总览(顶部统计条,返回 Bricks widget
dbname = get_module_dbname('pipeline_llm')
data = {"vendors": 0, "accounts": 0, "account_balance": 0, "models": 0,
"org_policies": 0, "usage_calls": 0, "usage_charge": 0}
try:
async with get_sor_context(request._run_ns, dbname) as sor:
vendors = await sor.sqlExe("SELECT COUNT(*) AS c FROM llm_vendor WHERE status='active'", {})
accounts = await sor.sqlExe(
"SELECT COUNT(*) AS c, COALESCE(SUM(balance),0) AS b FROM llm_account WHERE status='active'", {})
models = await sor.sqlExe("SELECT COUNT(*) AS c FROM llm_model WHERE status='active'", {})
orgs = await sor.sqlExe("SELECT COUNT(*) AS c FROM llm_org_policy WHERE status='active'", {})
usage = await sor.sqlExe(
"SELECT COUNT(*) AS c, COALESCE(SUM(charge),0) AS ch FROM llm_usage WHERE status='SUCCEEDED'", {})
await sor.sqlExe("COMMIT", {})
data['vendors'] = int(getattr(vendors[0], 'c', 0)) if vendors else 0
data['accounts'] = int(getattr(accounts[0], 'c', 0)) if accounts else 0
data['account_balance'] = round(float(getattr(accounts[0], 'b', 0)), 4) if accounts else 0
data['models'] = int(getattr(models[0], 'c', 0)) if models else 0
data['org_policies'] = int(getattr(orgs[0], 'c', 0)) if orgs else 0
data['usage_calls'] = int(getattr(usage[0], 'c', 0)) if usage else 0
data['usage_charge'] = round(float(getattr(usage[0], 'ch', 0)), 4) if usage else 0
except Exception:
pass
stats = [
('供应商', str(data['vendors'])),
('账号', str(data['accounts'])),
('账号总余额', str(data['account_balance'])),
('模型', str(data['models'])),
('组织策略', str(data['org_policies'])),
('调用次数', str(data['usage_calls'])),
('累计消费', str(data['usage_charge'])),
]
boxes = []
for label, val in stats:
boxes.append({
"widgettype": "VBox",
"options": {"css": "card", "padding": "12px 20px", "minWidth": "110px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": val, "cfontsize": 1.6, "color": "#1e293b", "halign": "middle"}},
{"widgettype": "Text", "options": {"text": label, "cfontsize": 0.9, "color": "#64748b", "halign": "middle"}},
]
})
return {
"widgettype": "HBox",
"options": {"gap": "12px", "padding": "0 0 16px 0", "wrap": "wrap"},
"subwidgets": boxes
}