Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTVI 0.2.0 #6

Merged
merged 2 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 5 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[versions]
agp = "8.5.1"
daily-android-client = "0.23.0"
kotlin = "2.0.0"
agp = "8.5.2"
daily-android-client = "0.24.0"
kotlin = "2.0.20"
coreKtx = "1.13.1"
kotlinxCoroutinesTest = "1.8.1"
kotlinxSerializationJson = "1.7.1"
kotlinxSerializationPlugin = "2.0.0"
kotlinxSerializationPlugin = "2.0.20"
dokka = "1.9.20"
androidxTest = "1.6.1"
rtviClient = "0.1.4"
rtviClient = "0.2.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
Expand Down
2 changes: 1 addition & 1 deletion rtvi-client-android-daily/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ publishing {
register<MavenPublication>("release") {
groupId = "ai.rtvi"
artifactId = "client-daily"
version = "0.1.5"
version = "0.2.0"

pom {
name.set("RTVI Client Daily Transport")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package ai.rtvi.client.daily

import ai.rtvi.client.VoiceClientOptions
import ai.rtvi.client.VoiceEventCallbacks
import ai.rtvi.client.RTVIClientOptions
import ai.rtvi.client.RTVIClientParams
import ai.rtvi.client.RTVIEventCallbacks
import ai.rtvi.client.helper.LLMContext
import ai.rtvi.client.helper.LLMContextMessage
import ai.rtvi.client.helper.LLMHelper
import ai.rtvi.client.result.RTVIError
import ai.rtvi.client.result.Result
import ai.rtvi.client.result.VoiceError
import ai.rtvi.client.types.ActionDescription
import ai.rtvi.client.types.Config
import ai.rtvi.client.types.Option
Expand All @@ -28,25 +29,28 @@ import org.junit.Test
class MainTests {

companion object {
private val options = VoiceClientOptions(
private val options = RTVIClientOptions(
services = listOf(
ServiceRegistration("tts", "cartesia"),
ServiceRegistration("llm", "together"),
),
config = listOf(
ServiceConfig(
"tts", listOf(
Option("voice", "79a125e8-cd45-4c13-8a67-188112f4dd22")
)
),
ServiceConfig(
"llm", listOf(
Option("model", "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo"),
Option(
"initial_messages", Value.Array(
Value.Object(
"role" to Value.Str("system"),
"content" to Value.Str("You are a helpful voice assistant.")
params = RTVIClientParams(
baseUrl = testUrl,
config = listOf(
ServiceConfig(
"tts", listOf(
Option("voice", "79a125e8-cd45-4c13-8a67-188112f4dd22")
)
),
ServiceConfig(
"llm", listOf(
Option("model", "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo"),
Option(
"initial_messages", Value.Array(
Value.Object(
"role" to Value.Str("system"),
"content" to Value.Str("You are a helpful voice assistant.")
)
)
)
)
Expand All @@ -67,8 +71,7 @@ class MainTests {

val client = DailyVoiceClient(
context = context,
baseUrl = testUrl,
callbacks = object : VoiceEventCallbacks() {
callbacks = object : RTVIEventCallbacks() {
override fun onBackendError(message: String) {
throw Exception("onBackendError: $message")
}
Expand All @@ -78,7 +81,7 @@ class MainTests {

val llmHelper = client.registerHelper("llm", LLMHelper(object : LLMHelper.Callbacks() {}))

client.start().await()
client.connect().await()

Assert.assertEquals(TransportState.Ready, client.state)

Expand Down Expand Up @@ -151,7 +154,7 @@ class MainTests {
@Test
fun testActionInvalid() = runTestWithConnectedClient {
Assert.assertEquals(
Result.Err(VoiceError.ErrorResponse(message = "Action abc123:say not registered")),
Result.Err(RTVIError.ErrorResponse(message = "Action abc123:say not registered")),
client.action(
"abc123",
"say",
Expand All @@ -163,7 +166,7 @@ class MainTests {
@Test
fun testGetConfig() = runTestWithConnectedClient {
Assert.assertEquals(
Config(config = options.config),
Config(config = options.params.config),
client.getConfig().await()
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ai.rtvi.client.daily

import ai.rtvi.client.result.Future
import ai.rtvi.client.result.VoiceError
import ai.rtvi.client.result.RTVIError
import ai.rtvi.client.result.resolvedPromiseErr
import ai.rtvi.client.result.resolvedPromiseOk
import ai.rtvi.client.result.withPromise
Expand Down Expand Up @@ -55,7 +55,7 @@ class DailyTransport(
private val thread = transportContext.thread

private val appContext = androidContext.applicationContext
private var state = TransportState.Idle
private var state = TransportState.Disconnected

private var devicesInitialized = false

Expand Down Expand Up @@ -197,7 +197,7 @@ class DailyTransport(
}
}

override fun initDevices(): Future<Unit, VoiceError> = withPromise(thread) { promise ->
override fun initDevices(): Future<Unit, RTVIError> = withPromise(thread) { promise ->

thread.runOnThread {

Expand All @@ -223,7 +223,7 @@ class DailyTransport(
}
}

if (state == TransportState.Idle) {
if (state == TransportState.Disconnected) {
setState(TransportState.Initialized)
}

Expand All @@ -232,12 +232,12 @@ class DailyTransport(

} catch (e: Exception) {
Log.e(TAG, "Exception in initDevices", e)
promise.resolveErr(VoiceError.ExceptionThrown(e))
promise.resolveErr(RTVIError.ExceptionThrown(e))
}
}
}

override fun connect(authBundle: AuthBundle): Future<Unit, VoiceError> =
override fun connect(authBundle: AuthBundle): Future<Unit, RTVIError> =
thread.runOnThreadReturningFuture {

Log.i(TAG, "connect(${authBundle.data})")
Expand All @@ -247,7 +247,7 @@ class DailyTransport(
} catch (e: Exception) {
return@runOnThreadReturningFuture resolvedPromiseErr(
thread,
VoiceError.ExceptionThrown(e)
RTVIError.ExceptionThrown(e)
)
}

Expand All @@ -268,7 +268,7 @@ class DailyTransport(
) {
if (it.isError) {
setState(TransportState.Error)
promise.resolveErr(it.error.toVoiceError())
promise.resolveErr(it.error.toRTVIError())
return@join
}

Expand All @@ -288,7 +288,7 @@ class DailyTransport(
}
}

override fun disconnect(): Future<Unit, VoiceError> = thread.runOnThreadReturningFuture {
override fun disconnect(): Future<Unit, RTVIError> = thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
callClient.leave(promise::resolveWithDailyResult)
Expand All @@ -298,7 +298,7 @@ class DailyTransport(

override fun sendMessage(
message: MsgClientToServer,
): Future<Unit, VoiceError> = thread.runOnThreadReturningFuture {
): Future<Unit, RTVIError> = thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
callClient.sendAppMessage(
Expand All @@ -321,10 +321,10 @@ class DailyTransport(
transportContext.callbacks.onTransportStateChanged(state)
}

override fun getAllCams(): Future<List<MediaDeviceInfo>, VoiceError> =
override fun getAllCams(): Future<List<MediaDeviceInfo>, RTVIError> =
resolvedPromiseOk(thread, getAllCamsInternal())

override fun getAllMics(): Future<List<MediaDeviceInfo>, VoiceError> =
override fun getAllMics(): Future<List<MediaDeviceInfo>, RTVIError> =
resolvedPromiseOk(thread, getAllMicsInternal())

private fun getAllCamsInternal() =
Expand All @@ -333,7 +333,7 @@ class DailyTransport(
private fun getAllMicsInternal() =
call?.availableDevices()?.audio?.map { it.toRtvi() } ?: emptyList()

override fun updateMic(micId: MediaDeviceId): Future<Unit, VoiceError> =
override fun updateMic(micId: MediaDeviceId): Future<Unit, RTVIError> =
thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
Expand All @@ -342,7 +342,7 @@ class DailyTransport(
}
}

override fun updateCam(camId: MediaDeviceId): Future<Unit, VoiceError> =
override fun updateCam(camId: MediaDeviceId): Future<Unit, RTVIError> =
thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
Expand All @@ -369,7 +369,7 @@ class DailyTransport(

override fun isMicEnabled() = call?.inputs()?.microphone?.isEnabled ?: false

override fun enableMic(enable: Boolean): Future<Unit, VoiceError> =
override fun enableMic(enable: Boolean): Future<Unit, RTVIError> =
thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
Expand All @@ -386,7 +386,7 @@ class DailyTransport(

override fun expiry() = thread.assertCurrent { expiry }

override fun enableCam(enable: Boolean): Future<Unit, VoiceError> =
override fun enableCam(enable: Boolean): Future<Unit, RTVIError> =
thread.runOnThreadReturningFuture {
withCall { callClient ->
withPromise(thread) { promise ->
Expand Down Expand Up @@ -431,14 +431,14 @@ class DailyTransport(
call = null
}

private fun <V> withCall(action: (CallClient) -> Future<V, VoiceError>): Future<V, VoiceError> {
private fun <V> withCall(action: (CallClient) -> Future<V, RTVIError>): Future<V, RTVIError> {

thread.assertCurrent()

val currentClient = call

return if (currentClient == null) {
resolvedPromiseErr(thread, VoiceError.TransportNotInitialized)
resolvedPromiseErr(thread, RTVIError.TransportNotInitialized)
} else {
return action(currentClient)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package ai.rtvi.client.daily

import ai.rtvi.client.VoiceClient
import ai.rtvi.client.VoiceClientOptions
import ai.rtvi.client.VoiceEventCallbacks
import ai.rtvi.client.RTVIClient
import ai.rtvi.client.RTVIClientOptions
import ai.rtvi.client.RTVIEventCallbacks
import android.content.Context

/**
* An RTVI client. Connects to a Daily Bots backend and handles bidirectional audio and video
* streaming.
*
* @param context The Android context object
* @param baseUrl URL of the Daily Bots backend.
* @param callbacks Callbacks invoked when changes occur in the voice session.
* @param options Additional options for configuring the client and backend.
*/
class DailyVoiceClient(
context: Context,
baseUrl: String,
callbacks: VoiceEventCallbacks,
options: VoiceClientOptions = VoiceClientOptions()
) : VoiceClient(
baseUrl = baseUrl,
callbacks: RTVIEventCallbacks,
options: RTVIClientOptions
) : RTVIClient(
transport = DailyTransport.Factory(context),
callbacks = callbacks,
options = options
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ai.rtvi.client.daily

import ai.rtvi.client.result.Promise
import ai.rtvi.client.result.VoiceError
import ai.rtvi.client.result.RTVIError
import ai.rtvi.client.types.MediaDeviceId
import ai.rtvi.client.types.MediaDeviceInfo
import ai.rtvi.client.types.MediaTrackId
Expand All @@ -17,12 +17,12 @@ import kotlinx.serialization.json.contentOrNull

internal val JSON_INSTANCE = Json { ignoreUnknownKeys = true }

internal fun RequestError?.toVoiceError() =
VoiceError.OtherError("Error from Daily client: ${this?.msg}")
internal fun RequestError?.toRTVIError() =
RTVIError.OtherError("Error from Daily client: ${this?.msg}")

internal fun Promise<Unit, VoiceError>.resolveWithDailyResult(result: RequestResult) {
internal fun Promise<Unit, RTVIError>.resolveWithDailyResult(result: RequestResult) {
if (result.isError) {
resolveErr(result.error.toVoiceError())
resolveErr(result.error.toRTVIError())
} else {
resolveOk(Unit)
}
Expand Down
Loading