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

90 lines
5.9 KiB
Python

from pathlib import Path
import shutil
root = Path(r'C:\wechat_rpa')
target = root / 'protocol_engine.py'
backup = Path(__file__).parent / 'protocol-before'
backup.mkdir(parents=True, exist_ok=True)
if not (backup / target.name).exists():
shutil.copy2(target, backup / target.name)
source = target.read_text(encoding='utf-8')
source = source.replace("reply_text='',log=None,progress=None):", "reply_text='',log=None,progress=None,review_assistant=None):", 1)
source = source.replace(" self._lock=threading.RLock();self._owned_db=db is None", " self._lock=threading.RLock();self._owned_db=db is None\n self._review_assistant=review_assistant;self._assistant_warning=''", 1)
anchor = ' def _save(self):'
helpers = Path(__file__).with_name('protocol_assistant_helpers.txt').read_text(encoding='utf-8')
assert anchor in source and 'def _assistant_call(' not in source
source = source.replace(anchor, helpers + '\n' + anchor, 1)
anchor = " phase={'queued':'等待消息合并','generating':'正在生成回复','awaiting_review':'等待审核',"
source = source.replace(anchor, " if stage=='awaiting_review':self._register_assistant_review(key,s)\n" + anchor, 1)
anchor = " if self._skip_excluded_session(key,message):return"
source = source.replace(anchor, """ if self._assistant_recipient(message['conv_id']):
with self._lock:
self._pending.pop(key,None)
if event:self._seen[key]=event
self._save()
return
if old and message.get('is_self'):
context=self.db.get_conversation_context_by_id(self.account,message['conv_id'],limit=500)
if self._reconcile_assistant_review(key,old,context):return
if self._assistant_pending(old):return
""" + anchor, 1)
source = source.replace("'detected_by':'protocol_db','detection_ts':now,'reply_text':'','awaiting_review':False,'content_type':message.get('content_type')}", "'detected_by':'protocol_db','detection_ts':now,'reply_text':'','awaiting_review':False,'content_type':message.get('content_type'),\n 'database_event':dict(message)}", 1)
anchor = ' self._completed_polls+=1'
source = source.replace(anchor, " self._assistant_call('enqueue_notifications',default=None)\n" + anchor, 1)
anchor = " if self._skip_excluded_session(key,state,expected_state=state):\n if excluded is not None:excluded.append(_session_exclusion(state))"
source = source.replace(anchor, """ if self._assistant_recipient(state['conv_id']):
if excluded is not None:excluded.append('配置的医疗助理会话不参与自动回复')
return False
""" + anchor, 1)
anchor = " last=(context or {}).get('last_message')\n if not last:return False"
source = source.replace(anchor, """ if self._reconcile_assistant_review(key,state,context):return False
last=(context or {}).get('last_message')
if not last:return False
if last.get('is_self') and self._assistant_pending(state):return False""", 1)
anchor = " if _send_protection(state):return\n if self._skip_excluded_session(key,state,expected_state=state):return"
source = source.replace(anchor, """ if _send_protection(state):return
if self._assistant_recipient(state['conv_id']):
with self._lock:
if self._pending.get(key) is state:self._pending.pop(key,None);self._save()
return
if self._reconcile_assistant_review(key,state):return
""" + ' if self._skip_excluded_session(key,state,expected_state=state):return', 1)
start = source.index(" with self._lock:\n if self._pending.get(key) is not state:return\n state.update(send_state='sending',awaiting_review=False)")
end = source.index(' def _needs_review(self,state):', start)
send_body = source[start:end]
send_body = send_body.replace(' self.reply_count+=1', " self._assistant_call('record_automated_send',state,receipt,default=None)\n self.reply_count+=1", 1)
source = source[:start] + ''' import send_lock
if not send_lock.try_acquire('protocol:'+str(threading.get_ident()),timeout=0):return
try:
if not self._current(key,state):return
self._send_ready(key,state)
finally:send_lock.release()
def _send_ready(self,key,state):
''' + send_body + source[end:]
old = ''' def _needs_review(self,state):
if self.send_mode=='review':return True,'人工审核后点击“通过并发送”'
import ai_config
from review_policy import selective_review_reason
reason=selective_review_reason(state,state.get('staged_user_text',''),state.get('reply_text',''),
rules=getattr(ai_config,'AI_REVIEW_RULES',[]) or [])
return bool(reason),reason
'''
new = ''' def _needs_review(self,state):
import ai_config
from review_policy import selective_review_reason
reason=selective_review_reason(state,state.get('staged_user_text',''),state.get('reply_text',''),
rules=getattr(ai_config,'AI_REVIEW_RULES',[]) or [])
if reason:return True,reason
if self._assistant_pending(state):
return True,state.get('review_reason') or '本会话仍有待处理审核,请由医疗助理回复客户'
if self.send_mode=='review' and not self._assistant_call('resumed',state.get('conv_id','')):
return True,'人工审核后点击“通过并发送”'
return False,''
'''
assert old in source
source = source.replace(old,new,1)
source = source.replace(' def close(self):\n self.sender.close()', " def close(self):\n if self._review_assistant is not None:\n try:self._review_assistant.close()\n except Exception:pass\n self.sender.close()", 1)
target.write_text(source,encoding='utf-8',newline='')
print('protocol assistant integration patched')