Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
lxm 1 year ago
parent
commit
52940c44d2
  1. 10
      lib/modules/agent/controllers/agent_controller.dart
  2. 92
      lib/modules/pairing/controllers/pairing_controller.dart
  3. 23
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  4. 5
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPClient.kt
  5. 12
      local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt

10
lib/modules/agent/controllers/agent_controller.dart

@ -430,6 +430,16 @@ class AgentController extends GetxController {
Map<String, dynamic> metaResult = {};
metaResult = jsonDecode(metaStr) as Map<String, dynamic>;
if (metaResult.isNotEmpty) {
var notreply = false;
if (metaResult.containsKey("notreply")) {
// 如果有导航卡片,直接添加
notreply = metaResult["notreply"] as bool;
}
if (notreply) {
Logger.i(TAG, 'Flutter 结束调用 不回复');
//不回复直接返回
break;
}
// 判断是否为新的回复或响应ID是否改变
if (_isNewAssistantResponse || _currentResponseId != responseId) {
// 添加新消息

92
lib/modules/pairing/controllers/pairing_controller.dart

@ -11,27 +11,27 @@ import '../../../core/utils/permission_util.dart';
/// 配对状态枚举 - 简化版本
enum PairingState {
idle, // 空闲/初始状态
checking, // 检查中(蓝牙、权限等)
waitingClassic, // 等待经典蓝牙连接
verifying, // 验证设备
associating, // 正在进行BLE设备关联
waitingBle, // 等待BLE连接
completed, // 配对完成
error, // 错误状态
idle, // 空闲/初始状态
checking, // 检查中(蓝牙、权限等)
waitingClassic, // 等待经典蓝牙连接
verifying, // 验证设备
associating, // 正在进行BLE设备关联
waitingBle, // 等待BLE连接
completed, // 配对完成
error, // 错误状态
}
/// 错误类型枚举
enum ErrorType {
none,
bluetoothOff, // 蓝牙关闭
noPermission, // 无权限
noClassicDevice, // 无经典蓝牙设备
deviceNotMatch, // 设备不匹配
deviceBound, // 设备已被绑定
bluetoothOff, // 蓝牙关闭
noPermission, // 无权限
noClassicDevice, // 无经典蓝牙设备
deviceNotMatch, // 设备不匹配
deviceBound, // 设备已被绑定
associationFailed, // 关联失败
bleTimeout, // BLE连接超时
networkError, // 网络错误
bleTimeout, // BLE连接超时
networkError, // 网络错误
}
/// 配对控制器 - 基于简化状态机的实现
@ -122,32 +122,27 @@ class PairingController extends GetxController {
/// 监听蓝牙开关状态
void _setupBluetoothStateListener() {
_workers.add(
ever(_bluetoothManager.bluetoothStateRx, (String state) {
Logger.d(_tag, '蓝牙状态变化: $state');
_handleBluetoothStateChange(state);
})
);
_workers.add(ever(_bluetoothManager.bluetoothStateRx, (String state) {
Logger.d(_tag, '蓝牙状态变化: $state');
_handleBluetoothStateChange(state);
}));
}
/// 监听经典蓝牙连接状态
void _setupClassicConnectionListener() {
_workers.add(
ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) {
Logger.d(_tag, '经典蓝牙设备变化: ${device?.name}');
_handleClassicDeviceChange(device);
})
);
_workers
.add(ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) {
Logger.d(_tag, '经典蓝牙设备变化: ${device?.name}');
_handleClassicDeviceChange(device);
}));
}
/// 监听BLE连接状态
void _setupBleConnectionListener() {
_workers.add(
ever(_bleManager.connectionStateRx, (int state) {
Logger.d(_tag, 'BLE连接状态变化: $state');
_handleBleStateChange(state);
})
);
_workers.add(ever(_bleManager.connectionStateRx, (int state) {
Logger.d(_tag, 'BLE连接状态变化: $state');
_handleBleStateChange(state);
}));
}
// ==================== 状态处理 ====================
@ -209,7 +204,8 @@ class PairingController extends GetxController {
/// 处理BLE状态变化
void _handleBleStateChange(int state) {
if (_currentState.value == PairingState.waitingBle) {
if (state == 2) { // BLE已连接
if (state == 2) {
// BLE已连接
_bleTimeoutTimer?.cancel();
_transition(PairingState.completed);
}
@ -371,7 +367,6 @@ class PairingController extends GetxController {
_currentClassicDevice = classicDevice;
_transition(PairingState.verifying);
await _verifyDevice(classicDevice);
} catch (e) {
Logger.e(_tag, '状态检查失败: $e');
_setError(ErrorType.networkError, '检查失败,请重试');
@ -388,8 +383,8 @@ class PairingController extends GetxController {
final location = await Permission.locationWhenInUse.request();
return bluetoothScan.isGranted &&
bluetoothConnect.isGranted &&
location.isGranted;
bluetoothConnect.isGranted &&
location.isGranted;
}
return true;
}
@ -405,7 +400,8 @@ class PairingController extends GetxController {
// 检查设备名称是否包含 DeepSound 或 DeapSound
final deviceName = device.name ?? '';
if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) {
if (deviceName.contains('DeepSound') ||
deviceName.contains('DeapSound')) {
Logger.i(_tag, '设备验证通过');
_verifiedDeviceAddress = device.address;
@ -413,13 +409,15 @@ class PairingController extends GetxController {
final pairedMacAddress = await _bleManager.getPairedMacAddress();
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
if (pairedMacAddress != null && pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
if (pairedMacAddress != null &&
pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
// 已有关联,检查BLE连接状态
Logger.i(_tag, '设备已关联,检查BLE连接状态');
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, '验证时BLE状态: $currentBleState');
if (currentBleState == 2) { // BleConnectionState.connected
if (currentBleState == 2) {
// BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else {
@ -452,7 +450,7 @@ class PairingController extends GetxController {
// 调用BLE管理器的关联方法
final success = await _bleManager.startDeviceAssociation(
deviceNamePattern: 'DeapSound', // 或者使用 _currentClassicDevice?.name
deviceNamePattern: 'DeapSound', // 或者使用 _currentClassicDevice?.name
macAddress: _verifiedDeviceAddress!,
);
@ -484,7 +482,8 @@ class PairingController extends GetxController {
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, 'BLE当前连接状态: $currentBleState');
if (currentBleState == 2) { // BleConnectionState.connected
if (currentBleState == 2) {
// BleConnectionState.connected
Logger.i(_tag, 'BLE已经连接,直接完成配对');
_bleTimeoutTimer?.cancel();
_transition(PairingState.completed);
@ -493,7 +492,8 @@ class PairingController extends GetxController {
// 注册后台扫描以开始BLE配对
if (_verifiedDeviceAddress != null) {
final success = await _bleManager.registerBackgroundScan(macAddress: _verifiedDeviceAddress);
final success = await _bleManager.registerBackgroundScan(
macAddress: _verifiedDeviceAddress);
if (!success && _currentState.value == PairingState.waitingBle) {
_setError(ErrorType.bleTimeout, 'BLE配对启动失败');
}
@ -505,7 +505,8 @@ class PairingController extends GetxController {
}
/// 导航到主页
void _navigateToHome() {
void _navigateToHome() async {
await BleManager.to.startAgentService();
Future.delayed(const Duration(seconds: 1), () {
Get.offAllNamed(Routes.home);
});
@ -563,7 +564,8 @@ class PairingController extends GetxController {
}
/// 用户点击跳过按钮
void onSkipTap() {
void onSkipTap() async {
await BleManager.to.startAgentService();
Logger.i(_tag, '用户选择跳过配对');
Get.offAllNamed(Routes.home);
}

23
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -739,13 +739,13 @@ object AgentService : CoroutineScope {
override fun onFunctionCallResult(functionCall: JSONObject, functionCallResult: JSONObject) {
audioPlayer?.stopAudio()
val name = functionCall.get("name") as String;
val (metestr, _broadcast)= autoHandleFcunCallResult(name,functionCallResult);
aiMetadata = metestr;
broadcast = _broadcast
val resultmap = autoHandleFcunCallResult(name,functionCallResult);
aiMetadata = resultmap["meta"] as String;
broadcast = resultmap["broadcast"] as Boolean;
sendEvent("function_call_result", mapOf(
"function_call" to functionCall.toString(),
"result" to functionCallResult.toString(),
"meta" to metestr,
"meta" to aiMetadata,
))
}
}
@ -1116,7 +1116,7 @@ object AgentService : CoroutineScope {
/*
* 自动播放音乐
* */
fun autoHandleFcunCallResult(toolname:String,functionCallResult: JSONObject): Pair<String, Boolean>{
fun autoHandleFcunCallResult(toolname:String,functionCallResult: JSONObject): Map<String,Any>{
println("协议工具返回数据 检查是否存在卡片! functionCallResult: ${functionCallResult}")
try {
val contentStr = functionCallResult.optString("context")
@ -1126,13 +1126,18 @@ object AgentService : CoroutineScope {
println("协议工具返回数据 检查是否存在卡片! textStr: ${textStr}")
val metadata: MutableMap<String, Any> = mutableMapOf()
var broadcast = true;
var notreply = false;
if (textStr.isNotEmpty()) {
val meta = JSONObject(textStr)
metadata[toolname] = meta // 现在可以赋值
val metaStr = JSONObject(metadata as Map<*, *>).toString()
if (meta.has("broadcast")){
broadcast = meta["broadcast"] as Boolean
}
if (meta.has("notreply")){
notreply = meta["notreply"] as Boolean
}
metadata[toolname] = meta // 现在可以赋值
metadata["notreply"] = notreply // 现在可以赋值
val metaStr = JSONObject(metadata as Map<*, *>).toString()
// Log.d(TAG, "mcp调用结果: $metaStr")
if (meta.has("card_music")) { //音乐卡片
val cardMusic = meta.getJSONObject("card_music")
@ -1190,13 +1195,13 @@ object AgentService : CoroutineScope {
val end = cardNavigation.optString("end", "")
processNavigation(start, end);
}
return Pair(metaStr, broadcast);
return mapOf("meta" to metaStr, "broadcast" to broadcast,"notreply" to notreply);
}
} catch (e: Exception) {
// 捕获其他类型的异常(可选)
println("为解析到卡片数据!")
}
return Pair("", true);
return mapOf("meta" to "", "broadcast" to true,"notreply" to false);
}
/**

5
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/MCPClient.kt

@ -237,7 +237,10 @@ class MCPClient(private val context: Context? = null) : AutoCloseable {
localFunctions[name]?.let { handler ->
return try {
val result = handler.handle(arguments)
mapOf("context" to result)
mapOf("context" to mapOf(
"type" to "text",
"text" to result,
))
} catch (e: Exception) {
mapOf(
"content" to listOf(mapOf(

12
local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/SystemFunctionHandler.kt

@ -234,7 +234,7 @@ private class ExitNavigationHandler(private val context: Context?) : FunctionHan
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已结束当前导航服务\"}"
return "{\"broadcast\":false,\"result\": \"已结束当前导航服务\"}"
}
}
@ -435,7 +435,7 @@ private class MediaPlayHandler(private val context: Context?) : FunctionHandler
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已开始播放媒体\"}"
return "{\"notreply\":true,\"broadcast\":false,\"result\": \"已开始播放媒体\"}"
}
}
@ -450,7 +450,7 @@ private class MediaPauseHandler(private val context: Context?) : FunctionHandler
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已暂停媒体播放\"}"
return "{\"notreply\":true,\"broadcast\":false,\"result\": \"已暂停媒体播放\"}"
}
}
/**
@ -464,7 +464,7 @@ private class MediaCloseHandler(private val context: Context?) : FunctionHandler
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已关闭媒体播放\"}"
return "{\"notreply\":true,\"broadcast\":false,\"result\": \"已关闭媒体播放\"}"
}
}
/**
@ -478,7 +478,7 @@ private class MediaPreviousHandler(private val context: Context?) : FunctionHand
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已切换到上一首\"}"
return "{\"notreply\":true,\"broadcast\":false,\"result\": \"已切换到上一首\"}"
}
}
@ -493,7 +493,7 @@ private class MediaNextHandler(private val context: Context?) : FunctionHandler
setPackage(context?.packageName) // 设置包名使其成为显式 Intent
}
context?.sendBroadcast(intent)
return "{\"result\": \"已切换到下一首\"}"
return "{\"notreply\":true,\"broadcast\":false,\"result\": \"已切换到下一首\"}"
}
}

Loading…
Cancel
Save