























@@ -226,14 +226,15 @@ class TalkModeManager(
226226// If this is a response we initiated, handle normally below.
227227// Otherwise, if ttsOnAllResponses, finish streaming TTS on terminal events.
228228val pending = pendingRunId
229-if (pending == null || runId != pending) {
229+val knownRun = pending == runId || hasRunCompletion(runId)
230+if (!knownRun) {
230231if (ttsOnAllResponses && state == "final") {
231232val text = extractTextFromChatEventMessage(obj["message"])
232233if (!text.isNullOrBlank()) {
233234 playTtsForText(text)
234235 }
235236 }
236-if (pending == null || runId != pending) return
237+return
237238 }
238239Log.d(tag, "chat event arrived runId=$runId state=$state pendingRunId=$pendingRunId")
239240val terminal =
@@ -539,6 +540,7 @@ class TalkModeManager(
539540540541private suspend fun sendChat(message: String, session: GatewaySession): String {
541542val runId = UUID.randomUUID().toString()
543+ armPendingRun(runId)
542544val params =
543545 buildJsonObject {
544546 put("sessionKey", JsonPrimitive(mainSessionKey.ifBlank { "main" }))
@@ -547,19 +549,29 @@ class TalkModeManager(
547549 put("timeoutMs", JsonPrimitive(30_000))
548550 put("idempotencyKey", JsonPrimitive(runId))
549551 }
550-val res = session.request("chat.send", params.toString())
551-val parsed = parseRunId(res) ?: runId
552-if (parsed != runId) {
553- pendingRunId = parsed
552+try {
553+val res = session.request("chat.send", params.toString())
554+val parsed = parseRunId(res) ?: runId
555+if (parsed != runId) {
556+ pendingRunId = parsed
557+ }
558+return parsed
559+ } catch (err: Throwable) {
560+ clearPendingRun(runId)
561+throw err
554562 }
555-return parsed
556563 }
557564558565private suspend fun waitForChatFinal(runId: String): Boolean {
559- pendingFinal?.cancel()
560-val deferred = CompletableDeferred<Boolean>()
561- pendingRunId = runId
562- pendingFinal = deferred
566+ consumeRunCompletion(runId)?.let { return it }
567+val deferred =
568+if (pendingRunId == runId) {
569+ pendingFinal ?: armPendingRun(runId)
570+ } else {
571+ armPendingRun(runId)
572+ }
573+574+ consumeRunCompletion(runId)?.let { return it }
563575564576val result =
565577 withContext(Dispatchers.IO) {
@@ -570,11 +582,25 @@ class TalkModeManager(
570582 }
571583 }
572584573-if (!result) {
585+if (!result && pendingRunId == runId) {
586+ clearPendingRun(runId)
587+ }
588+return result
589+ }
590+591+private fun armPendingRun(runId: String): CompletableDeferred<Boolean> {
592+ pendingFinal?.cancel()
593+val deferred = CompletableDeferred<Boolean>()
594+ pendingRunId = runId
595+ pendingFinal = deferred
596+return deferred
597+ }
598+599+private fun clearPendingRun(runId: String) {
600+if (pendingRunId == runId) {
574601 pendingFinal = null
575602 pendingRunId = null
576603 }
577-return result
578604 }
579605580606private fun cacheRunCompletion(runId: String, isFinal: Boolean) {
@@ -593,6 +619,12 @@ class TalkModeManager(
593619 }
594620 }
595621622+private fun hasRunCompletion(runId: String): Boolean {
623+ synchronized(completedRunsLock) {
624+return completedRunStates.containsKey(runId)
625+ }
626+ }
627+596628private fun consumeRunText(runId: String): String? {
597629 synchronized(completedRunsLock) {
598630return completedRunTexts.remove(runId)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。