# 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='ok'", {}) 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 }