|
|
@ -482,11 +482,12 @@ class AgentServiceImpl: NSObject { |
|
|
guard let self = self else { return } |
|
|
guard let self = self else { return } |
|
|
DispatchQueue.main.async { [weak self] in |
|
|
DispatchQueue.main.async { [weak self] in |
|
|
guard let self = self else { return } |
|
|
guard let self = self else { return } |
|
|
self._log("INFO", "[Agent] idle check triggered auto stop, mode: \(self.currentRecognitionMode)") |
|
|
self._log("INFO", "[Agent] idle check triggered, mode: \(self.currentRecognitionMode), speaking: \(self.isSpeaking), aiStreaming: \(self.isAiStreaming)") |
|
|
//打电话模式下面 不能关闭识别器 |
|
|
if self.isRecognizing { |
|
|
if self.isRecognizing && !self.isSpeaking && !self.isAiStreaming{ |
|
|
if !self.isSpeaking && !self.isAiStreaming { |
|
|
|
|
|
// 条件满足:TTS未播放且AI未流式输出,执行自动停止 |
|
|
BleService.shared.closeCodec() |
|
|
BleService.shared.closeCodec() |
|
|
if (currentRecognitionMode != "phone_call"){ |
|
|
if (self.currentRecognitionMode != "phone_call"){ |
|
|
self.stopRecognition() |
|
|
self.stopRecognition() |
|
|
} |
|
|
} |
|
|
self.sendEvent(name: "auto_stop", data: [ |
|
|
self.sendEvent(name: "auto_stop", data: [ |
|
|
@ -494,6 +495,11 @@ class AgentServiceImpl: NSObject { |
|
|
"seconds": idleSeconds, |
|
|
"seconds": idleSeconds, |
|
|
"mode": self.currentRecognitionMode |
|
|
"mode": self.currentRecognitionMode |
|
|
]) |
|
|
]) |
|
|
|
|
|
} else { |
|
|
|
|
|
// 条件不满足:TTS或AI仍在工作中,重新调度计时器等待下一轮检查 |
|
|
|
|
|
self._log("INFO", "[Agent] idle check conditions not met (speaking=\(self.isSpeaking), ai=\(self.isAiStreaming)), rescheduling") |
|
|
|
|
|
self.startIdleCheck(idleSeconds: idleSeconds) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -715,6 +721,8 @@ class AgentServiceImpl: NSObject { |
|
|
isAiStreaming = false |
|
|
isAiStreaming = false |
|
|
_ = chatApiService?.cancelCurrentStream() |
|
|
_ = chatApiService?.cancelCurrentStream() |
|
|
interrupted = true |
|
|
interrupted = true |
|
|
|
|
|
// AI流结束是重要的状态变化,重启idle检测避免识别状态卡住 |
|
|
|
|
|
restartIdleCheck() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if interrupted { |
|
|
if interrupted { |
|
|
@ -784,10 +792,17 @@ class AgentServiceImpl: NSObject { |
|
|
var info = UserPortrait.shared.getAll() |
|
|
var info = UserPortrait.shared.getAll() |
|
|
info["language"] = self.language |
|
|
info["language"] = self.language |
|
|
|
|
|
|
|
|
// Add current time (formatted string) |
|
|
// Add current time (TTS友好的自然语言格式) |
|
|
|
|
|
let now = Date() |
|
|
|
|
|
let lang = Locale.current.languageCode ?? "en" |
|
|
let dateFormatter = DateFormatter() |
|
|
let dateFormatter = DateFormatter() |
|
|
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" |
|
|
switch lang { |
|
|
info["current_time"] = dateFormatter.string(from: Date()) |
|
|
case "zh": dateFormatter.dateFormat = "yyyy年M月d日 H时mm分ss秒"; dateFormatter.locale = Locale(identifier: "zh_CN") |
|
|
|
|
|
case "ja": dateFormatter.dateFormat = "yyyy年M月d日 H時mm分ss秒"; dateFormatter.locale = Locale(identifier: "ja_JP") |
|
|
|
|
|
case "ko": dateFormatter.dateFormat = "yyyy년 M월 d일 H시 mm분 ss초"; dateFormatter.locale = Locale(identifier: "ko_KR") |
|
|
|
|
|
default: dateFormatter.dateFormat = "MMMM d, yyyy, h:mm:ss a"; dateFormatter.locale = Locale.current |
|
|
|
|
|
} |
|
|
|
|
|
info["current_time"] = dateFormatter.string(from: now) |
|
|
// 添加调试日志 |
|
|
// 添加调试日志 |
|
|
// print("系统提示词模板: \(systemPrompt)") |
|
|
// print("系统提示词模板: \(systemPrompt)") |
|
|
// print("用户画像数据: \(info)") |
|
|
// print("用户画像数据: \(info)") |
|
|
@ -2039,7 +2054,7 @@ extension AgentServiceImpl: TtsEventListener { |
|
|
case .playbackCompleted: |
|
|
case .playbackCompleted: |
|
|
isSpeaking = false |
|
|
isSpeaking = false |
|
|
restartIdleCheck() |
|
|
restartIdleCheck() |
|
|
if(isInterrupt){//播报结束。打开解码器 |
|
|
if(currentRecognitionMode == "ble_wakeup" && isInterrupt){//播报结束。打开解码器 |
|
|
BleService.shared.openB1Encoder() |
|
|
BleService.shared.openB1Encoder() |
|
|
} |
|
|
} |
|
|
sendEvent(name: "playback_completed", data: ["status": "playback_completed"]) |
|
|
sendEvent(name: "playback_completed", data: ["status": "playback_completed"]) |
|
|
@ -2392,13 +2407,10 @@ extension AgentServiceImpl: AzureAsrHelper.ContinuousRecognizeCallback { |
|
|
func onRecognizing(sessionid:String ,_ recognizing: String, _ detectedLanguage: String) { |
|
|
func onRecognizing(sessionid:String ,_ recognizing: String, _ detectedLanguage: String) { |
|
|
pendingProcessWorkItem?.cancel() |
|
|
pendingProcessWorkItem?.cancel() |
|
|
if !recognizing.isEmpty && isKeepResult { |
|
|
if !recognizing.isEmpty && isKeepResult { |
|
|
let previousHasSpeech = hasSpeechDetected |
|
|
|
|
|
hasSpeechDetected = true |
|
|
hasSpeechDetected = true |
|
|
|
|
|
// 每次识别到语音都重启idle计时器,避免用户持续说话时误触超时 |
|
|
if !previousHasSpeech { |
|
|
|
|
|
print("onRecognizing restartIdleCheck") |
|
|
|
|
|
restartIdleCheck() |
|
|
restartIdleCheck() |
|
|
} |
|
|
|
|
|
if currsessionAsrId.isEmpty { |
|
|
if currsessionAsrId.isEmpty { |
|
|
currsessionAsrId = sessionid |
|
|
currsessionAsrId = sessionid |
|
|
} |
|
|
} |
|
|
@ -2412,9 +2424,13 @@ extension AgentServiceImpl: AzureAsrHelper.ContinuousRecognizeCallback { |
|
|
} |
|
|
} |
|
|
sendEvent(name: "recognizing", data: data) |
|
|
sendEvent(name: "recognizing", data: data) |
|
|
|
|
|
|
|
|
|
|
|
// 执行打断:同时停止TTS和AI流,避免isAiStreaming残留导致idle check失效 |
|
|
if isSpeaking || isAiStreaming { |
|
|
if isSpeaking || isAiStreaming { |
|
|
stopTts() |
|
|
stopTts() |
|
|
// interruptCurrentResponse() |
|
|
if isAiStreaming { |
|
|
|
|
|
isAiStreaming = false |
|
|
|
|
|
_ = chatApiService?.cancelCurrentStream() |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|