Files
kefu/deploy/review-assistant-20260917/patch_protocol_cancellation.py
T
2026-09-21 10:34:06 +08:00

52 lines
5.8 KiB
Python

from pathlib import Path
p = Path(r'C:\wechat_rpa\protocol_engine.py')
s = p.read_text(encoding='utf-8')
assert 'def _flush_assistant_cancellations' not in s
s = s.replace("self._manual_handoffs={}\n", "self._manual_handoffs={};self._assistant_cancellations={}\n", 1)
s = s.replace(" self._contact_blocked=raw.get('contactBlocked',{})\n", " self._assistant_cancellations=raw.get('assistant_cancellations',{})\n if not isinstance(self._assistant_cancellations,dict):raise NativeUnavailable('审核提醒取消记录格式错误')\n self._assistant_cancellations={k:v for k,v in self._assistant_cancellations.items() if isinstance(v,dict)}\n self._contact_blocked=raw.get('contactBlocked',{})\n", 1)
s = s.replace(" if saved and saved['status']=='confirmed':\n self._pending.pop(key,None)\n", " if saved and saved['status']=='confirmed':\n self._assistant_call('record_automated_send',state,saved.get('result') or {},default=None)\n self._pending.pop(key,None)\n", 1)
s = s.replace(" if not assistant.enabled():return default\n", " if method not in ('cancel_review','record_automated_send') and not assistant.enabled():return default\n", 1)
where = " def _assistant_recipient(self,conv_id):\n"
helpers = ''' def _queue_assistant_cancellation(self,state):
# Persist only an exact episode target, never a conversation-wide retry
# that could cancel a later independent risk review.
review_id=state.get('assistant_review_id')
if review_id:
self._assistant_cancellations[review_id]={
'account':state.get('account'), 'conv_id':state.get('conv_id'),
'assistant_review_id':review_id}
def _flush_assistant_cancellations(self):
with self._lock:items=list(self._assistant_cancellations.items())
for review_id,state in items:
if state.get('account')!=self.account:continue
if self._assistant_call('cancel_review',state) is not True:continue
with self._lock:
if self._assistant_cancellations.get(review_id) is not state:continue
self._assistant_cancellations.pop(review_id,None)
try:self._save()
except Exception:
self._assistant_cancellations[review_id]=state
raise
def _assistant_cancellation_pending(self,state):
with self._lock:
return any(item.get('account')==self.account and item.get('conv_id')==state.get('conv_id')
for item in self._assistant_cancellations.values())
'''
s = s.replace(where, helpers + where, 1)
s = s.replace("'manual_handoffs':self._manual_handoffs}", "'manual_handoffs':self._manual_handoffs,'assistant_cancellations':self._assistant_cancellations}", 1)
s = s.replace(" def poll_once(self):\n if self.stop_event.is_set():return\n", " def poll_once(self):\n if self.stop_event.is_set():return\n try:self._flush_assistant_cancellations()\n except Exception as exc:self._isolate_task_error(None,exc)\n", 1)
s = s.replace(" if _send_protection(state):return\n if self._assistant_recipient(state['conv_id']):", " if _send_protection(state) or self._assistant_cancellation_pending(state):return\n if self._assistant_recipient(state['conv_id']):", 1)
s = s.replace(" def _control(self,keys,action):\n result=", " def _control(self,keys,action):\n removed=[]\n result=", 1)
s = s.replace(" with self._lock:\n for key in keys:\n", " with self._lock:\n previous_pending=dict(self._pending);previous_cancellations=dict(self._assistant_cancellations)\n for key in keys:\n", 1)
s = s.replace(" if action=='delete':self._pending.pop(key,None);result['deleted'].append(key)\n", " if action=='delete':\n self._queue_assistant_cancellation(s)\n self._pending.pop(key,None);result['deleted'].append(key);removed.append(s)\n", 1)
s = s.replace(" self._save();self._reply_wakeup.set()\n return result\n", " try:self._save()\n except Exception:\n if action=='delete':\n self._pending=previous_pending;self._assistant_cancellations=previous_cancellations\n raise\n self._reply_wakeup.set()\n self._flush_assistant_cancellations()\n for state in removed:\n if not state.get('assistant_review_id'):self._assistant_call('cancel_review',state)\n return result\n", 1)
s = s.replace(" previous_handoffs=dict(self._manual_handoffs);previous_attention=self.needs_attention\n", " previous_handoffs=dict(self._manual_handoffs);previous_attention=self.needs_attention\n previous_cancellations=dict(self._assistant_cancellations)\n", 1)
s = s.replace(" self._pending.pop(key,None)\n result['handed_off']", " self._queue_assistant_cancellation(state)\n self._pending.pop(key,None)\n result['handed_off']", 1)
s = s.replace(" self._manual_handoffs=previous_handoffs;self.needs_attention=previous_attention\n", " self._manual_handoffs=previous_handoffs;self.needs_attention=previous_attention\n self._assistant_cancellations=previous_cancellations\n", 1)
s = s.replace(" for key,state in removed:\n self.log", " self._flush_assistant_cancellations()\n for key,state in removed:\n if not state.get('assistant_review_id'):self._assistant_call('cancel_review',state)\n self.log", 1)
p.write_text(s, encoding='utf-8', newline='\n')
print('Protocol explicit dismissals now persist exact-episode cancellation retries')