"""创建风控 Agent 本地验收所需的模型端点和发布配置。""" from __future__ import annotations import asyncio import hashlib import json import sys from datetime import UTC, datetime from pathlib import Path from sqlalchemy import text PROJECT_ROOT = Path(__file__).resolve().parents[1] if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) from app.infrastructure.db import SessionFactory # noqa: E402 ADMIN_USER_ID = 9003 ENDPOINT_CODE = "deepseek-flash" RELEASE_NO = "risk-agent-local-v1" TOOL_CONFIGS = ( ("risk:risk_overview", {"allowed_tools": ["get_risk_overview"]}), ("risk:risk_search", {"allowed_tools": ["search_risk_alerts"]}), ("risk:risk_evidence", {"allowed_tools": ["get_alert_evidence"]}), ("risk:general", {"allowed_tools": []}), ) INTENT_CONFIGS = ( ("risk_overview", "风险概览", ["请查看当前风险概览", "当前有多少高风险预警"], ["get_risk_overview"]), ("risk_search", "风险查询", ["查询高风险预警", "查看规则 RW-007 命中的预警"], ["search_risk_alerts"]), ("risk_evidence", "预警证据", ["查询预警编号 ALERT-001 的证据", "查看这条预警的证据链"], ["get_alert_evidence"]), ("general", "通用风险咨询", ["奶龙风控智能助手能做什么", "说明你的功能边界"], []), ) def checksum(value: dict) -> str: payload = json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) return hashlib.sha256(payload.encode("utf-8")).hexdigest() async def seed() -> None: now = datetime.now(UTC).replace(tzinfo=None) async with SessionFactory() as session: await session.execute(text(""" INSERT INTO model_endpoint_config (endpoint_code, provider, model_name, base_url, secret_ref, capabilities, allowed_data_levels, context_window, timeout_ms, status, created_by, reviewer_id, reviewed_at, created_at, updated_at) VALUES (:endpoint_code, 'deepseek', 'deepseek-chat', 'https://api.deepseek.com', 'env:DEEPSEEK_API_KEY', :capabilities, :data_levels, 64000, 30000, 'active', :admin_id, :admin_id, :now, :now, :now) ON DUPLICATE KEY UPDATE provider=VALUES(provider), model_name=VALUES(model_name), base_url=VALUES(base_url), secret_ref=VALUES(secret_ref), capabilities=VALUES(capabilities), allowed_data_levels=VALUES(allowed_data_levels), context_window=VALUES(context_window), timeout_ms=VALUES(timeout_ms), status='active', reviewer_id=:admin_id, reviewed_at=:now, updated_at=:now """), { "endpoint_code": ENDPOINT_CODE, "capabilities": json.dumps([ "chat", "intent_classification", "risk_answer", "text_generation", ]), "data_levels": json.dumps(["internal"]), "admin_id": ADMIN_USER_ID, "now": now, }) release_id = await session.scalar( text("SELECT id FROM config_release WHERE status='active' LIMIT 1") ) if release_id is None: result = await session.execute(text(""" INSERT INTO config_release (release_no, title, change_summary, status, created_by, reviewer_id, reviewed_at, activated_at, created_at, updated_at) VALUES (:release_no, '奶龙风控智能助手本地配置', '发布 risk Agent 工具白名单和意图配置', 'active', :admin_id, :admin_id, :now, :now, :now, :now) """), {"release_no": RELEASE_NO, "admin_id": ADMIN_USER_ID, "now": now}) release_id = int(result.lastrowid) for config_key, value in TOOL_CONFIGS: await session.execute(text(""" INSERT INTO platform_config_item (release_id, namespace, config_key, value_json, schema_version, checksum, created_at) VALUES (:release_id, 'agent_tools', :config_key, :value_json, '1', :checksum, :now) ON DUPLICATE KEY UPDATE value_json=VALUES(value_json), schema_version=VALUES(schema_version), checksum=VALUES(checksum) """), { "release_id": release_id, "config_key": config_key, "value_json": json.dumps(value, ensure_ascii=False), "checksum": checksum(value), "now": now, }) for intent_code, intent_name, examples, allowed_tools in INTENT_CONFIGS: await session.execute(text(""" INSERT INTO agent_intent_config (agent_type, intent_code, intent_name, description, examples, classifier_instruction, confidence_threshold, max_clarification_rounds, transfer_on_failure, allowed_tools, priority, version, status, effective_at, created_by, reviewer_id, reviewed_at, created_at, updated_at) VALUES ('risk', :intent_code, :intent_name, :description, :examples, :instruction, 0.6500, 2, 1, :allowed_tools, 100, 1, 'active', :now, :admin_id, :admin_id, :now, :now, :now) ON DUPLICATE KEY UPDATE intent_name=VALUES(intent_name), description=VALUES(description), examples=VALUES(examples), classifier_instruction=VALUES(classifier_instruction), allowed_tools=VALUES(allowed_tools), status='active', effective_at=:now, reviewer_id=:admin_id, reviewed_at=:now, updated_at=:now """), { "intent_code": intent_code, "intent_name": intent_name, "description": f"奶龙风控智能助手:{intent_name}", "examples": json.dumps(examples, ensure_ascii=False), "instruction": "只处理风控只读查询、分析和边界说明,不执行人工处置。", "allowed_tools": json.dumps(allowed_tools, ensure_ascii=False), "admin_id": ADMIN_USER_ID, "now": now, }) await session.commit() print(f"risk_agent_config_ready release_id={release_id} endpoint={ENDPOINT_CODE}") if __name__ == "__main__": asyncio.run(seed())