75 lines
4.1 KiB
Plaintext
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
|