@@ -844,6 +844,7 @@ def __init__(self, sync_message_queue, lanlan_name, lanlan_prompt):
844844 self ._takeover_input_dispatcher : Optional [
845845 Callable [..., Awaitable [bool ]]
846846 ] = None
847+ self ._latest_voice_transcript_request_id = ""
847848 # 由前端控制的Agent相关开关
848849 self .agent_flags = {
849850 'agent_enabled' : False ,
@@ -1975,6 +1976,30 @@ async def _dispatch_voice_transcript_bridge(
19751976 ) -> str :
19761977 """Let plugin-side voice filters decide whether to cancel or prime context."""
19771978 session_snapshot = self .session
1979+ request_id_snapshot = str (request_id or "" )
1980+
1981+ def _session_changed () -> bool :
1982+ if self .session is session_snapshot :
1983+ return False
1984+ logger .debug ("[%s] voice bridge result ignored after session change" , self .lanlan_name )
1985+ return True
1986+
1987+ def _request_stale () -> bool :
1988+ if not request_id_snapshot :
1989+ return False
1990+ latest_request_id = str (
1991+ getattr (self , "_latest_voice_transcript_request_id" , "" ) or ""
1992+ )
1993+ if latest_request_id == request_id_snapshot :
1994+ return False
1995+ logger .debug (
1996+ "[%s] voice bridge result ignored after newer request latest=%s current=%s" ,
1997+ self .lanlan_name ,
1998+ latest_request_id ,
1999+ request_id_snapshot ,
2000+ )
2001+ return True
2002+
19782003 metadata : dict [str , Any ] = {
19792004 "session_type" : type (session_snapshot ).__name__ if session_snapshot else "" ,
19802005 "voice_source" : True ,
@@ -1983,6 +2008,9 @@ async def _dispatch_voice_transcript_bridge(
19832008 if request_id :
19842009 metadata ["request_id" ] = request_id
19852010
2011+ if _session_changed () or _request_stale ():
2012+ return ""
2013+
19862014 try :
19872015 result = await publish_voice_transcript_request_reliably (
19882016 self .lanlan_name ,
@@ -1997,13 +2025,7 @@ async def _dispatch_voice_transcript_bridge(
19972025 if not isinstance (result , dict ) or not result :
19982026 return ""
19992027
2000- def _session_changed () -> bool :
2001- if self .session is session_snapshot :
2002- return False
2003- logger .debug ("[%s] voice bridge result ignored after session change" , self .lanlan_name )
2004- return True
2005-
2006- if _session_changed ():
2028+ if _session_changed () or _request_stale ():
20072029 return ""
20082030
20092031 action = str (result .get ("action" ) or "" ).strip ()
@@ -2013,10 +2035,10 @@ def _session_changed() -> bool:
20132035 logger .debug ("[%s] voice bridge cancel skipped: session has no cancel_response" , self .lanlan_name )
20142036 return ""
20152037 try :
2016- if _session_changed ():
2038+ if _session_changed () or _request_stale () :
20172039 return ""
20182040 await cancel_response ()
2019- if _session_changed ():
2041+ if _session_changed () or _request_stale () :
20202042 return ""
20212043 logger .debug ("[%s] voice bridge cancelled current response" , self .lanlan_name )
20222044 except asyncio .CancelledError :
@@ -2039,9 +2061,11 @@ def _session_changed() -> bool:
20392061 return ""
20402062 skipped = bool (result .get ("skipped" , False ))
20412063 try :
2042- if _session_changed ():
2064+ if _session_changed () or _request_stale () :
20432065 return ""
20442066 await prime_context (context_text , skipped = skipped )
2067+ if _session_changed () or _request_stale ():
2068+ return ""
20452069 logger .debug (
20462070 "[%s] voice bridge primed context len=%d skipped=%s" ,
20472071 self .lanlan_name ,
@@ -2207,6 +2231,8 @@ async def handle_input_transcript(self, transcript: str, *, is_voice_source: boo
22072231 if is_voice_source and transcript_text
22082232 else ""
22092233 )
2234+ if realtime_voice_request_id :
2235+ self ._latest_voice_transcript_request_id = realtime_voice_request_id
22102236
22112237 # 更新用户活动时间戳(用于主动搭话检测)
22122238 self .last_user_activity_time = time .time ()
0 commit comments