From 53d3a32f485621408c1da23e3f9f02b0e643ffca Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 13 May 2025 18:42:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent/controllers/agent_controller.dart | 47 +++++++++---------- .../open_ai_service/OpenAIService.kt | 2 +- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index d1b41afd0..617cd5258 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -116,12 +116,12 @@ class AgentController extends GetxController { // 切换TTS状态 Future toggleTts() async { isTtsEnabled.toggle(); - + // 如果关闭TTS,停止当前语音 if (!isTtsEnabled.value && isSpeaking.value) { await AgentService.stopTts(); } - + // 保存偏好设置 try { final storage = GetStorage(); @@ -382,22 +382,15 @@ class AgentController extends GetxController { logger.i('Flutter 结束调用 mcp: $result, $functionCall'); if (result.isNotEmpty) { final parsedResult = jsonDecode(result); - final meta = parsedResult["meta"]; - Map metaResult = {}; - - if (meta != null && meta is String && meta.isNotEmpty) { - try { - metaResult = jsonDecode(meta); - } catch (e) { - print('解析meta数据失败: $e'); - } - } - if(metaResult.isNotEmpty){ - + final meta = parsedResult["meta"] as String; + final metaResult = jsonDecode(meta); + if (meta.isNotEmpty) { + logger.i('Flutter 结束调用 mcp metaResult: $metaResult'); // 判断是否为新的回复或响应ID是否改变 if (_isNewAssistantResponse || _currentResponseId != responseId) { // 添加新消息 - messages.add(Message(isUser: false, text: "", meta: metaResult)); + messages + .add(Message(isUser: false, text: "", meta: metaResult)); _isNewAssistantResponse = false; _currentResponseId = responseId; } else { @@ -407,11 +400,14 @@ class AgentController extends GetxController { messages[lastIndex] = Message( isUser: false, text: messages[lastIndex].text, - meta: meta, + meta: metaResult, timestamp: messages[lastIndex].timestamp, ); } } + messages.refresh(); + // 滚动到底部 + _scrollToBottom(); } } break; @@ -467,7 +463,8 @@ class AgentController extends GetxController { // 标记为新的AI回复 _isNewAssistantResponse = true; // 根据TTS状态决定是否朗读 - await AgentService.processTextInput(text, speakResponse: isTtsEnabled.value); + await AgentService.processTextInput(text, + speakResponse: isTtsEnabled.value); } catch (e) { logger.e('发送文本消息失败: $e'); isProcessing.value = false; @@ -549,18 +546,18 @@ class AgentController extends GetxController { Future _checkMicrophonePermission() async { try { PermissionStatus status = await Permission.microphone.status; - + // 如果已授权,直接返回 true if (status.isGranted) { return true; } - + // 如果被永久拒绝,提示用户前往设置页面 if (status.isPermanentlyDenied) { _showPermissionDialog(true); return false; } - + // 如果之前拒绝但不是永久拒绝,或首次请求,尝试请求权限 if (status.isDenied) { status = await Permission.microphone.request(); @@ -571,22 +568,22 @@ class AgentController extends GetxController { return false; } } - + return false; } catch (e) { logger.e('检查麦克风权限失败: $e'); return false; } } - + // 显示权限提示对话框 void _showPermissionDialog(bool isPermanent) { Get.dialog( AlertDialog( title: const Text('需要麦克风权限'), - content: Text(isPermanent - ? '语音功能需要麦克风权限。请前往设置页面手动开启权限。' - : '语音功能需要麦克风权限。请允许使用麦克风权限以继续使用语音功能。'), + content: Text(isPermanent + ? '语音功能需要麦克风权限。请前往设置页面手动开启权限。' + : '语音功能需要麦克风权限。请允许使用麦克风权限以继续使用语音功能。'), actions: [ TextButton( onPressed: () => Get.back(), diff --git a/local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt b/local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt index 8b70b05e2..6dd0bd660 100644 --- a/local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt +++ b/local_plugins/open_ai_service/android/src/main/kotlin/com/yunqiinnovation/open_ai_service/OpenAIService.kt @@ -698,7 +698,7 @@ class OpenAIService(private val context: Context? = null) : CoroutineScope { put("arguments", firstToolCall.arguments) put("id", firstToolCall.id) } - Log.d(TAG, "工具调用: id=${firstToolCall.id}, name=${firstToolCall.name}") + Log.d(TAG, "工具调用: id=${firstToolCall.id}, name=${firstToolCall.name} arguments=${firstToolCall.arguments}") // 通知上层工具调用事件 callback.onFunctionCall(functionCall)