git.iko.soy/opencode-android
on d643c13 help sign in
72 lines 2.2 kB history raw
1package soy.iko.opencode.data.model
3import androidx.compose.runtime.Immutable
4import kotlinx.serialization.Serializable
6/** Response of `GET /config/providers`. */
7@Immutable
8@Serializable
9data class ProvidersResponse(
10 val providers: List<Provider> = emptyList(),
11 val default: Map<String, String> = emptyMap(),
14@Immutable
15@Serializable
16data class Provider(
17 val id: String,
18 val name: String? = null,
19 val models: Map<String, ModelInfo> = emptyMap(),
20) {
21 val displayName: String get() = name?.takeIf { it.isNotBlank() } ?: id
24@Immutable
25@Serializable
26data class ModelInfo(
27 val id: String? = null,
28 val name: String? = null,
29) {
30 fun displayName(modelKey: String): String =
31 name?.takeIf { it.isNotBlank() } ?: id ?: modelKey
34/** A flattened provider/model selection used by the prompt body and the model picker. */
35@Immutable
36@Serializable
37data class ModelRef(
38 val providerID: String,
39 val modelID: String,
42/** A single selectable entry in the model picker, flattened from [ProvidersResponse]. */
43@Immutable
44data class ModelOption(
45 val providerID: String,
46 val modelID: String,
47 val providerLabel: String,
48 val modelLabel: String,
49) {
50 val ref: ModelRef get() = ModelRef(providerID, modelID)
53/** Flatten providers into a sorted list of pickable options. */
54fun ProvidersResponse.toOptions(): List<ModelOption> =
55 providers.flatMap { provider ->
56 provider.models.map { (modelKey, info) ->
57 ModelOption(
58 providerID = provider.id,
59 modelID = info.id ?: modelKey,
60 providerLabel = provider.displayName,
61 modelLabel = info.displayName(modelKey),
62 )
63 }
64 }.sortedWith(compareBy({ it.providerLabel.lowercase() }, { it.modelLabel.lowercase() }))
66/** The default option to preselect: the server's default for some provider, else the first model. */
67fun ProvidersResponse.defaultOption(options: List<ModelOption> = toOptions()): ModelOption? {
68 default.entries.firstOrNull()?.let { (providerID, modelID) ->
69 options.firstOrNull { it.providerID == providerID && it.modelID == modelID }?.let { return it }
70 }
71 return options.firstOrNull()