from __future__ import annotations from app.models.agent_asset import AgentAsset from app.schemas.agent_asset import AgentAssetRuleJsonRead, AgentAssetRuleJsonWrite from app.services.agent_asset_spreadsheet import RISK_RULES_LIBRARY, RULE_LIBRARY_NAMES class AgentAssetJsonRuleMixin: def _resolve_json_risk_rule_document(self, asset: AgentAsset) -> tuple[str, str]: config_json = dict(asset.config_json or {}) detail_mode = str(config_json.get("detail_mode") or "").strip().lower() if detail_mode != "json_risk": raise ValueError("当前资产不是 JSON 风险规则。") rule_library = str(config_json.get("rule_library") or RISK_RULES_LIBRARY).strip() if rule_library not in RULE_LIBRARY_NAMES: raise ValueError("规则库目录不合法。") rule_document = config_json.get("rule_document") if not isinstance(rule_document, dict): raise ValueError("规则资产缺少 rule_document 配置。") file_name = str(rule_document.get("file_name") or "").strip() if not file_name: raise ValueError("规则资产缺少 JSON 文件名。") return rule_library, file_name def read_rule_json(self, asset_id: str) -> AgentAssetRuleJsonRead: asset = self.repository.get(asset_id) if asset is None: raise LookupError("资产不存在。") rule_library, file_name = self._resolve_json_risk_rule_document(asset) payload = self.rule_library_manager.read_rule_library_json( library=rule_library, file_name=file_name, ) return AgentAssetRuleJsonRead( file_name=file_name, rule_code=str(payload.get("rule_code") or asset.code or ""), name=str(payload.get("name") or asset.name or ""), description=str(payload.get("description") or asset.description or "").strip(), evaluator=str(payload.get("evaluator") or ""), ontology_signal=str(payload.get("ontology_signal") or "") or None, flow_diagram_svg=str(payload.get("flow_diagram_svg") or "") or None, inputs=payload.get("inputs") if isinstance(payload.get("inputs"), dict) else {}, outcomes=payload.get("outcomes") if isinstance(payload.get("outcomes"), dict) else {}, payload=payload, ) def write_rule_json( self, asset_id: str, *, body: AgentAssetRuleJsonWrite, actor: str, request_id: str | None = None, ) -> AgentAssetRuleJsonRead: asset = self.repository.get(asset_id) if asset is None: raise LookupError("资产不存在。") rule_library, file_name = self._resolve_json_risk_rule_document(asset) payload = dict(body.payload or {}) asset_code = str(asset.code or "").strip() if asset_code and str(payload.get("rule_code") or "").strip() not in {"", asset_code}: raise ValueError("规则 JSON 的 rule_code 必须与资产编码一致。") if asset_code and not str(payload.get("rule_code") or "").strip(): payload["rule_code"] = asset_code saved = self.rule_library_manager.write_rule_library_json( library=rule_library, file_name=file_name, payload=payload, ) rule_description = str(saved.get("description") or "").strip() if rule_description: asset.description = rule_description rule_name = str(saved.get("name") or "").strip() if rule_name: asset.name = rule_name risk_category = str(saved.get("risk_category") or "").strip() if risk_category: config_json = dict(asset.config_json or {}) config_json["risk_category"] = risk_category asset.config_json = config_json asset.scenario_json = [risk_category] self.audit_service.log_action( actor=actor, action="update_agent_asset_rule_json", resource_type=asset.asset_type, resource_id=asset.id, before_json={"file_name": file_name}, after_json={"file_name": file_name, "rule_code": saved.get("rule_code")}, request_id=request_id, ) self.db.commit() return self.read_rule_json(asset_id)