Files
kefu/deploy/review-visibility-20260916/fix_visual_review.py
T
2026-09-21 10:34:06 +08:00

89 lines
4.5 KiB
Python

from pathlib import Path
import shutil
ROOTS = [Path('C:/wechat_rpa'), Path('C:/kefu/wechat_rpa')]
def replace_once(source, before, after):
assert source.count(before) == 1, (before[:100], source.count(before))
return source.replace(before, after)
for root in ROOTS:
target = root / 'wechat_bot.py'
original = target.read_bytes()
source = original.decode('utf-8').replace('\r\n', '\n')
source = replace_once(source,
' value.get("confirmed_unread", False)\n or str(value.get("send_state") or "")\n',
' value.get("confirmed_unread", False)\n or value.get("awaiting_review", False)\n or value.get("review_approved", False)\n or str(value.get("stage") or "") == "manual_review"\n or str(value.get("send_state") or "")\n')
marker = ' "awaiting_review": bool(value.get("awaiting_review", False)),\n'
assert source.count(marker) == 2
source = source.replace(marker, marker + ''' "review_reason": str(value.get("review_reason") or "")[:500],
"review_origin": str(value.get("review_origin") or "")[:16],
"review_approved": bool(value.get("review_approved", False)),
"review_approved_at": value.get("review_approved_at", 0.0),
"judge_risk": str(value.get("judge_risk") or "")[:32],
"judge_reason": str(value.get("judge_reason") or "")[:500],
''')
source = replace_once(source,
' if send_baseline_blocks is not None:\n',
''' # Older clients discarded review reasons. Treat an unclassified
# restored draft as still requiring a decision, never as permission
# to send merely because the global mode is now automatic.
if state["awaiting_review"] or (
state["stage"] == "manual_review" and not state["review_approved"]
):
state["awaiting_review"] = True
state["stage"] = "manual_review"
if not state["review_reason"] and state["review_origin"] != "global":
legacy_detail = str(value.get("stage_detail") or "")
state["review_reason"] = (
legacy_detail[:500]
if "命中审核规则" in legacy_detail or "裁判" in legacy_detail
else "历史审核原因未保存,请人工核对本条草稿"
)
if send_baseline_blocks is not None:
''')
source = replace_once(source,
''' if self._reply_awaiting_review(fp):
self._set_task_stage(
fp,
"manual_review",
detail="AI 回复已填入输入框,等待人工核对并发送",
)
self._log_queue_event(fp, "待审核", "回复草稿已填入企业微信输入框")
return
''',
''' if self._reply_awaiting_review(fp):
state = self._pending_reply_state(fp) or {}
reason = str(state.get("review_reason") or "").strip()
detail = (
f"{reason},已停止自动发送,等待人工核对并发送"
if reason else "AI 回复已填入输入框,等待人工核对并发送"
)
self._set_task_stage(fp, "manual_review", detail=detail)
self._log_queue_event(fp, "待审核", detail)
return
''')
source = replace_once(source,
' state.pop("review_reason", None)\n',
''' state.pop("review_reason", None)
state.pop("review_origin", None)
state.pop("judge_risk", None)
state.pop("judge_reason", None)
state.pop("judge_score", None)
state.pop("model_chosen", None)
state.pop("model_candidates", None)
''')
source = replace_once(source,
' pending_state["review_reason"] = rule_reason\n',
' pending_state["review_reason"] = rule_reason\n'
' pending_state["review_origin"] = "global" if blanket_review else "rule"\n')
backup = root / 'backups/review-visibility-20260916'
backup.mkdir(parents=True, exist_ok=True)
assert not (backup / target.name).exists(), 'Backup already exists; inspect before rerun'
shutil.copy2(target, backup / target.name)
newline = '\r\n' if b'\r\n' in original else '\n'
target.write_bytes(source.replace('\n', newline).encode('utf-8'))
print(root, 'patched visual review persistence and reasons')