fix: 全面系统修复 — delivery目标修正 + 脚本同步 + refresh_mtf_cache import修复 + clean_watchlist硬编码修复
修复清单: - cron delivery修正:10个job从deliver=origin/all改为local,消除推送错误 - refresh_mtf_cache.py:替换strategy_lifecycle.PORTFOLIO_PATH导入为mofin_db直接读DB - clean_watchlist.py:修复mo_data导入名错误和JSON硬编码路径 - MoFin/scripts/与profile scripts互相补全,双向sync到一致 - price_monitor.py:现金源从portfolio_summary表改为cash_log(Dad确认的现金权威) - 更新watchlist.json加入000850华茂股份
This commit is contained in:
Executable
+194
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
检查 MoFin prompt-manager 的跨提示词依赖一致性。
|
||||
|
||||
功能:
|
||||
1. 对每个有 depends_on 的 prompt,验证上游 prompt 的 current_version 匹配
|
||||
2. 对每个有 impacts 的 prompt,验证下游 prompt 的 depends_on.version 是否已正确更新
|
||||
3. 输出状态:✅ 全部一致 / ⚠️ 有差异(列出差异详情)
|
||||
|
||||
用法:
|
||||
python3 check-prompt-deps.py
|
||||
python3 check-prompt-deps.py --registry /path/to/registry.json
|
||||
|
||||
集成方式:
|
||||
每次做策略分析前,或每次更新提示词后,运行一次确认一致性。
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_REGISTRY = "/home/hmo/projects/MoFin/data/prompts/registry.json"
|
||||
|
||||
def load_registry(path: str) -> dict:
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
def prompt_map(registry: dict) -> dict:
|
||||
"""将 prompts 数组转为 id -> prompt 的字典"""
|
||||
return {p["id"]: p for p in registry.get("prompts", [])}
|
||||
|
||||
def check_depends_on(pm: dict) -> list:
|
||||
"""检查所有 depends_on 声明是否匹配上游的 current_version"""
|
||||
issues = []
|
||||
for p in pm.values():
|
||||
deps = p.get("depends_on")
|
||||
if not deps:
|
||||
continue
|
||||
target_id = deps.get("prompt")
|
||||
expected_ver = deps.get("version")
|
||||
target = pm.get(target_id)
|
||||
if not target:
|
||||
issues.append({
|
||||
"type": "MISSING_UPSTREAM",
|
||||
"prompt": p["id"],
|
||||
"detail": f"依赖的上游提示词 '{target_id}' 在 registry 中不存在"
|
||||
})
|
||||
continue
|
||||
actual_ver = target.get("current_version")
|
||||
if actual_ver != expected_ver:
|
||||
issues.append({
|
||||
"type": "VERSION_MISMATCH",
|
||||
"prompt": p["id"],
|
||||
"detail": (
|
||||
f"{p['id']}.depends_on → {target_id}@{expected_ver}, "
|
||||
f"但 {target_id}.current_version = {actual_ver}"
|
||||
)
|
||||
})
|
||||
return issues
|
||||
|
||||
def check_impacts_fulfilled(pm: dict) -> list:
|
||||
"""检查有 impacts 声明的 prompt,其下游是否已更新 depends_on 到当前版本"""
|
||||
issues = []
|
||||
for p in pm.values():
|
||||
impacted = p.get("impacts")
|
||||
if not impacted:
|
||||
continue
|
||||
my_id = p["id"]
|
||||
my_ver = p.get("current_version")
|
||||
for downstream_id in impacted:
|
||||
downstream = pm.get(downstream_id)
|
||||
if not downstream:
|
||||
issues.append({
|
||||
"type": "MISSING_DOWNSTREAM",
|
||||
"prompt": my_id,
|
||||
"detail": f"impacts 中列出的 '{downstream_id}' 在 registry 中不存在"
|
||||
})
|
||||
continue
|
||||
dd = downstream.get("depends_on", {})
|
||||
expected_ver = dd.get("version") if dd.get("prompt") == my_id else None
|
||||
if expected_ver is None:
|
||||
issues.append({
|
||||
"type": "MISSING_DEPENDS_ON",
|
||||
"prompt": my_id,
|
||||
"detail": (
|
||||
f"{my_id}.impacts 声明了 {downstream_id}, "
|
||||
f"但 {downstream_id} 没有 depends_on → {my_id}"
|
||||
)
|
||||
})
|
||||
elif expected_ver != my_ver:
|
||||
issues.append({
|
||||
"type": "STALE_DEPENDENCY",
|
||||
"prompt": my_id,
|
||||
"detail": (
|
||||
f"{my_id}.current_version = {my_ver}, "
|
||||
f"但 {downstream_id}.depends_on.version = {expected_ver}"
|
||||
)
|
||||
})
|
||||
return issues
|
||||
|
||||
def check_integrity(pm: dict) -> list:
|
||||
"""基本格式校验"""
|
||||
issues = []
|
||||
for p in pm.values():
|
||||
deps = p.get("depends_on")
|
||||
if deps:
|
||||
if not deps.get("prompt") or not deps.get("version"):
|
||||
issues.append({
|
||||
"type": "INVALID_DEPENDS_ON",
|
||||
"prompt": p["id"],
|
||||
"detail": "depends_on 结构不完整,需包含 prompt 和 version"
|
||||
})
|
||||
if not deps.get("reason"):
|
||||
issues.append({
|
||||
"type": "MISSING_REASON",
|
||||
"prompt": p["id"],
|
||||
"detail": "depends_on 缺少 reason 字段(说明为什么依赖)"
|
||||
})
|
||||
impacts = p.get("impacts")
|
||||
if impacts and not isinstance(impacts, list):
|
||||
issues.append({
|
||||
"type": "INVALID_IMPACTS",
|
||||
"prompt": p["id"],
|
||||
"detail": "impacts 必须是数组"
|
||||
})
|
||||
return issues
|
||||
|
||||
def main():
|
||||
reg_path = DEFAULT_REGISTRY
|
||||
if len(sys.argv) > 2 and sys.argv[1] == "--registry":
|
||||
reg_path = sys.argv[2]
|
||||
if not os.path.exists(reg_path):
|
||||
print(f"❌ 找不到 registry 文件: {reg_path}")
|
||||
sys.exit(1)
|
||||
|
||||
registry = load_registry(reg_path)
|
||||
pm = prompt_map(registry)
|
||||
|
||||
all_issues = []
|
||||
all_issues.extend(check_integrity(pm))
|
||||
all_issues.extend(check_depends_on(pm))
|
||||
all_issues.extend(check_impacts_fulfilled(pm))
|
||||
|
||||
print(f"📋 MoFin 提示词版本依赖检查 ({registry.get('updated_at', '?')})")
|
||||
print(f" 共 {len(pm)} 个提示词")
|
||||
print()
|
||||
|
||||
if not all_issues:
|
||||
print("✅ 全部一致,无依赖问题")
|
||||
# 打印当前依赖状态一览
|
||||
print()
|
||||
for p in pm.values():
|
||||
deps = p.get("depends_on")
|
||||
impacts = p.get("impacts")
|
||||
status = p["id"]
|
||||
if deps:
|
||||
status += f" ← 依赖 {deps['prompt']}@{deps['version']}"
|
||||
if impacts:
|
||||
status += f" → 影响 {', '.join(impacts)}"
|
||||
print(f" {status}")
|
||||
sys.exit(0)
|
||||
|
||||
# 按类型分组输出
|
||||
categories = {
|
||||
"MISSING_UPSTREAM": "上游提示词缺失",
|
||||
"VERSION_MISMATCH": "依赖版本不匹配",
|
||||
"MISSING_DOWNSTREAM": "下游提示词缺失",
|
||||
"MISSING_DEPENDS_ON": "下游缺少 depends_on 声明",
|
||||
"STALE_DEPENDENCY": "下游依赖版本未同步更新",
|
||||
"INVALID_DEPENDS_ON": "depends_on 结构不完整",
|
||||
"MISSING_REASON": "缺少依赖原因说明",
|
||||
"INVALID_IMPACTS": "impacts 格式错误",
|
||||
}
|
||||
|
||||
has_error = False
|
||||
for issue in all_issues:
|
||||
cat = categories.get(issue["type"], issue["type"])
|
||||
marker = "❌" if issue["type"] in ("VERSION_MISMATCH", "STALE_DEPENDENCY", "MISSING_UPSTREAM") else "⚠️"
|
||||
if marker == "❌":
|
||||
has_error = True
|
||||
print(f"{marker} [{issue['prompt']}] {cat}")
|
||||
print(f" {issue['detail']}")
|
||||
|
||||
print()
|
||||
if has_error:
|
||||
print("❗ 存在必须修复的依赖问题,请在更新提示词前先处理。")
|
||||
else:
|
||||
print("💡 无版本冲突,但上面有信息缺失/规范问题,建议补充。")
|
||||
|
||||
sys.exit(1 if has_error else 0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user