Skip to content

Commit

Permalink
Add model Preference
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpv committed Jan 22, 2025
1 parent dfb20e5 commit 3377af7
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 14 deletions.
80 changes: 68 additions & 12 deletions mobile/src/main/java/com/swooby/alfredai/PushToTalkPreferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuAnchorType
import androidx.compose.material3.Slider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -42,7 +46,6 @@ import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.openai.infrastructure.Serializer
import com.openai.models.RealtimeSessionCreateRequest
import com.openai.models.RealtimeSessionInputAudioTranscription
import com.openai.models.RealtimeSessionModel
Expand Down Expand Up @@ -110,6 +113,10 @@ class PushToTalkPreferences(context: Context) {
private val prefs: SharedPreferences =
context.getSharedPreferences("pushToTalkPreferences", Context.MODE_PRIVATE)

//
//region generic get/set primitives
//

@Suppress("SameParameterValue")
private fun getBoolean(key: String, default: Boolean): Boolean {
return prefs.getBoolean(key, default)
Expand Down Expand Up @@ -161,6 +168,10 @@ class PushToTalkPreferences(context: Context) {
}
}

//
//endregion
//

var autoConnect: Boolean
get() = getBoolean("autoConnect", autoConnectDefault)
set(value) = putBoolean("autoConnect", value)
Expand All @@ -180,6 +191,16 @@ class PushToTalkPreferences(context: Context) {
putString("apiKey", apiKeyEncrypted)
}

var model: RealtimeSessionModel
get() {
return getString("model", modelDefault.name).let {
RealtimeSessionModel.valueOf(it)
}
}
set(value) {
putString("model", value.name)
}

var instructions: String
get() = getString("instructions", instructionsDefault)
set(value) = putString("instructions", value)
Expand All @@ -192,24 +213,27 @@ class PushToTalkPreferences(context: Context) {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PushToTalkPreferenceScreen(
pushToTalkViewModel2: PushToTalkViewModel? = null,
pushToTalkViewModel: PushToTalkViewModel? = null,
onSaveSuccess: (() -> Unit)? = null,
setSaveButtonCallback: (((() -> Unit)?) -> Unit)? = null,
) {
val _autoConnect by (pushToTalkViewModel2?.autoConnect ?: MutableStateFlow(PushToTalkPreferences.autoConnectDefault).asStateFlow()).collectAsState()
val _apiKey by (pushToTalkViewModel2?.apiKey ?: MutableStateFlow(PushToTalkPreferences.apiKeyDefault).asStateFlow()).collectAsState()
val _instructions by (pushToTalkViewModel2?.instructions ?: MutableStateFlow(PushToTalkPreferences.instructionsDefault).asStateFlow()).collectAsState()
val _temperature by (pushToTalkViewModel2?.temperature ?: MutableStateFlow(PushToTalkPreferences.temperatureDefault).asStateFlow()).collectAsState()

var editedAutoConnect by remember { mutableStateOf(_autoConnect) }
var editedApiKey by remember { mutableStateOf(_apiKey) }
var editedInstructions by remember { mutableStateOf(_instructions) }
var editedTemperature by remember { mutableStateOf(_temperature) }
val initialAutoConnect by (pushToTalkViewModel?.autoConnect ?: MutableStateFlow(PushToTalkPreferences.autoConnectDefault).asStateFlow()).collectAsState()
val initialApiKey by (pushToTalkViewModel?.apiKey ?: MutableStateFlow(PushToTalkPreferences.apiKeyDefault).asStateFlow()).collectAsState()
val initialModel by (pushToTalkViewModel?.model ?: MutableStateFlow(PushToTalkPreferences.modelDefault).asStateFlow()).collectAsState()
val initialInstructions by (pushToTalkViewModel?.instructions ?: MutableStateFlow(PushToTalkPreferences.instructionsDefault).asStateFlow()).collectAsState()
val initialTemperature by (pushToTalkViewModel?.temperature ?: MutableStateFlow(PushToTalkPreferences.temperatureDefault).asStateFlow()).collectAsState()

var editedAutoConnect by remember { mutableStateOf(initialAutoConnect) }
var editedApiKey by remember { mutableStateOf(initialApiKey) }
var editedModel by remember { mutableStateOf(initialModel) }
var editedInstructions by remember { mutableStateOf(initialInstructions) }
var editedTemperature by remember { mutableStateOf(initialTemperature) }

val saveOperation: () -> Unit = {
pushToTalkViewModel2?.updatePreferences(
pushToTalkViewModel?.updatePreferences(
editedAutoConnect,
editedApiKey,
editedModel,
editedInstructions,
editedTemperature,
)
Expand Down Expand Up @@ -286,6 +310,38 @@ fun PushToTalkPreferenceScreen(
modifier = Modifier.fillMaxWidth(),
)
}
item {
var modelExpanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = modelExpanded,
onExpandedChange = { modelExpanded = !modelExpanded }
) {
TextField(
readOnly = true,
value = editedModel.name,
onValueChange = { /* read-only; ignore */ },
label = { Text("Model") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = modelExpanded) },
modifier = Modifier
.fillMaxWidth()
.menuAnchor(type = MenuAnchorType.PrimaryNotEditable, enabled = true)
)
ExposedDropdownMenu(
expanded = modelExpanded,
onDismissRequest = { modelExpanded = false }
) {
RealtimeSessionModel.entries.forEach { model ->
DropdownMenuItem(
text = { Text(model.name) },
onClick = {
editedModel = model
modelExpanded = false
}
)
}
}
}
}

item {
TextField(
Expand Down
37 changes: 35 additions & 2 deletions mobile/src/main/java/com/swooby/alfredai/PushToTalkViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.openai.models.RealtimeServerEventResponseTextDone
import com.openai.models.RealtimeServerEventSessionCreated
import com.openai.models.RealtimeServerEventSessionUpdated
import com.openai.models.RealtimeSessionCreateRequest
import com.openai.models.RealtimeSessionModel
import com.swooby.alfred.common.openai.realtime.RealtimeClient
import com.swooby.alfred.common.openai.realtime.RealtimeClient.RealtimeClientListener
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -51,6 +52,9 @@ class PushToTalkViewModel(private val application: Application)
private var _apiKey = MutableStateFlow(prefs.apiKey)
val apiKey = _apiKey.asStateFlow()

private var _model = MutableStateFlow(prefs.model)
val model = _model.asStateFlow()

private var _instructions = MutableStateFlow(prefs.instructions)
val instructions = _instructions.asStateFlow()

Expand All @@ -61,7 +65,7 @@ class PushToTalkViewModel(private val application: Application)
get() {
return RealtimeSessionCreateRequest(
modalities = null,
model = PushToTalkPreferences.modelDefault,
model = model.value,
instructions = instructions.value,
voice = PushToTalkPreferences.voiceDefault,
inputAudioFormat = null,
Expand All @@ -78,6 +82,7 @@ class PushToTalkViewModel(private val application: Application)
fun updatePreferences(
autoConnect: Boolean,
apiKey: String,
model: RealtimeSessionModel,
instructions: String,
temperature: Float,
) {
Expand All @@ -93,6 +98,12 @@ class PushToTalkViewModel(private val application: Application)
_apiKey.value = apiKey
}

if (model != prefs.model) {
updateSession = true
prefs.model = model
_model.value = model
}

if (instructions != prefs.instructions) {
updateSession = true
prefs.instructions = instructions
Expand All @@ -105,7 +116,20 @@ class PushToTalkViewModel(private val application: Application)
_temperature.value = temperature
}

tryInitializeRealtimeClient()
if (realtimeClient == null) {
tryInitializeRealtimeClient()
} else {
if (isConnectingOrConnected) {
if (isConnecting || reconnectSession) {
_realtimeClient?.disconnect()
_realtimeClient?.connect()
} else {
if (isConnected && updateSession) {
realtimeClient?.dataSendSessionUpdate(sessionConfig)
}
}
}
}
}

val isConfigured: Boolean
Expand All @@ -120,6 +144,15 @@ class PushToTalkViewModel(private val application: Application)
return _realtimeClient
}

val isConnectingOrConnected: Boolean
get() = realtimeClient?.isConnectingOrConnected ?: false

val isConnected: Boolean
get() = realtimeClient?.isConnected ?: false

val isConnecting: Boolean
get() = realtimeClient?.isConnecting ?: false

private fun tryInitializeRealtimeClient(): Boolean {
if (!isConfigured) {
return false
Expand Down

0 comments on commit 3377af7

Please sign in to comment.