davidliu
Committed by GitHub

Add types for agent and transcription attributes (#733)

---
"client-sdk-android": minor
---
Add types for agent and transcription attributes
... ...
... ... @@ -14,6 +14,7 @@ dagger = "2.46"
groupie = "2.9.0"
junit-lib = "4.13.2"
junit-jupiter = "5.5.0"
klaxon = "5.5"
kotlinx-serialization = "1.5.0"
leakcanaryAndroid = "2.8.1"
lint = "30.0.1"
... ... @@ -48,6 +49,7 @@ dagger-lib = { module = "com.google.dagger:dagger", version.ref = "dagger" }
dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
groupie = { module = "com.github.lisawray.groupie:groupie", version.ref = "groupie" }
groupie-viewbinding = { module = "com.github.lisawray.groupie:groupie-viewbinding", version.ref = "groupie" }
klaxon = { module = "com.beust:klaxon", version.ref = "klaxon" }
noise = { module = "com.github.paramsen:noise", version.ref = "noise" }
androidx-lifecycle-common-java8 = { module = "androidx.lifecycle:lifecycle-common-java8", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
... ...
... ... @@ -148,6 +148,8 @@ dependencies {
api libs.okhttp.lib
implementation libs.okhttp.coroutines
api libs.audioswitch
implementation libs.klaxon
implementation libs.androidx.annotation
implementation libs.androidx.core
implementation libs.protobuf.javalite
... ...
/*
* Copyright 2025 LiveKit, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.livekit.android.room.types
import com.beust.klaxon.Converter
import com.beust.klaxon.Json
import com.beust.klaxon.JsonValue
import com.beust.klaxon.Klaxon
private fun <T> Klaxon.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonValue) -> T, toJson: (T) -> String, isUnion: Boolean = false) =
this.converter(
object : Converter {
@Suppress("UNCHECKED_CAST")
override fun toJson(value: Any) = toJson(value as T)
override fun fromJson(jv: JsonValue) = fromJson(jv) as Any
override fun canConvert(cls: Class<*>) = cls == k.java || (isUnion && cls.superclass == k.java)
},
)
private val klaxon = Klaxon()
.convert(AgentInput::class, { AgentInput.fromValue(it.string!!) }, { "\"${it.value}\"" })
.convert(AgentOutput::class, { AgentOutput.fromValue(it.string!!) }, { "\"${it.value}\"" })
.convert(AgentState::class, { AgentState.fromValue(it.string!!) }, { "\"${it.value}\"" })
data class AgentAttributes(
@Json(name = "lk.agent.inputs")
val lkAgentInputs: List<AgentInput>? = null,
@Json(name = "lk.agent.outputs")
val lkAgentOutputs: List<AgentOutput>? = null,
@Json(name = "lk.agent.state")
val lkAgentState: AgentState? = null,
@Json(name = "lk.publish_on_behalf")
val lkPublishOnBehalf: String? = null,
) {
fun toJson() = klaxon.toJsonString(this)
companion object {
fun fromJson(json: String) = klaxon.parse<AgentAttributes>(json)
}
}
enum class AgentInput(val value: String) {
Audio("audio"),
Text("text"),
Video("video");
companion object {
fun fromValue(value: String): AgentInput = when (value) {
"audio" -> Audio
"text" -> Text
"video" -> Video
else -> throw IllegalArgumentException()
}
}
}
enum class AgentOutput(val value: String) {
Audio("audio"),
Transcription("transcription");
companion object {
fun fromValue(value: String): AgentOutput = when (value) {
"audio" -> Audio
"transcription" -> Transcription
else -> throw IllegalArgumentException()
}
}
}
enum class AgentState(val value: String) {
Idle("idle"),
Initializing("initializing"),
Listening("listening"),
Speaking("speaking"),
Thinking("thinking");
companion object {
fun fromValue(value: String): AgentState = when (value) {
"idle" -> Idle
"initializing" -> Initializing
"listening" -> Listening
"speaking" -> Speaking
"thinking" -> Thinking
else -> throw IllegalArgumentException()
}
}
}
/**
* Schema for transcription-related attributes
*/
data class TranscriptionAttributes(
/**
* The segment id of the transcription
*/
@Json(name = "lk.segment_id")
val lkSegmentID: String? = null,
/**
* The associated track id of the transcription
*/
@Json(name = "lk.transcribed_track_id")
val lkTranscribedTrackID: String? = null,
/**
* Whether the transcription is final
*/
@Json(name = "lk.transcription_final")
val lkTranscriptionFinal: Boolean? = null,
) {
fun toJson() = klaxon.toJsonString(this)
companion object {
fun fromJson(json: String) = klaxon.parse<TranscriptionAttributes>(json)
}
}
... ...