import 'dart:async'; import 'package:get/get.dart'; import 'package:flutter/widgets.dart'; import '../../core/utils/logger.dart'; import '../providers/agent_provider.dart'; import '../models/agent.dart'; import '../../modules/chat/controllers/chat_controller.dart'; import '../../modules/chat/models/message_model.dart'; import 'azure_asr_service.dart'; import 'volcano_ai_service.dart'; import 'volcano_tts_api_service.dart'; import 'chat_history_service.dart'; /// 后台代理服务,用于在应用处于后台时处理AI交互 class BackgroundAgentService extends GetxService { // 服务实例 final AzureAsrService _asrService = Get.find(); final VolcanoAIService _aiService = Get.find(); final VolcanoTtsApiService _ttsService = Get.find(); final ChatHistoryService _historyService = Get.find(); // 状态控制 final RxBool isProcessing = false.obs; final RxBool isListening = false.obs; // 语音识别状态 final RxString recognizedText = ''.obs; // 流式响应控制 StreamSubscription? _recognitionSubscription; StreamSubscription? _aiResponseSubscription; // 定时器,用于检测无活动超时 Timer? _inactivityTimer; // 当前处理的Agent Agent? _currentAgent; // 消息历史 - 与ChatController共享 List> get messageHistory { // 首先尝试从ChatController获取消息历史 if (Get.isRegistered()) { final chatController = Get.find(); // 检查ChatController是否正在与personal_assistant交互 if (chatController.agent?.id == 'personal_assistant') { return chatController.messages.map((m) => { 'role': m.role, 'content': m.content, }).toList(); } } // 如果无法从ChatController获取,则使用本地存储的历史记录 if (_localMessageHistory.isEmpty) { _loadChatHistory(); } return _localMessageHistory; } // 本地消息历史备份 final List> _localMessageHistory = []; // 构造函数 BackgroundAgentService() { Logger.info('BackgroundAgentService 已创建'); } // TTS是否正在播放,直接从VolcanoTtsApiService获取 bool get isTtsSpeaking => _ttsService.isPlaying; @override void onClose() { // 取消所有订阅 _recognitionSubscription?.cancel(); _aiResponseSubscription?.cancel(); // 停止TTS if (_ttsService.isPlaying) { _ttsService.stop(); } // 停止语音识别 if (isListening.value) { _asrService.stopContinuousRecognition(); } // 取消定时器 _inactivityTimer?.cancel(); super.onClose(); } /// 开始代理交互 /// /// [agentId] 要交互的代理ID Future startAgentInteraction(String agentId) async { // 先说"我在听",然后再播放欢迎消息 const listeningMessage = "我在听"; _ttsService.speakSingle(listeningMessage); // 防止重复处理 if (isProcessing.value) { Logger.warning('已经在处理交互,忽略此次请求'); return; } isProcessing.value = true; try { // 获取Agent final agent = AgentProvider.getAgentById(agentId); if (agent == null) { Logger.error('无法获取Agent: $agentId'); isProcessing.value = false; return; } _currentAgent = agent; // 加载该Agent的聊天历史 _loadChatHistory(); // 启动语音识别 - 保持持续识别状态 await _startVoiceRecognition(); // 启动无活动定时器 _startInactivityTimer(); } catch (e) { Logger.error('启动代理交互失败', e); isProcessing.value = false; } } /// 启动语音识别 Future _startVoiceRecognition() async { if (isListening.value) { // 如果已经在监听,不需要重新启动 Logger.info('语音识别已经在运行,无需重新启动'); return; } try { // 启动语音识别 final success = await _asrService.startContinuousRecognition(); if (success) { isListening.value = true; recognizedText.value = ''; // 监听识别事件 _recognitionSubscription = _asrService.recognitionStream?.listen( (event) { // 重置无活动定时器 _resetInactivityTimer(); switch (event.type) { case RecognitionEventType.recognizing: // 实时更新识别文本 if (event.text.isNotEmpty) { recognizedText.value = event.text; // 如果正在播放TTS,检测到用户说话则中断当前播放和AI回复 if (_ttsService.isPlaying && event.text.trim().length > 3) { _interruptCurrentResponse("检测到用户说话,中断当前响应"); } } break; case RecognitionEventType.finalResult: // 最终结果 if (event.text.isNotEmpty) { recognizedText.value = event.text; // 处理识别到的文本 _processRecognizedText(event.text); // 重置识别文本但保持识别状态 recognizedText.value = ''; } break; case RecognitionEventType.sessionStopped: case RecognitionEventType.canceled: // 会话结束,表示识别在其它地方被启动,直接退出后台服务 isListening.value = false; Logger.info('语音识别会话被中止,退出后台代理服务'); stopInteraction(); break; default: break; } }, onError: (error) { Logger.error('语音识别错误', error); isListening.value = false; // 如果出错,尝试重新启动语音识别 _restartVoiceRecognition(); }, ); } else { Logger.error('启动语音识别失败'); isProcessing.value = false; } } catch (e) { Logger.error('启动语音识别失败', e); isListening.value = false; isProcessing.value = false; } } /// 处理识别到的文本 Future _processRecognizedText(String text) async { if (text.trim().isEmpty || _currentAgent == null) return; try { // 添加用户消息到历史记录 _addMessageToHistory('user', text); // 启动TTS会话,使用当前Agent的voice _ttsService.startSession(_currentAgent!.voice); // 获取AI响应 String fullResponse = ''; // 获取AI响应流 final responseStream = _aiService.sendMessageStream( messages: messageHistory, systemPrompt: _currentAgent!.systemPrompt, ); // 订阅响应流 _aiResponseSubscription = responseStream.listen( (chunk) { fullResponse += chunk; // 如果TTS启用,发送到TTS _ttsService.speak(chunk); // 重置无活动定时器 _resetInactivityTimer(); }, onDone: () { // 添加AI响应到历史记录 _addMessageToHistory('assistant', fullResponse); // 结束TTS会话 _ttsService.endSession(); // 注意:我们不再在这里重启语音识别,因为它应该已经在运行 }, onError: (error) { Logger.error('AI响应错误', error); // 播放错误消息 const errorMessage = '抱歉,我遇到了一些问题,无法回应您的请求。'; _ttsService.speak(errorMessage); // 添加错误消息到历史记录 _addMessageToHistory('assistant', errorMessage); // 结束TTS会话 _ttsService.endSession(); }, ); } catch (e) { Logger.error('处理识别文本失败', e); // 播放错误消息 const errorMessage = '抱歉,我遇到了一些问题,无法回应您的请求。'; _ttsService.speak(errorMessage); // 添加错误消息到历史记录 _addMessageToHistory('assistant', errorMessage); } } /// 重新启动语音识别(仅在识别会话意外终止时使用) Future _restartVoiceRecognition() async { // 停止当前的语音识别 if (isListening.value) { await _asrService.stopContinuousRecognition(); isListening.value = false; // 取消当前的订阅 _recognitionSubscription?.cancel(); _recognitionSubscription = null; } // 等待一段时间,确保资源被正确释放 await Future.delayed(Duration(milliseconds: 500)); // 重新启动语音识别 await _startVoiceRecognition(); } /// 添加消息到历史记录 void _addMessageToHistory(String role, String content) { // 添加到本地历史记录 _localMessageHistory.add({ 'role': role, 'content': content, }); // 保持本地历史记录不超过10条消息 if (_localMessageHistory.length > 10) { _localMessageHistory.removeAt(0); } // 如果ChatController可用,同步消息到ChatController if (Get.isRegistered()) { final chatController = Get.find(); if (chatController.agent?.id == 'personal_assistant') { // 向ChatController添加消息 final message = Message( role: role, content: content, timestamp: DateTime.now(), ); chatController.addMessage(message); } } else { // 如果ChatController不可用,保存到本地存储 _saveChatHistory(); } } // 加载聊天历史 void _loadChatHistory() { if (_currentAgent == null) return; try { // 加载聊天历史 final messages = _historyService.loadHistory(_currentAgent!.id); // 清空本地历史,然后添加加载的历史 _localMessageHistory.clear(); // 将Message转换为Map格式 if (messages.isNotEmpty) { for (final message in messages) { _localMessageHistory.add({ 'role': message.role, 'content': message.content, }); } Logger.info('已加载${messages.length}条聊天历史记录,代理: ${_currentAgent!.id}'); } } catch (e) { Logger.error('加载聊天历史记录失败', e); } } // 保存聊天历史 void _saveChatHistory() { if (_currentAgent == null) return; try { // 将本地历史转换为Message列表 final messages = _localMessageHistory.map((m) => Message( role: m['role']!, content: m['content']!, timestamp: DateTime.now(), )).toList(); // 保存到ChatHistoryService _historyService.saveHistory(_currentAgent!.id, messages); } catch (e) { Logger.error('保存聊天历史记录失败', e); } } /// 启动无活动定时器 void _startInactivityTimer() { _inactivityTimer?.cancel(); _inactivityTimer = Timer(Duration(seconds: 30), () { // 如果30秒内没有TTS输出或用户说话,停止语音识别 if (!_ttsService.isPlaying && isProcessing.value) { Logger.info('检测到30秒内无活动,停止语音识别'); stopInteraction(); } }); } /// 重置无活动定时器 void _resetInactivityTimer() { if (_inactivityTimer != null) { _inactivityTimer!.cancel(); _startInactivityTimer(); } } /// 中断当前响应 void _interruptCurrentResponse(String reason) { Logger.info(reason); // 停止TTS if (_ttsService.isPlaying) { _ttsService.stop(); } // 取消AI响应流订阅 _aiResponseSubscription?.cancel(); _aiResponseSubscription = null; } /// 响应新的媒体事件(双击媒体按钮) Future respondToNewMediaEvent() async { // 不管当前状态如何,总是中断当前响应 _interruptCurrentResponse("检测到新的媒体事件,中断当前响应"); // 回答"我在听" const listeningMessage = "我在听"; _ttsService.speakSingle(listeningMessage); // 不需要重启语音识别,因为它应该已经在运行 // 如果识别会话已经终止,确保重新启动 if (!isListening.value) { await _restartVoiceRecognition(); } // 重置无活动定时器 _resetInactivityTimer(); } /// 停止当前交互 Future stopInteraction() async { try { // 保存聊天历史 _saveChatHistory(); // 取消所有订阅 _recognitionSubscription?.cancel(); _aiResponseSubscription?.cancel(); // 停止TTS if (_ttsService.isPlaying) { _ttsService.stop(); } // 停止语音识别 // if (isListening.value) { // await _asrService.stopContinuousRecognition(); // isListening.value = false; // } // 取消定时器 _inactivityTimer?.cancel(); // 重置状态 isProcessing.value = false; _currentAgent = null; Logger.info('已停止后台代理交互'); } catch (e) { Logger.error('停止交互失败', e); } } }