Browse Source

上传android 的mcp连接和异常修复

newdev_shunjiawei
liwei1dao 1 year ago
parent
commit
aa957bdc95
  1. 32
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt
  2. 4
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt
  3. 6
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPSubClient.kt

32
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt

@ -333,7 +333,7 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
chatsFlow.collect { result -> chatsFlow.collect { result ->
if (isCanceled) return@collect if (isCanceled) return@collect
val choice = result.choices?.firstOrNull() val choice = result.choices.firstOrNull()
if (choice == null) { if (choice == null) {
Log.e("ChatApiService", "choice为null") Log.e("ChatApiService", "choice为null")
return@collect return@collect
@ -352,33 +352,35 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
// 收集工具调用信息 // 收集工具调用信息
delta.toolCalls?.forEach { toolCall -> delta.toolCalls?.forEach { toolCall ->
val id = toolCall.id ?: run {
Log.e("ChatApiService", "toolCall.id 为空,跳过本次处理")
return@forEach
}
Log.e("ChatApiService", "AI发起工具调用: ${toolCall.id} ${toolCall.index} ${toolCall.function?.name} ${toolCall.function?.arguments}")
val index = toolCall.index val index = toolCall.index
// 创建或获取现有的工具调用信息 // 创建或获取现有的工具调用信息
val toolCallInfo = toolCalls.getOrPut(index) { ToolCallInfo() } val toolCallInfo = toolCalls.getOrPut(index) { ToolCallInfo() }
// 安全处理工具调用ID // 安全处理工具调用ID
try { try {
toolCall.id?.let { id -> toolCall.id?.let { i ->
toolCallInfo.id = id.toString() toolCallInfo.id = i.toString()
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("ChatApiService", "处理工具调用ID异常: ${e.message}") Log.e("ChatApiService", "处理工具调用ID异常: ${e.message}")
} }
// 安全处理函数信息 // 安全处理函数信息
try { try {
toolCall.function?.let { function -> toolCall.function?.let { function ->
try { try {
function.name?.let { name -> function.name.let { name ->
toolCallInfo.name = name toolCallInfo.name = name
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("ChatApiService", "处理工具调用函数名称异常: ${e.message}") Log.e("ChatApiService", "处理工具调用函数名称异常! function:${toolCall.function} err:${e.message}")
} }
try { try {
function.arguments?.let { args -> function.arguments.let { args ->
toolCallInfo.arguments += args toolCallInfo.arguments += args
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -417,11 +419,9 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
Log.e("ChatApiService", "查找有效工具调用异常: ${e.message}") Log.e("ChatApiService", "查找有效工具调用异常: ${e.message}")
null null
} }
if (firstToolCall == null) { if (firstToolCall == null) {
return false return false
} }
// 创建函数调用字典 // 创建函数调用字典
val functionCall = try { val functionCall = try {
mapOf( mapOf(
@ -433,10 +433,8 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
Log.e("ChatApiService", "创建函数调用字典异常: ${e.message}") Log.e("ChatApiService", "创建函数调用字典异常: ${e.message}")
return false return false
} }
// 通知上层工具调用事件 // 通知上层工具调用事件
streamCallback?.onFunctionCall(convertMapToJsonObject(functionCall)) streamCallback?.onFunctionCall(convertMapToJsonObject(functionCall))
// 在后台队列处理工具调用 // 在后台队列处理工具调用
launch { launch {
try { try {
@ -444,14 +442,13 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
// 通过MCP客户端处理工具调用 // 通过MCP客户端处理工具调用
val functionName = firstToolCall.name val functionName = firstToolCall.name
val argumentsJson = firstToolCall.arguments val argumentsJson = firstToolCall.arguments
val result = if (_mcpClient?.hasToolWithName(functionName) == true) { val result = if (_mcpClient?.hasToolWithName(functionName) == true) {
// 解析参数 // 解析参数
val arguments = _mcpClient?.parseJsonArguments(argumentsJson) ?: emptyMap() val arguments = _mcpClient?.parseJsonArguments(argumentsJson) ?: emptyMap()
// 调用MCP工具 // 调用MCP工具
val toolResult = _mcpClient?.callTool(functionName, arguments) val toolResult = _mcpClient?.callTool(functionName, arguments)
Log.e("ChatApiService", "AI调用工具结果: $functionName}:$arguments} toolResult:${toolResult}")
// 处理结果 // 处理结果
if (toolResult != null) { if (toolResult != null) {
if (toolResult["isError"] == true) { if (toolResult["isError"] == true) {
@ -478,14 +475,12 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
// 工具不存在 // 工具不存在
mapOf("context" to "Tool not found: $functionName") mapOf("context" to "Tool not found: $functionName")
} }
if (!isCanceled) { if (!isCanceled) {
// 处理结果 // 处理结果
streamCallback?.onFunctionCallResult( streamCallback?.onFunctionCallResult(
convertMapToJsonObject(functionCall), convertMapToJsonObject(functionCall),
convertMapToJsonObject(result) convertMapToJsonObject(result)
) )
// 将结果发送回OpenAI继续对话 // 将结果发送回OpenAI继续对话
sendFunctionCallResultInternal( sendFunctionCallResultInternal(
messages = currentMessages, messages = currentMessages,
@ -855,12 +850,11 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor
nameOrNull = name, nameOrNull = name,
argumentsOrNull = arguments argumentsOrNull = arguments
) )
val toolCall = ToolCall.Function( val toolCall = ToolCall.Function(
id = ToolId(id), id = ToolId(id),
function = functionCall function = functionCall
) )
toolCallsList.add(toolCall) toolCallsList.add(toolCall)
} }
} }

4
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/CustomSseClientTransport.kt

@ -107,7 +107,9 @@ class CustomSseClientTransport(
"open" -> { "open" -> {
// SSE连接已打开 // SSE连接已打开
} }
"ping" -> {
// 心跳
}
"endpoint" -> { "endpoint" -> {
try { try {
val eventData = event.data ?: "" val eventData = event.data ?: ""

6
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPSubClient.kt

@ -77,11 +77,11 @@ class MCPSubClient(
} }
// 连接到服务器 // 连接到服务器
client?.connect(transport) client.connect(transport)
// 获取可用工具列表 // 获取可用工具列表
try { try {
val toolsResult = client?.listTools() val toolsResult = client.listTools()
if (toolsResult != null) { if (toolsResult != null) {
availableTools.clear() availableTools.clear()
val filtered = toolsResult.tools.filter { tool -> val filtered = toolsResult.tools.filter { tool ->
@ -101,7 +101,7 @@ class MCPSubClient(
retryCount = 0 retryCount = 0
currentReconnectDelay = initialReconnectDelay currentReconnectDelay = initialReconnectDelay
// 启动心跳检测 // 启动心跳检测
startHeartbeat() // startHeartbeat()
true true
} catch (e: Exception) { } catch (e: Exception) {

Loading…
Cancel
Save