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

75 lines
4.1 KiB
Plaintext

def _assistant_call(self,method,*args,default=False):
"""Optional coordination cannot stop the protocol listener or approve work."""
try:
if self._review_assistant is None:
from review_assistant import ReviewAssistantCoordinator
self._review_assistant=ReviewAssistantCoordinator(
root=self.path.parent,account=self.account,pid=self.pid,db=self.db,log=self.log)
assistant=self._review_assistant
if not assistant.enabled():return default
return getattr(assistant,method)(*args)
except Exception as exc:
warning=f'{method}:{type(exc).__name__}'
if warning!=self._assistant_warning:
self._assistant_warning=warning
try:self.log('[医疗助理] 协作状态暂不可用,协议监听继续;'+warning)
except Exception:pass
return default
def _assistant_recipient(self,conv_id):
return bool(self._assistant_call('is_recipient',conv_id))
def _assistant_pending(self,state):
# Preserve an already-registered review if coordination storage is
# temporarily unavailable; never interpret a read failure as approval.
if state.get('assistant_review_id') and not state.get('approved'):return True
return bool(self._assistant_call('has_pending',state.get('conv_id','')))
def _register_assistant_review(self,key,state,context=None):
if _send_protection(state) or state.get('account')!=self.account:return
if not state.get('awaiting_review') or state.get('approved'):return
if context is None:
context=self.db.get_conversation_context_by_id(self.account,state['conv_id'],limit=500)
review_id=self._assistant_call('ensure_review',state,context,default='')
if review_id and review_id!=state.get('assistant_review_id'):
with self._lock:
if self._pending.get(key) is state:
state['assistant_review_id']=review_id
self._save()
def _reconcile_assistant_review(self,key,state,context=None):
if (state.get('account')!=self.account or _send_protection(state)
or not (state.get('awaiting_review') or state.get('assistant_review_id')
or self._assistant_call('has_pending',state.get('conv_id','')))):
return False
if context is None:
context=self.db.get_conversation_context_by_id(self.account,state['conv_id'],limit=500)
self._register_assistant_review(key,state,context)
evidence=self._assistant_call('reconcile',state,context,default=None)
if not isinstance(evidence,dict) or not evidence:return False
if (evidence.get('review_id') and state.get('assistant_review_id')
and evidence['review_id']!=state['assistant_review_id']):return False
with self._lock:
if self._pending.get(key) is not state or _send_protection(state):return False
previous_seen=self._seen.get(key)
if state.get('dedup_key'):self._seen[key]=state['dedup_key']
self._pending.pop(key,None)
try:self._save()
except Exception:
self._pending[key]=state
if previous_seen is None:self._seen.pop(key,None)
else:self._seen[key]=previous_seen
raise
try:
from queue_log import QueueLog
QueueLog().append(key,state.get('display_name',''),'已审核',
'已检测到当前企微账号人工回复;本轮旧AI草稿已丢弃,后续消息重新执行风控')
self.log('[协议已审核] '+state.get('display_name','')+' · 已人工回复,本轮旧AI草稿已丢弃')
except Exception:pass
self._listening_progress()
last=(context or {}).get('last_message') or {}
if (last and not last.get('is_self') and last.get('dedup_key')!=state.get('dedup_key')
and last.get('account')==self.account and last.get('conv_id')==state.get('conv_id')):
self._upsert(last)
return True