From fce5010450fbf945c635d16ba85512e807be0968 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 21 Oct 2025 20:48:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0bug=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent/controllers/agent_controller.dart | 26 +++++--- .../chat_api/CustomSseClientTransport.kt | 54 +++++++++++---- .../chat_api/SystemFunctionHandler.kt | 65 ++++++++++--------- .../chat_api/SystemFunctionHandler.swift | 39 +++++------ 4 files changed, 112 insertions(+), 72 deletions(-) diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index ad10e5d70..55169ac42 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -613,10 +613,20 @@ class AgentController extends GetxController with WidgetsBindingObserver { final sessionid = event.data['sessionid'] ?? ''; final text = event.data['text'] ?? ''; Logger.i(TAG, '[$sessionid]识别最终结果: $text'); + + if (currsessionid.value != "" && currsessionid.value != sessionid) { + final index = messages.lastIndexWhere( + (msg) => msg.sessionid == currsessionid.value && msg.isUser); + //出现了为识别结束的消息 + if (index >= 0) { + //异除去当前会话的识别中消息 + messages.removeAt(index); + } + } + currsessionid.value = sessionid; // 查找是否有正在识别中的消息 final index = messages.lastIndexWhere( (msg) => msg.sessionid == sessionid && msg.isUser); - if (text.isNotEmpty) { if (index >= 0) { // 将识别中的消息转换为最终消息 @@ -655,7 +665,7 @@ class AgentController extends GetxController with WidgetsBindingObserver { // 查找是否有正在识别中的消息 final index = messages.lastIndexWhere( (msg) => msg.sessionid == sessionid && msg.isUser); - + currsessionid.value = ''; if (currentText.value.isNotEmpty) { if (index >= 0) { // 将识别中的消息转换为最终消息 @@ -668,14 +678,14 @@ class AgentController extends GetxController with WidgetsBindingObserver { functionCalls: messages[index].functionCalls, isToolCallsExpanded: messages[index].isToolCallsExpanded, ); - // messages.refresh(); } else { // 如果没有找到识别中的消息,添加新消息 messages.add(Message( - sessionid: sessionid, - isUser: true, - text: currentText.value, - isRecognizing: false)); + sessionid: sessionid, + isUser: true, + text: currentText.value, + isRecognizing: false, + )); } isProcessing.value = true; @@ -685,8 +695,8 @@ class AgentController extends GetxController with WidgetsBindingObserver { } else if (index >= 0) { // 如果识别结果为空,移除临时的识别消息 messages.removeAt(index); - // messages.refresh(); } + messages.refresh(); break; case AgentServiceEventType.ttsStarted: isSpeaking.value = true; diff --git a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt index b515dedb2..da85cbaeb 100644 --- a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt +++ b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt @@ -177,14 +177,39 @@ class CustomSseClientTransport( } } - // 添加查询参数 + // 添加查询参数,避免重复参数 val endpointWithParams = if (queryParams.isNotEmpty()) { + // 解析现有的查询参数 + val existingParams = mutableMapOf() if (validatedEndpoint.contains("?")) { - val queryString = queryParams.entries.joinToString("&") { "${it.key}=${it.value}" } - "$validatedEndpoint&$queryString" + val urlParts = validatedEndpoint.split("?", limit = 2) + if (urlParts.size == 2) { + urlParts[1].split("&").forEach { param -> + val parts = param.split("=", limit = 2) + if (parts.size == 2) { + existingParams[parts[0]] = parts[1] + } + } + } + } + + // 合并参数,避免重复 + val allParams = mutableMapOf() + allParams.putAll(existingParams) + allParams.putAll(queryParams) + + // 构建最终URL + val baseUrl = if (validatedEndpoint.contains("?")) { + validatedEndpoint.split("?")[0] } else { - val queryString = queryParams.entries.joinToString("&") { "${it.key}=${it.value}" } - "$validatedEndpoint?$queryString" + validatedEndpoint + } + + if (allParams.isNotEmpty()) { + val queryString = allParams.entries.joinToString("&") { "${it.key}=${it.value}" } + "$baseUrl?$queryString" + } else { + baseUrl } } else { validatedEndpoint @@ -280,7 +305,7 @@ class CustomSseClientTransport( } sessionScope = CoroutineScope(transportScope.coroutineContext + SupervisorJob()) - + Log.e(TAG, "$serviceidString 解析成功: start 会话") // 创建SSE会话 - 直接使用原始URL session = urlString?.let { val sseConnectUrl = if (queryParams.isNotEmpty()) { @@ -303,14 +328,14 @@ class CustomSseClientTransport( reconnectionTime = reconnectionTime, block = requestBuilder, ) - + Log.e(TAG, "$serviceidString: start 会话 collectEvents") // 收集SSE事件 collectEvents() - + Log.e(TAG, "$serviceidString: start 会话 endpoint") // 等待endpoint就绪 endpoint.await() - Log.d(TAG, "CustomSseClientTransport启动完成") + Log.d(TAG, "$serviceidString: CustomSseClientTransport启动完成") } /** @@ -322,15 +347,18 @@ class CustomSseClientTransport( Log.e(TAG, "发送失败: 未连接") error("Not connected") } - + try { val messageEndpoint = endpoint.getCompleted() + Log.d(TAG, "$serviceidString 准备发送消息到: $messageEndpoint") val jsonString = json.encodeToString(message) - val response = client.post(messageEndpoint) { - headers.append(HttpHeaders.ContentType, ContentType.Application.Json.toString()) - setBody(jsonString) + val response = withTimeout(15000) { // 减少超时时间到15秒 + client.post(messageEndpoint) { + headers.append(HttpHeaders.ContentType, ContentType.Application.Json.toString()) + setBody(jsonString) + } } // 优化处理百度API的202状态码 diff --git a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt index 756a7269a..94173554d 100644 --- a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt +++ b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt @@ -60,6 +60,18 @@ class SystemFunctionHandler(private val context: Context? = null) { // handler = TranslationModeHandler(context) // ) + // 注册获取联系人列表函数 + client.registerLocalFunction( + name = "get_contacts_list", + description = "获取用户通信录联系人列表", + parameters = mapOf( + "type" to "object", + "properties" to emptyMap(), + "required" to emptyList() + ), + handler = GetContactsListHandler(context) + ) + // 注册发送短信函数 client.registerLocalFunction( name = "send_text_message", @@ -67,7 +79,7 @@ class SystemFunctionHandler(private val context: Context? = null) { parameters = mapOf( "type" to "object", "properties" to mapOf( - "contact" to mapOf( + "phone_number" to mapOf( "type" to "string", "description" to "电话号码" ), @@ -76,23 +88,11 @@ class SystemFunctionHandler(private val context: Context? = null) { "description" to "短信内容" ) ), - "required" to listOf("contact", "message") + "required" to listOf("phone_number", "message") ), handler = SendTextMessageHandler(context) ) - // 注册获取联系人列表函数 - client.registerLocalFunction( - name = "get_contacts_list", - description = "获取用户通信录联系人列表", - parameters = mapOf( - "type" to "object", - "properties" to emptyMap(), - "required" to emptyList() - ), - handler = GetContactsListHandler(context) - ) - // 注册拨打电话函数 client.registerLocalFunction( name = "make_phone_call", @@ -100,12 +100,12 @@ class SystemFunctionHandler(private val context: Context? = null) { parameters = mapOf( "type" to "object", "properties" to mapOf( - "contact" to mapOf( + "phone_number" to mapOf( "type" to "string", - "description" to "联系人姓名或电话号码" + "description" to "联系人电话号码" ) ), - "required" to listOf("contact") + "required" to listOf("phone_number") ), handler = MakePhoneCallHandler(context) ) @@ -495,10 +495,10 @@ private class TranslationModeHandler(private val context: Context?) : FunctionHa */ private class SendTextMessageHandler(private val context: Context?) : FunctionHandler { override suspend fun handle(arguments: Map): String { - val contact = arguments["contact"] as? String + val phone_number = arguments["phone_number"] as? String val message = arguments["message"] as? String - if (contact == null || message == null) { + if (phone_number == null || message == null) { return JSONObject().apply { put("error", JSONObject().apply { put("code", "invalid_arguments") @@ -529,12 +529,12 @@ private class SendTextMessageHandler(private val context: Context?) : FunctionHa }.toString() } - val phoneNumber = handler.getPhoneNumberForContact(contact) + val phoneNumber = handler.getPhoneNumberForContact(phone_number) if (phoneNumber.isEmpty()) { return JSONObject().apply { put("error", JSONObject().apply { put("code", "contact_not_found") - put("message", "未找到联系人信息: $contact") + put("message", "未找到联系人信息: $phone_number") }) }.toString() } @@ -556,7 +556,7 @@ private class SendTextMessageHandler(private val context: Context?) : FunctionHa } JSONObject().apply { - put("result", "已成功向${contact}发送短信") + put("result", "已成功向${phone_number}发送短信") put("phone", phoneNumber) put("message", message) }.toString() @@ -637,13 +637,13 @@ private class MakePhoneCallHandler(private val context: Context?) : FunctionHand } override suspend fun handle(arguments: Map): String { - val contact = arguments["contact"] as? String + val phone_number = arguments["phone_number"] as? String - if (contact == null) { + if (phone_number == null) { return JSONObject().apply { put("error", JSONObject().apply { put("code", "invalid_arguments") - put("message", "缺少必要参数:contact") + put("message", "缺少必要参数:phone_number") }) }.toString() } @@ -670,12 +670,12 @@ private class MakePhoneCallHandler(private val context: Context?) : FunctionHand }.toString() } - val phoneNumber = handler.getPhoneNumberForContact(contact) + val phoneNumber = handler.getPhoneNumberForContact(phone_number) if (phoneNumber.isEmpty()) { return JSONObject().apply { put("error", JSONObject().apply { put("code", "contact_not_found") - put("message", "未找到联系人信息: $contact") + put("message", "未找到联系人信息: $phone_number") }) }.toString() } @@ -688,7 +688,7 @@ private class MakePhoneCallHandler(private val context: Context?) : FunctionHand context.startActivity(intent) JSONObject().apply { - put("result", "正在拨打${contact}的电话") + put("result", "正在拨打${phone_number}的电话") put("phone", phoneNumber) }.toString() } catch (e: SecurityException) { @@ -1106,10 +1106,11 @@ private class GetCurrentLocationHandler(private val context: Context?) : Functio val result = JSONObject().apply { put("result", JSONObject().apply { - put("longitude", longitude) - put("latitude", latitude) - put("timestamp", System.currentTimeMillis()) - + put("经度", longitude) // 经度 + put("纬度", latitude) // 纬度 + put("经纬度", "$latitude,$longitude") + put("纬经度", "$longitude,$latitude") + put("时间戳", System.currentTimeMillis()) }) }.toString() diff --git a/local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift b/local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift index 1b892350a..cc7613322 100644 --- a/local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift +++ b/local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift @@ -71,12 +71,13 @@ public class SystemFunctionHandler: NSObject { // 注册翻译模式函数 // registerTranslationModeFunction(client: client) - // 注册发送短信函数 - registerSendTextMessageFunction(client: client) - // 注册查询通讯录函数 registerGetContactsFunction(client: client) + // 注册发送短信函数 + registerSendTextMessageFunction(client: client) + + // 注册拨打电话函数 registerMakePhoneCallFunction(client: client) @@ -163,16 +164,16 @@ public class SystemFunctionHandler: NSObject { let parameters: [String: Any] = [ "type": "object", "properties": [ - "contact": [ + "phone_number": [ "type": "string", - "description": "联系人姓名或电话号码" + "description": "联系人电话号码" ], "message": [ "type": "string", "description": "要发送的短信内容" ] ], - "required": ["contact", "message"] + "required": ["phone_number", "message"] ] let handler = SendTextMessageHandler() @@ -194,8 +195,8 @@ public class SystemFunctionHandler: NSObject { let handler = GetContactsHandler() _ = client.registerLocalFunction( - name: "get_contacts", - description: "获取联系人列表,读取通讯录信息,联系人名称和电话", + name: "get_contacts_list", + description: "获取用户通信录联系人列表", parameters: parameters, handler: handler ) @@ -206,12 +207,12 @@ public class SystemFunctionHandler: NSObject { let parameters: [String: Any] = [ "type": "object", "properties": [ - "contact": [ + "phone_number": [ "type": "string", - "description": "联系人姓名或电话号码" + "description": "联系人电话号码" ] ], - "required": ["contact"] + "required": ["phone_number"] ] let handler = MakePhoneCallHandler() @@ -628,22 +629,22 @@ private class SendTextMessageHandler: NSObject, FunctionHandler, MFMessageCompos private var continuation: CheckedContinuation? func handle(arguments: [String: Any]) async throws -> String { - guard let contact = arguments["contact"] as? String, + guard let phoneNumber = arguments["phone_number"] as? String, let message = arguments["message"] as? String else { throw ChatApiException("缺少必要参数") } - let result = await sendTextMessage(contact: contact, message: message) + let result = await sendTextMessage(phoneNumber: phoneNumber, message: message) return "{\"result\": \"\(result.message)\"}" } - private func sendTextMessage(contact: String, message: String) async -> Result { + private func sendTextMessage(phoneNumber: String, message: String) async -> Result { return await withCheckedContinuation { continuation in self.continuation = continuation DispatchQueue.main.async { if MFMessageComposeViewController.canSendText() { let messageVC = MFMessageComposeViewController() - messageVC.recipients = [contact] + messageVC.recipients = [phoneNumber] messageVC.body = message messageVC.messageComposeDelegate = self // 设置 delegate @@ -693,16 +694,16 @@ private class SendTextMessageHandler: NSObject, FunctionHandler, MFMessageCompos /// 拨打电话处理器 private class MakePhoneCallHandler: FunctionHandler { func handle(arguments: [String: Any]) async throws -> String { - guard let contact = arguments["contact"] as? String else { + guard let phoneNumber = arguments["phone_number"] as? String else { throw ChatApiException("缺少联系人参数") } - let result = await makePhoneCall(contact: contact) + let result = await makePhoneCall(phoneNumber: phoneNumber) return "{\"result\": \"\(result.message)\"}" } - private func makePhoneCall(contact: String) async -> Result { - guard let url = URL(string: "tel:\(contact)") else { + private func makePhoneCall(phoneNumber: String) async -> Result { + guard let url = URL(string: "tel:\(phoneNumber)") else { return Result(success: false, message: "无法创建电话URL") } return await withCheckedContinuation { continuation in