|
|
|
@ -612,7 +612,7 @@ object AgentService : CoroutineScope { |
|
|
|
val responseBuilder = StringBuilder() |
|
|
|
var aiMetadata:String = "" |
|
|
|
var userMetadata = JSONObject() |
|
|
|
var nobroadcast = false |
|
|
|
var broadcast = false //是否播发 |
|
|
|
// 如果有图片,添加图片信息到元数据 |
|
|
|
if (hasImage) { |
|
|
|
userMetadata.put("hasImage", true) |
|
|
|
@ -673,16 +673,18 @@ object AgentService : CoroutineScope { |
|
|
|
object : StreamCallback { |
|
|
|
override fun onToken(token: String) { |
|
|
|
responseBuilder.append(token) |
|
|
|
if (speakResponse && !nobroadcast) { |
|
|
|
if (speakResponse && broadcast) { |
|
|
|
ttsService?.speakStream(token) |
|
|
|
} |
|
|
|
// 发送流式回复token |
|
|
|
sendEvent("assistant_token", mapOf("token" to token)) |
|
|
|
if (broadcast){ |
|
|
|
// 发送流式回复token |
|
|
|
sendEvent("assistant_token", mapOf("token" to token)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override fun onComplete() { |
|
|
|
// 视情况决定是否朗读回复 |
|
|
|
if (speakResponse && !nobroadcast) { |
|
|
|
if (speakResponse && broadcast) { |
|
|
|
ttsService?.flushStream() |
|
|
|
} |
|
|
|
val response = responseBuilder.toString() |
|
|
|
@ -737,15 +739,14 @@ 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); |
|
|
|
val (metestr, _broadcast)= autoHandleFcunCallResult(name,functionCallResult); |
|
|
|
aiMetadata = metestr; |
|
|
|
nobroadcast = broadcast |
|
|
|
broadcast = _broadcast |
|
|
|
sendEvent("function_call_result", mapOf( |
|
|
|
"function_call" to functionCall.toString(), |
|
|
|
"result" to functionCallResult.toString(), |
|
|
|
"meta" to metestr, |
|
|
|
)) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
@ -859,7 +860,7 @@ object AgentService : CoroutineScope { |
|
|
|
) |
|
|
|
|
|
|
|
if (userMessageId != -1L) { |
|
|
|
if (assistantMessage.isNotEmpty() ) { |
|
|
|
if (assistantMessage.isNotEmpty() || aiMetadata.isNotEmpty()) { |
|
|
|
// 保存AI回复 |
|
|
|
val assistantMessageId = chatStorageHelper.saveMessage( |
|
|
|
sessionId = sessionId, |
|
|
|
@ -1124,54 +1125,58 @@ object AgentService : CoroutineScope { |
|
|
|
val textStr = content.optString("text") |
|
|
|
println("协议工具返回数据 检查是否存在卡片! textStr: ${textStr}") |
|
|
|
val metadata: MutableMap<String, Any> = mutableMapOf() |
|
|
|
var broadcast = false; |
|
|
|
println("协议工具返回数据 检查是否存在卡片!") |
|
|
|
var broadcast = true; |
|
|
|
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 |
|
|
|
} |
|
|
|
// Log.d(TAG, "mcp调用结果: $metaStr") |
|
|
|
if (meta.has("card_music")) { //音乐卡片 |
|
|
|
val cardMusic = meta.getJSONObject("card_music") |
|
|
|
val id = cardMusic.optString("id", "") |
|
|
|
val id = cardMusic.optInt("id", 0) |
|
|
|
val url = cardMusic.optString("url", "") |
|
|
|
val name = cardMusic.optString("name", "") |
|
|
|
val sgener = cardMusic.optString("sgener", "") |
|
|
|
val image = cardMusic.optString("image", "") |
|
|
|
val ts = cardMusic.optInt("ts", 0) |
|
|
|
processMusicPlay( |
|
|
|
mapOf( |
|
|
|
"id" to id, |
|
|
|
"url" to url, |
|
|
|
"title" to name, |
|
|
|
"artist" to sgener, |
|
|
|
"coverUrl" to image |
|
|
|
"coverUrl" to image, |
|
|
|
"ts" to ts |
|
|
|
) |
|
|
|
) |
|
|
|
broadcast = true; |
|
|
|
} else if (meta.has("card_musiclist")) { //音乐列表 |
|
|
|
val cardMusiclist = meta.getJSONObject("card_musiclist") |
|
|
|
val musics = cardMusiclist.optJSONArray("musics") |
|
|
|
if (musics != null) { |
|
|
|
val playlist = mutableListOf<Map<String, String>>() |
|
|
|
val playlist = mutableListOf<Map<String, Any>>() |
|
|
|
for (i in 0 until musics.length()) { |
|
|
|
val item = musics.optJSONObject(i) ?: continue |
|
|
|
val id = item.optString("id", "") |
|
|
|
val id = item.optInt("id", 0) |
|
|
|
val url = item.optString("url", "") |
|
|
|
val name = item.optString("name", "") |
|
|
|
val sgener = item.optString("sgener", "") |
|
|
|
val image = item.optString("image", "") |
|
|
|
val ts = item.optInt("ts", 0) |
|
|
|
playlist.add( |
|
|
|
mapOf( |
|
|
|
"id" to id, |
|
|
|
"url" to url, |
|
|
|
"title" to name, |
|
|
|
"artist" to sgener, |
|
|
|
"coverUrl" to image |
|
|
|
"coverUrl" to image, |
|
|
|
"ts" to ts |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
if (playlist.isNotEmpty()) { |
|
|
|
broadcast = true; |
|
|
|
processMusicPlayList(playlist) |
|
|
|
} else { |
|
|
|
Log.w(TAG, "card_musiclist 中没有有效的音乐条目") |
|
|
|
@ -1183,7 +1188,6 @@ object AgentService : CoroutineScope { |
|
|
|
val cardNavigation = meta.getJSONObject("card_navigation") |
|
|
|
val start = cardNavigation.optString("start", "") |
|
|
|
val end = cardNavigation.optString("end", "") |
|
|
|
broadcast = true; |
|
|
|
processNavigation(start, end); |
|
|
|
} |
|
|
|
return Pair(metaStr, broadcast); |
|
|
|
@ -1192,7 +1196,7 @@ object AgentService : CoroutineScope { |
|
|
|
// 捕获其他类型的异常(可选) |
|
|
|
println("为解析到卡片数据!") |
|
|
|
} |
|
|
|
return Pair("", false); |
|
|
|
return Pair("", true); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -1205,7 +1209,7 @@ object AgentService : CoroutineScope { |
|
|
|
* @param singer 歌手名称,默认为空 |
|
|
|
* @return 是否成功开始处理 |
|
|
|
*/ |
|
|
|
fun processMusicPlay(song: Map<String,String>){ |
|
|
|
fun processMusicPlay(song: Map<String,Any>){ |
|
|
|
// 在其他 Service、BroadcastReceiver 或 Application 中调用 |
|
|
|
Log.i(TAG, "播放音乐: ${song}") |
|
|
|
MusicServiceStarter.startServiceWithCommand(context, command = "play", song = song) |
|
|
|
@ -1220,7 +1224,7 @@ object AgentService : CoroutineScope { |
|
|
|
* @param singer 歌手,默认为false |
|
|
|
* @return 是否成功开始处理 |
|
|
|
*/ |
|
|
|
fun processMusicPlayList(songs:List<Map<String,String>>){ |
|
|
|
fun processMusicPlayList(songs:List<Map<String,Any>>){ |
|
|
|
// 如果 playlist 中有有效的歌曲,开始播放 |
|
|
|
if (songs.isNotEmpty()) { |
|
|
|
MusicServiceStarter.startServiceWithPlaylist(context, command = "playlist", songs = songs) |
|
|
|
|