从单个 role 构建 profile
(role_name: str, role_data: Dict[str, Any])
| 73 | |
| 74 | |
| 75 | def build_profile_from_role(role_name: str, role_data: Dict[str, Any]) -> Dict[str, Any]: |
| 76 | """从单个 role 构建 profile""" |
| 77 | user_id = role_data.get("user_id", f"user_{role_name}") |
| 78 | now = datetime.now().isoformat() |
| 79 | |
| 80 | # 从 seed_directions 构建 core_directions |
| 81 | core_directions = {} |
| 82 | seed_directions = role_data.get("seed_directions", []) |
| 83 | for sd in seed_directions: |
| 84 | canonical_name = sd.get("canonical_name", sd.get("bootstrap_phrase", "")) |
| 85 | weight = float(sd.get("weight", 0.5)) |
| 86 | if canonical_name: |
| 87 | core_directions[canonical_name] = weight |
| 88 | |
| 89 | # 构建 must_read |
| 90 | must_read = { |
| 91 | "authors": role_data.get("must_read_authors", []) or [], |
| 92 | "institutions": role_data.get("must_read_institutions", []) or [], |
| 93 | "keywords": role_data.get("must_read_keywords", []) or [], |
| 94 | } |
| 95 | |
| 96 | # 构建 topic_weights (从 core_directions 复制) |
| 97 | topic_weights = { |
| 98 | k.replace(" ", "_").lower(): v |
| 99 | for k, v in core_directions.items() |
| 100 | } |
| 101 | |
| 102 | profile = { |
| 103 | "user_id": user_id, |
| 104 | "version": "0.1", |
| 105 | "created_at": now, |
| 106 | "updated_at": now, |
| 107 | "core_directions": core_directions, |
| 108 | "methodology_preferences": role_data.get("methodology_preferences") or {}, |
| 109 | "must_read": must_read, |
| 110 | "topic_weights": topic_weights, |
| 111 | "author_heat": {}, |
| 112 | "institution_heat": {}, |
| 113 | "interest_vector": [0.0] * 768, |
| 114 | "taste_profile": { |
| 115 | "preferred_work_type": role_data.get("preferred_work_type", []) or [], |
| 116 | "dispreferred_work_type": role_data.get("dispreferred_work_type", []) or [], |
| 117 | }, |
| 118 | "reading_history": [], |
| 119 | "behavior_logs_summary": { |
| 120 | "total_pushes": 0, |
| 121 | "total_selected": 0, |
| 122 | "total_skipped": 0, |
| 123 | "selection_rate": 0.0, |
| 124 | }, |
| 125 | "description": role_data.get("description", ""), |
| 126 | "secondary_topics": role_data.get("secondary_topics", []) or [], |
| 127 | "report_preferences": role_data.get("report_preferences") or {}, |
| 128 | "drift_plan": role_data.get("drift_plan") or {}, |
| 129 | "drift_state": { |
| 130 | "status": "stable", |
| 131 | "score": 0.0, |
| 132 | "last_drift_date": None, |