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

74 lines
6.4 KiB
Python

from pathlib import Path
root = Path('C:/wechat_rpa')
path = root / 'protocol_engine.py'
text = path.read_text(encoding='utf-8')
def replace(old,new,count=1):
global text
assert text.count(old)==count,(str(path),old[:90],text.count(old),count)
text=text.replace(old,new)
replace('def _restore_review_details(state):', '''def _send_protection(state):
"""Use either durable field; missing/old schema must not enable a replay."""
status=str(state.get('send_state') or '')
stage=str(state.get('stage') or '')
if status=='sending' or stage=='sending':return 'sending'
if status in ('uncertain','unknown','sent_uncommitted') or stage in ('receipt_check','uncertain','unknown'):
return 'uncertain'
if status=='failed' or stage=='failed':return 'failed'
return 'uncertain' if status else ''
def _restore_review_details(state):''')
replace(" if state.get('send_state')=='sending':state.update(send_state='uncertain',stage='receipt_check',last_error='上次发送结果待核对,禁止自动重发')", " if _send_protection(state) in ('sending','uncertain'):state.update(send_state='uncertain',stage='receipt_check',last_error=state.get('last_error') or '上次发送结果待核对,禁止自动重发')")
replace("s.get('send_state')=='uncertain'", "_send_protection(s)=='uncertain'",2)
replace("if old and old.get('send_state') in ('sending','uncertain','failed'):return", "if old and _send_protection(old):return")
replace("if state.get('send_state') in ('sending','uncertain','failed') or state.get('stage')=='error':return", "if _send_protection(state) or state.get('stage')=='error':return")
replace("if s.get('send_state') in ('sending','uncertain','failed'):result['protected'].append(key);continue", "if _send_protection(s):result['protected'].append(key);continue")
replace("if self._pending.get(key) is state:state['send_state']='';self._save()", "if self._pending.get(key) is state:state.update(send_state='',stage='queued',stage_detail='发送前检查已取消,等待重新核对');self._save()")
replace(' def handoff_pending_replies(self, keys):', ' def handoff_pending_replies(self, keys, *, confirm_uncertain=False):')
replace(" result={'handed_off':[], 'deleted':[], 'missing':[], 'protected':[], 'scheduled':[]}", " result={'handed_off':[], 'deleted':[], 'missing':[], 'protected':[], 'scheduled':[], 'requires_confirmation':[]}")
replace(" if state.get('account')!=self.account or state.get('send_state')=='sending':\n result['protected'].append(key);continue", """ protection=_send_protection(state)
if state.get('account')!=self.account or protection=='sending':
result['protected'].append(key);continue
if protection=='uncertain' and not confirm_uncertain:
result['protected'].append(key);result['requires_confirmation'].append(key);continue""")
compile(text,str(path),'exec')
path.write_text(text,encoding='utf-8')
for root in (Path('C:/wechat_rpa'),Path('C:/kefu/wechat_rpa')):
path=root/'gui_runtime.py'
text=path.read_text(encoding='utf-8')
replace('def delete_pending_reply_file(keys, path="", *, handoff=False):', 'def delete_pending_reply_file(keys, path="", *, handoff=False, confirm_uncertain=False):')
replace(' result = {"deleted": [], "missing": sorted(requested), "protected": [], "scheduled": []}\n if not requested:', ' result = {"deleted": [], "missing": sorted(requested), "protected": [], "scheduled": []}\n if handoff:\n result["requires_confirmation"] = []\n if not requested:')
replace(' if handoff and str(state.get("send_state") or "") == "sending":\n result["protected"].append(key)\n continue', ''' send_state = str(state.get("send_state") or "")
stage = str(state.get("stage") or "")
sending = send_state == "sending" or stage == "sending"
uncertain = send_state in {"uncertain", "sent_uncommitted", "unknown"} or stage in {"receipt_check", "uncertain", "unknown"}
if sending or (uncertain and not (handoff and confirm_uncertain)):
result["protected"].append(key)
if handoff and uncertain and not sending:
result["requires_confirmation"].append(key)
continue''')
replace('def handoff_pending_reply_file(keys, path=""):', 'def handoff_pending_reply_file(keys, path="", *, confirm_uncertain=False):')
replace(' result = delete_pending_reply_file(keys, path, handoff=True)', ' result = delete_pending_reply_file(keys, path, handoff=True, confirm_uncertain=confirm_uncertain)')
replace(' self._queued_handoffs = set()', ' self._queued_handoffs = set()\n self._queued_handoff_confirmations = set()')
replace(' def _handoff_bot_tasks(bot, keys):', ' def _handoff_bot_tasks(bot, keys, *, confirm_uncertain=False):')
replace(' return handoff(keys)', ' return handoff(keys, confirm_uncertain=confirm_uncertain)')
replace(' def handoff_pending_tasks(self, keys):', ' def handoff_pending_tasks(self, keys, *, confirm_uncertain=False):')
replace(' self._queued_handoffs.update(requested)\n return', ' self._queued_handoffs.update(requested)\n if confirm_uncertain:\n self._queued_handoff_confirmations.update(requested)\n return')
replace(' return self._handoff_bot_tasks(bot, requested)', ' return self._handoff_bot_tasks(bot, requested, confirm_uncertain=confirm_uncertain)')
replace(' requested = set(self._queued_handoffs)\n self._queued_handoffs.clear()\n if requested:\n self._handoff_bot_tasks(bot, requested)', ''' requested = set(self._queued_handoffs)
confirmed = requested & self._queued_handoff_confirmations
self._queued_handoffs.clear()
self._queued_handoff_confirmations.clear()
if requested - confirmed:
self._handoff_bot_tasks(bot, requested - confirmed, confirm_uncertain=False)
if confirmed:
self._handoff_bot_tasks(bot, confirmed, confirm_uncertain=True)''')
compile(text,str(path),'exec')
path.write_text(text,encoding='utf-8')
print('Both runtimes and protocol engine now require explicit uncertainty confirmation and protect stage-only sends.')