Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ data class ConversationConfig(
val onAgentToolResponse: ((toolName: String, toolCallId: String, toolType: String, isError: Boolean) -> Unit)? = null,
val onConversationInitiationMetadata: ((conversationId: String, agentOutputFormat: String, userInputFormat: String) -> Unit)? = null,
val onInterruption: ((eventId: Int) -> Unit)? = null,
val onDisconnect: ((details: DisconnectionDetails) -> Unit)? = null
val onDisconnect: ((details: DisconnectionDetails) -> Unit)? = null,
val onError: ((code: Int, message: String?) -> Unit)? = null

) {
init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class ConversationEventHandler(
private val onAgentToolResponse: ((String, String, String, Boolean) -> Unit)? = null,
private val onConversationInitiationMetadata: ((String, String, String) -> Unit)? = null,
private val onInterruption: ((Int) -> Unit)? = null,
private val onEndCall: (suspend () -> Unit)? = null
private val onEndCall: (suspend () -> Unit)? = null,
private val onError: ((Int, String?) -> Unit)? = null
) {

private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
Expand Down Expand Up @@ -67,6 +68,7 @@ class ConversationEventHandler(
is ConversationEvent.Audio -> handleAudio(event)
is ConversationEvent.ConversationInitiationMetadata -> handleConversationInitiationMetadata(event)
is ConversationEvent.Interruption -> handleInterruption(event)
is ConversationEvent.ServerError -> handleServerError(event)

}
} catch (e: Exception) {
Expand Down Expand Up @@ -214,6 +216,18 @@ class ConversationEventHandler(
}
}

/**
* Handle server error events
*/
private fun handleServerError(event: ConversationEvent.ServerError) {
Log.e("ConvEventHandler", "Server error (${event.code}): ${event.message ?: "unknown"}")
try {
onError?.invoke(event.code, event.message)
} catch (e: Exception) {
Log.e("ConvEventHandler", "Error in onError callback: ${e.message}", e)
}
}

/**
* Handle client tool call events
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ internal class ConversationSessionImpl(
},
onEndCall = {
endSession()
},
onError = { code, message ->
try { config.onError?.invoke(code, message) } catch (_: Throwable) {}
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,15 @@ sealed class ConversationEvent {
val eventId: Int
) : ConversationEvent()

/**
* Event representing a server error
*
* @param code The error code from the server
* @param message Optional error message describing the error
*/
data class ServerError(
val code: Int,
val message: String?
) : ConversationEvent()

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ object ConversationEventParser {
"interruption" -> parseInterruption(jsonObject)
"audio_alignment" -> parseAudioAlignment(jsonObject)
"ping" -> parsePing(jsonObject)
"error" -> parseError(jsonObject)
else -> {
handleParsingError(json, IllegalArgumentException("Unknown event type: $eventType"))
null
Expand Down Expand Up @@ -313,6 +314,22 @@ object ConversationEventParser {
)
}

/**
* Parse error event from server
* Supports both nested error_event and flat structure:
* {"type":"error","error_event":{"code":1011,"message":"..."}}
* {"type":"error","code":1011,"message":"..."}
*/
private fun parseError(jsonObject: JsonObject): ConversationEvent.ServerError {
val errorEvent = jsonObject.getAsJsonObject("error_event")
val code = errorEvent?.get("code")?.asInt
?: jsonObject.get("code")?.asInt
?: 1011
val message = errorEvent?.get("message")?.let { if (it.isJsonNull) null else it.asString }
?: jsonObject.get("message")?.let { if (it.isJsonNull) null else it.asString }
return ConversationEvent.ServerError(code = code, message = message)
}

/**
* Handle parsing errors
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ class ConversationViewModel(application: Application) : AndroidViewModel(applica
},
onInterruption = { eventId ->
Log.d("ConversationViewModel", "onInterruption: eventId=$eventId")
},
onError = { code, message ->
Log.e("ConversationViewModel", "onError: Server error ($code): ${message ?: "unknown"}")
_errorMessage.postValue("Server error ($code): ${message ?: "unknown"}")
}
)

Expand Down