52 lines
5.8 KiB
Python
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')
|